zoukankan      html  css  js  c++  java
  • Hibernate基础学习(四)—对象-关系映射(上)

    一、映射对象标识符

         Java语言按内存地址来识别或区分同一个类的不同对象,而关系数据库按主键值来识别或区分同一个表的不同记录。Hibernate使用对象标识符(OID)来建立内存中的对象和数据库表中的记录的对应关系,对象的OID和数据库表的主键对应,为了保证OID的唯一性和不可变性,应该让Hibernate,而不是应用程序来为OID赋值。

        Hibernate推荐在数据表中使用代理主键,即不具备业务含义的字段。代理主键通常为整型,因为整型比字符串要节省更多数据库空间。

        在对象关系映射文件中,<id>元素用来设置对象标识符,<generator>子元素用来设定标识符生成器。

    User.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.kiwi.domain.User" table="t_user">
    		
    		<!-- 配置主键 -->
    		<id name="uid">
    			<!-- 主键生成策略 -->
    			<generator class="native"/>
    		</id>
    		
    		<!-- 
    			普通属性 : 数据库中的基本类型
    			name:对象中的属性名
    			type: 类型,如果不写,Hibernate会自动监测
    			column: 对应表中的列名
    			length:长度,不是所有的类型都有长度属性
    			not-null:非空约束,默认为false
    		-->
    		<property name="username" type="string" column="t_name"/>
    		<property name="password" type="string" column="t_pwd"/>
    		<property name="age" type="int" column="t_age"/>
    		<property name="birthday" type="date" column="t_birth"/>
    		
    	</class>
    
    </hibernate-mapping> 

    Hibernate提供内置标识符生成器如下:

         image

    1.increment

    (1)increment 标识符生成器由Hibernate以递增的方式为代理主键赋值。
    (2)Hibernate 会先读取数据库表中的主键的最大值,而向表中插入记录时,就在max(id)的基础上递增,增量为1。

    适用范围:
         (1)由于increment生存标识符机制不依赖于底层数据库系统, 因此它适合所有的数据库系统。
         (2)适用于只有单个Hibernate 应用进程访问同一个数据库的场合,在集群环境下不推荐使用它。
         (3)OID必须为long,int或short类型,如果把OID定义为byte类型,在运行时会抛出异常。

    2.identity

         identity标识符生成器由底层数据库来负责生成标识符, 它要求底层数据库把主键定义为自动增长字段类型。
    适用范围:

    (1)由于identity生成标识符的机制依赖于底层数据库系统,因此,要求底层数据库系统必须支持自动增长字段类型。支持自动增长字段类型的数据库包括: DB2,Mysql,SQLServer,Sybase等。

    (2)OID 必须为long,int 或short类型,如果把OID定义为byte类型,在运行时会抛出异常。

    3.native

         native标识符生成器依据底层数据库对自动生成标识符的支持能力,来选择使用identity,sequence或hilo标识符生成器。

    适用范围:
         (1)由于native能根据底层数据库系统的类型,自动选择合适的标识符生成器,因此很适合于跨数据库平台开发。

         (2)OID必须为long,int 或short类型,如果把OID定义为byte类型,在运行时会抛出异常。

    4.sequence

         sequence标识符生成器利用底层数据库提供的序列来生成标识符

         image

         Hibernate 在持久化一个对象时, 先从底层数据库的 news_seq 序列中获得一个唯一的标识号, 再把它作为主键值。
    适用范围:

    (1)由于sequence 生成标识符的机制依赖于底层数据库系统的序列,因此,要求底层数据库系统必须支持序列。支持序列的数据库包括: DB2,Oracle 等。

    (2)OID必须为long,int或short类型,如果把OID定义为byte类型,在运行时会抛出异常。

    5.hilo

         hilo 标识符生成器由Hibernate按照一种high/low 算法生成标识符,它从数据库的特定表的字段中获取high值。

         image

          table: 存放使用次数的表名。

          column: 上面表的列,存放使用次数。

          max_lo: 步长。

         Hibernate 在持久化一个对象时, 由Hibernate负责生成主键值。 hilo 标识符生成器在生成标识符时,需要读取并修改 HI_TABLE 表中的 NEXT_VALUE 值。

    适用范围:
         (1)由于hilo生存标识符机制不依赖于底层数据库系统,因此它适合所有的数据库系统。

         (2)OID必须为long,int或short类型,如果把OID定义为byte类型,在运行时会抛出异常。

    6.uuid

    适用范围:

         (1)由于 hilo 生成标识符机制不依赖于底层数据库系统, 因此它适合所有的数据库系统。

         (2)OID 必须为String类型。

    7.assigned

         表示手工指定主键的值。

    二、Java类型、Hibernate类型和SQL类型之间的关系

         image

         image

         在标准 SQL 中,DATE 类型表示日期,TIME 类型表示时间,TIMESTAMP 类型表示时间戳, 同时包含日期和时间信息。

         image

    三、映射值类型集合

    1.Set

         Customer类与Order类为一对多的关联关系,在Customer类中定义了一个集合类型orders,它用来存放所有与Customer对象关联的Order对象。假如Customer类有一个集合属性address,用来存放Customer对象的所有地址,那么address和orders有相同的定义形式。

    	private Set<Order> orders = new HashSet<Order>(); //保存多个订单
    	private Set<String> address = new HashSet<String>(); //保存多个地址

         orders属性与address属性的区别在于,前者存放的是实体类型的Order对象,后者存放的是值类型的String对象。实体类型的对象有单独的OID和独立的生命周期,而值类型的对象没有单独的OID和独立的生命周期。

         image

    Customer.java

    public class Customer{
    
    	private Integer uid;
    	private String username;
    
    	private Set<String> address = new HashSet<String>(); //保存多个地址
    	
    
    	public Customer(){
    	}
    
    	public Customer(int uid,String username,Set<String> address){
    		this.uid = uid;
    		this.username = username;
    		this.address = address;
    	}
    
    	//get、set方法....
    }

    Customer.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>
    
    	<class name="com.kiwi.domain.Customer" table="t_customer">
    
    		<id name="uid">
    			<generator class="native" />
    		</id>
    
    		<property name="username" type="string" column="t_name" />
    
    		<!-- address属性,Set集合
    			name: 类的的属性名
    			table: 集合的表名
    		 -->
    		<set name="address" table="cus_address">
    			<!-- 外键 -->
    			<key column="cusId" />
    			<!-- 集合的属性 -->
    			<element type="string" column="address" />
    		</set>
    
    	</class>
    
    </hibernate-mapping> 
    Test.java
    			Customer c = new Customer();
    			c.setUsername("Tom");
    			
    			c.getAddress().add("朝阳区");
    			c.getAddress().add("海淀区");
    			
    			session.save(c);

    结果:

    t_customer           cus_address

    image  image

    2.List

       image

    Customer.java

    public class Customer{
    
    	private Integer uid;
    	private String username;
    
    	private List<String> emails = new ArrayList<String>();
    	
    	//get、set......
    }
    Customer.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>
    
    	<class name="com.kiwi.domain.Customer" table="t_customer">
    
    		<id name="uid">
    			<generator class="native" />
    		</id>
    
    		<property name="username" type="string" column="t_name" />
    
    		<!-- emails属性 List集合 -->
    		<list name="emails" table="cus_email">
    			<key column="cusID"/>
    			<list-index column="idx"/>
    			<element type="string" column="email"/>
    		</list>
    
    	</class>
    
    </hibernate-mapping> 
    Test.java
    			Customer c = new Customer();
    			c.setUsername("Tom");
    			c.getEmails().add("111@163.com");
    			c.getEmails().add("222@163.com");
    			c.getEmails().add("111@163.com");
    			session.save(c);

    结果:

    t_customer             cus_email

    image     image

    3.Map

    Customer.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>
    
    	<class name="com.kiwi.domain.Customer" table="t_customer">
    
    		<id name="uid">
    			<generator class="native" />
    		</id>
    
    		<property name="username" type="string" column="t_name" />
    		
    		<!-- map -->
    		<map name="address" table="cus_address">
    		
    			<key column="cusID"/>
    			<map-key type="string" column="key_"/>
    			<element column="value_" type="string"/>
    		</map>
    
    	</class>
    
    </hibernate-mapping> 
    Test.java
    			Customer c = new Customer();
    			c.setUsername("Tom");
    			c.getAddress().put("公司","朝阳区");
    			c.getAddress().put("住宅","昌平区");
    			session.save(c);

    结果:

         imageimage

  • 相关阅读:
    下载安装ActiveMQ(消息队列)
    互联网项目架构之基于服务的分布式架构
    Shell报错bash^M /bin/bash^M: bad interpreter: No such file or directory
    rpm参数
    zabbix3.4+grafana5.0.1数据可视化
    Linux下目录栈操作详解
    有惊无险,拯救zabbix网页端
    tomcat7 开启gzip压缩
    欢迎使用CSDN-markdown基本语法
    新项目平台后台测试环境搭建
  • 原文地址:https://www.cnblogs.com/yangang2013/p/5515593.html
Copyright © 2011-2022 走看看