码迷,mamicode.com
首页 > Web开发 > 详细

hibernate映射学习(一)

时间:2015-06-14 11:02:52      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:hibernate   实例   映射   

今天这篇博客将会主要学习hibernate关于实体类和表格中的映射详细学习。首先看下”常用主键的生成策略”

hibernate常用主键生成策略

在hibernate中,每个主键必须定义相应的主键生成策略,它用来为持久化类实例生成唯一的标识。
1.assigned
在hibernate中,如果不想使用hibernate的主键生成策略,那么此时就需要自己指定主键,此时的主键生成策略,就需要使用assigned。
在使用assigned的时候,必须手动指定id,比如我连续两次执行如下代码:

transaction = session.beginTransaction();
UserInfo info = new UserInfo();
info.setUserName("aa");
info.setUserPass("vvv");
session.save(info);
transaction.commit();

当第一次执行的时候,此时主键id,默认是0,而第二次执行,由于我们没有自己指定id,所以还是会使用默认值的,所以hibernate会抛出如下异常:
技术分享
2.increment
这里使用hibernate的主键自增的生成策略,主要为long,short或者int类型生成唯一标识,只有在没有其他进程给同一张表中插入数据才能使用,在集群下不要使用,不依赖数据库。比如这次给userinfo的主键使用increment。

<id name="userId" column="uid">
    <!-- 主键的生成策略:native(主键自增),assigned(指派) -->
    <generator class="increment"></generator>
</id>

此时我在多次执行上面的插入方法,就不会抛出异常,因为此时是主键自增的。在指定为increment的时候,当插入的时,hibernate首先在数据库当中查询最大的id值,然后对该id加一,再次插入。
3.native和identity
代表主键自增的意思,根据数据库不同,hibernate自动选择不同的实现方式。
4.hilo
使用一个高/低位算法高效生成long,short或者int类型的标识符,给定一个表和字段(默认分别是hibernate_unique_key和next_hi)作为高位值的来源,高/低位算法生成的标识符,只在一个特定的数据库当中是唯一的。

<id name="userId">
    <generator class="hilo"></generator>
</id>

这里我们制定id的生成策略是hilo,此时两次执行插入操作:

transaction = session.beginTransaction();
UserInfo info = new UserInfo();
info.setUserName("aa");
info.setUserPass("vvv");
session.save(info);
transaction.commit();

此时,hibernate为我们额外生成了一张表:hibernate_unique_key在该表中一个字段next_hi
技术分享
可以看到,此时hibernate自动为我们生成主键
技术分享
上面说了,默认维护主键的表示hibernate_unique_key,不过我们也可以自己指定。

<id name="userId">
    <generator class="hilo">
        <param name="table">testprimary</param>
        <param name="column">testcolumn</param>
    </generator>
</id>

5.uuid
uuid表示为string类型的属性生成主键,并且生成的主键也是一个唯一的字符串。比如我将userinfo的实体类的id更改为string类型。主键生成策略指定为uuid

<id name="userId">
    <generator class="uuid">
    </generator>
</id>

此时多次执行插入操作:
技术分享
6.联合主键生成策略
如果使用联合主键生成策略,就不能像之前那样使用简单的两个字段来代替了,此时必须使用一个实现Serializable接口的实体类。

package com.mydb.entity;

import java.io.Serializable;

public class ComposeKey implements Serializable {
    private int userId;
    private String userAddress;
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserAddress() {
        return userAddress;
    }
    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((userAddress == null) ? 0 : userAddress.hashCode());
        result = prime * result + userId;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ComposeKey other = (ComposeKey) obj;
        if (userAddress == null) {
            if (other.userAddress != null)
                return false;
        } else if (!userAddress.equals(other.userAddress))
            return false;
        if (userId != other.userId)
            return false;
        return true;
    }

}

可以看到这里,我使用userId和userAddress这两个字段来保证联合主键,主要ComposeKey必须实现hashCode和equals方法,因为hibernate是使用这两个方法来比较两个对象是否相等,从而保证联合主键的唯一性。
此时UserInfo类内容如下:

package com.mydb.entity;

import java.io.Serializable;

public class UserInfo implements Serializable {
    private ComposeKey composeKey;
    private String userName;
    private String userPass;

    public ComposeKey getComposeKey() {
        return composeKey;
    }
    public void setComposeKey(ComposeKey composeKey) {
        this.composeKey = composeKey;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPass() {
        return userPass;
    }
    public void setUserPass(String userPass) {
        this.userPass = userPass;
    }
}

接下来就是配置联合主键了。UserInfo.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- name="全类名" table="表名" -->
    <class name="com.mydb.entity.UserInfo" table="userinfo" lazy="false">
        <composite-id name="composeKey" class="com.mydb.entity.ComposeKey">
            <key-property name="userId"></key-property>
            <key-property name="userAddress"></key-property>
        </composite-id>
        <property name="userName" column="uname"></property>
        <property name="userPass" column="upass"></property>
    </class>
</hibernate-mapping>    

此时,执行插入操作,由于使用了联合主键,相当于我们自己指定了主键,需要显示的set来设置主键:

transaction = session.beginTransaction();
UserInfo info = new UserInfo();
info.setComposeKey(new ComposeKey(1,"china"));
info.setUserName("aa");
info.setUserPass("vvv");
session.save(info);
transaction.commit();

技术分享
可以看到这个时候userId和userAddress这两个属性,联合用来作为userInfo表中的主键的。此时如果我在插入一条id是info.setComposeKey(new ComposeKey(1,”china”));这样的数据,hibernate就会为我们抛出如下异常:
技术分享

属性的映射

对于属性的映射,常见的属性如下:
1.name:对应类的属性名称
2.type:指定属性的类型,一般情况下可以不使用,有hibernate自动匹配
3.length:指定长度
4.column:指定属性所对应的数据库字段的名称,如果不指定,就是属性的名称
5.not-null:是否非空
6.unique:是否唯一
7.update:是否在发出update语句的时候,包含本属性
当需要存入一个很长的文本,比如一本小说的时候,需要指定type类型为”text”,这种类型只受硬盘大小的限制。

好了,关于hibernate的一对一的映射学习,就到这里了,下一篇博客将会学习hibernate关联映射。希望大家能够喜欢。

hibernate映射学习(一)

标签:hibernate   实例   映射   

原文地址:http://blog.csdn.net/mockingbirds/article/details/46489163

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!