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关联映射。希望大家能够喜欢。

时间: 2024-11-09 04:26:35

hibernate映射学习(一)的相关文章

hibernate映射学习(三)

在前面几篇文章中,分别学习了hibernate的关联映射,基本的一对一,一对多,多对 多等都有学习,今天我会给大家带来hibernate中关于"组合映射"和"继承映射"的学习. ## 组合映射## 为什么要学习组合映射,它和一般的映射有什么区别吗??我们先来看一下下面这种情况: 上图,可以看出,user包含了username,address包含了homeaddress,contact包含了qq,phone,这些字段,由于这些属性没有什么必然联系,我们可以将这些字段放

hibernate 框架学习笔记---网上摘抄的一个非常好的例子

编写Spring+Hibernate框架下的应用,总是离不了编写一个通用的泛型GenericHibernateDao.查阅了网上不少的GenericHibernateDao实现,归纳整理为如下实现,供后续编码参考. 首先定义接口泛型DAO接口 GenericDao package com.th.huz; import java.io.Serializable;import java.util.Collection;import java.util.Iterator;import java.uti

Hibernate映射文件如何配置触发器

Hibernate映射文件之触发器生成(generated属性.database-object元素) (2013-02-27 12:28:49) 转载▼ 标签: it 分类: JAVA学习笔记 这里分两个Project: 第一个Project: 通过映射文件的database-object来创建数据表.触发器 1. 创建两个.java文件: CreateTable.java和CreateTrigger.java,里面只需有个类名就行,目的是要创建对应的映射文件CreateTable.hbm.xm

【SSH系列】Hibernate映射 -- 一对多关联映射

    映射原理       一对多关联映射和多对一关联映射的映射原理是一样一样的,所以说嘛,知识都是相通的,一通百通,为什么说一对多关联映射和多对一关联映射是一样的呢?因为她们都是在多的一端加入一个外键,指向一的一段,关联关系都是在多的一端进行维护,只是我们在写映射的时候发生了变化.       一对多和多对一的映射原理是一样的,但是她们之间也存在着小小的区别,毕竟世界上没有两片完全相同的叶子,她们之间的区别就是维护的关系不同,我们先来看多对一,多端维护一端的关系,在加载多端的时候,可以将一端

Hibernate映射解析——七种映射关系

        ORM,全称是(Object Relational Mapping),即对象关系映射.ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现,这样开发人员就可以把对数据库的操作转化为对这些对象的操作.Hibernate正是实现了这种思想,达到了方便开发人员以面向对象的思想来实现对数据库的操作.    Hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.java).映射文件(*.hbm.xml)和数据库配置文件(*.properties/*.cfg

【SSH进阶之路】Hibernate映射——多对多关联映射(八)

上篇博文[SSH进阶之路]Hibernate映射--一对多关联映射(七),我们介绍了一对多关联映射,它是多对多关联映射的基础. 多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接开始. 映射原理 不论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张做一个关联.用第三张表来解决可能会造成数据冗余的问题. 举例 一个用户(User)对多个角色(Role),一个角色对多个用户. 分类 单向的多对多关联映射(单向User--->Role) 对象模型 关系模型 实例

hibernate映射-基于主键映射的1-1关联关系

(学习记录,错误不足之处,请您耐心指正^_^) hibernate映射-基于主键映射的1-1关联关系 基于主键的映射策略:指一端的主键生成器使用foreign策略,表明根据对方的主键来生成自己的主键,自己并不独立生成主键. 一.代码示例: {类文件↓} Manager.class 1 package com.zit.hibernate.one2one.primary; 2 3 public class Manager { 4 5 private Integer mgrId; 6 private

hibernate映射-双向n-n关联关系

(学习记录,错误不足之处,请您耐心指正^_^) hibernate映射-双向n-n关联关系 一.代码示例: {类文件↓} Category.class package com.zit.hibernate.n2n.both; import java.util.HashSet; import java.util.Set; public class Category { private Integer id; private String name; private Set<Item> items

Hibernate 映射文件详解

Hibernate 映射文件详解 2010-09-02 19:03:33|  分类: Hibernate学习|举报|字号 订阅 Hibernate的持久化类和关系数据库之间的映射通常是用一个XML文档来定义的.该文档通过一系列XML元素的配置,来将持久化类与数据库表之间建立起一一映射.这意味着映射文档是按照持久化类的定义来创建的,而不是表的定义. 一.根元素:<hibernate-mapping>,每一个hbm.xml文件都有唯一的一个根元素,包含一些可选的属性 1)package:指定一个包