zoukankan      html  css  js  c++  java
  • Hibernate基础之基本映射与关联映射

    转自:http://www.blogjava.net/wangjin/archive/2009/03/29/262760.html

    Hibernate开发文档
    一.基本概念:
    SessionFactory :它是单个数据映射表经编译后的内存镜像,是线程安全的,是生成session的工厂.该对象可以在进程或集群的级别上,为那些事务之间可以重用的数据提供可选的二级缓存.
    Session:它是应用程序与持久存储层之间交互操作的一个单线程对象.所有的持久化对象必须在session管理下才可以进行持久化操作.此对象生存期很短,它隐藏了JDBC连接,也是Transaction的工厂.Session对象有一个一级缓存,显式执行flush之前,所有持久化操作的数据都缓存在Session对象处.
    持久态:系统创建的pojo对象,一旦与Session关联起来并对应成数据库中的记录,对其所有的操作都相当于对数据库的操作
    暂态/脱管态:暂态指新创建的未与Session关联的的对象,其可能是未持久化的对象;脱管态指持久态的对象因Session关闭导致临时失去持久态的对象
    事务:代表一次原子操作,具有数据库事务的概念.某些情况下,一个Session之内可能包含多个Transaction对象.虽然事务操作是可选的,但是所有持久化操作都应该在事务管理下进行,即使是只读操作.
    连接提供者:ConnectionProvider,是生成jdbc连接的工厂,同时具备连接池的作用.它通过抽象将应用从底层的Datasource或DriverManager隔离开.无需直接访问
    事务工厂:它是生成Transaction对象实例的工厂,无需直接访问
    二.使用须知;
    1.配置文件
    ①hibernate.properties
      Configuration cfg=new Configuration()
                     .addResource("Item.hbm.xml")
                     .addResource("Bid.hbm.xml");
      还可以
      Configuration cfg=new Configuration()
         .addClass(lee.Item.Class)
                     .addClass(lee.Bid.Class);
      这种可以让Hibernate自动根据持久化类来搜索配置文件,但是应保证配置文件和pojo同一目录下
    ②使用 hibernate.cfg.xml
      这种方法可以直接使用
     Configuration cfg=new Configuration().configure()
    ③使用Configuration cfg=new Configuration().addClass("").setProperty("","")
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
      "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
      "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
    <session-factory>
     <property name="hibernate.connection.driver_class">
      com.mysql.jdbc.Driver
     </property>
     <property name="hibernate.connection.password">32147</property>
     <property name="hibernate.connection.url">
      jdbc:mysql://localhost:3306/hibernate
     </property>
     <property name="hibernate.connection.username">root</property>
     <property name="hibernate.dialect">
      org.hibernate.dialect.MySQLDialect
     </property>
     <property name="show_sql">true</property>
     <property name="hbm2ddl.auto">update</property>
     <mapping resource="News.hbm.xml" />
    </session-factory>
    </hibernate-configuration>

    2.连接池:
    <!—连接池-->
    <property name="hibernate.c3p0.max_size">20</property>
    <property name="hibernate.c3p0.min_size">1</property>
    <property name="hibernate.c3p0.timeout">5000</property>
    <!—缓存Statement的数量-->
    <property name="hibernate.c3p0.max_statements">100</property>
    <property name="hibernate.c3p0.idle_test_period">3000</property>
    <property name="hibernate.c3p0.acquire_increment">2</property>
    <property name="hibernate.c3p0.validate">true</property>
    3.JNDI 无需hibernate自己管理数据源的时候使用,虽然使用JNDI数据源,仍然需要指定数据库的方言,尽管数据库方言是可选de.
    <!--配置JNDI数据源的JNDI名-->
    <property name="connection.datasource">java:comp/env/jdbc/dstest</property>
    <!—配置连接库的方言-->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    4.其他配置属性:
    ①hibernate.show_sql 是否输出sql
    ②hibernate.jdbc.fetch_size  指定jdbc抓取数量的大小,
    ③hibernate.jdbc.batch_size 指定Hibernate使用JDBC批量更新的大小,它可以接受一个整数值,建议5到三十
    ④hibernate.connection.autocommit 设置是否自动提交,通常不建议打开
    ⑤hibernate.hbm2ddl.auto 设置当创建SessionFactory时,是否根据映射文件自动建立数据库表.该属性可以为:update create create-drop
    三.持久化类的要求:
    1.getter setter 等
    2.一个无参构造器
    3.一个标示属性
    4.如果使用一个有public final方法的类,必须通过设置lazy="false"来禁用代理
    5.重写equals() hashCode()方法(如果需要把pojo类的实例放入Set中的时候) 重写时,通常建议使用业务键值来实现.
    6.状态转换:
    //////
     News n=new News();
     n.setName("");
     sess.save(n)
    //////
      News n=Session.load(News.class, new Integer(pk));
      n.setTitle("biaoti");
    ////
      News n=Session.load(News.class, new Integer(pk));
      Session.delete(n);
    四.映射文件
    1.样本
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping
        PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="lee">
        <class name="Person">
            <id name="id" column="personid">
                <generator class="identity"/>
            </id>
            <property name="name"/>
            <property name="age"/>
        </class> 
    </hibernate-mapping>
    2.主键生成器
    increment   对long short int数据列生成自增长主键
    identity     对如SQL Server,MySql等支持自增长列的数据库且数据列的类型long int short
    sequence    对如Oracle DB2等支持sequence的数据库且数据列的类型为long int short
    uuid        采用128-位UUID算法生成唯一的字符串主键
    3.映射集合属性
    List
    <list name="schools" table="school">
    <key column="personid" not-null="true"/>
    <list-index column="list_order"/>
    <element type="string" column="school_name"/>
    </list>
    Set
    <set name="shools" table="shool">
    <key column="personid" not-null="true"/>
    <element type="string" column="school_name" not-null="true"/>
    </set>
    Bag
    <bag name="shools" table="shool">
    <key column="personid" not-null="true"/>
    <element type="string" column="school_name" not-null="true"/>
    </bag>
    Map  
    <map name="scores" table="score">
    <key column="personid" not-null="true"/>
    <map-key column="xueke" type="string"/>
    <element type="float" column="mark"/>
    </map>
    4.组件及复合主键映射
    ①"属性组件"组件为pojo的一个普通属性类 private Name name  Name(first,last)
    <component name="name" class="Name" unique="true">
    <property name="first"/>
    <property name="last"/>
    </component>
    ②"集合元素组件"组件为List等集合的一个元素 private List<School> schools  
    School(name, address)
    <list name="schools" table="school">
    <!--映射关联外键-->
    .<key column="personid" not-null="true"/>
    <list-index column="list_order">
    <composite-element class="School">
    <property name="name">
    <property name="address">
    </composite-element>

    ③"属性组件主键" private Name name (用name做主键 ,不推荐) Name(firstName,lastName)
    <composite-id name="name" class="Class">
    <!-- key-property元素确定标识属性包含的属性-->
    <key-property name="firstName">
    <kry-property name="lastName">
    </composite-id>
    ④"复合主键" private String firstName ;private String lastName;
    <composite-id>
    <!-- key-property元素映射复合主键的每个元素-->
    <key-property name="firstName">
    <kry-property name="lastName">
    </composite-id>
    5.关联关系
    单向还是双向:
    单向还是双向取决于对关联端的访问要求,从根本上来讲双向和单向是没有区别的,举个子如,老师找学生;学生找老师;老师找学生同时学生也找老师.单向也好,双向也好,都指同一个关联关系
    一对多还是多对一到底怎么看:
     
    ㈠单向关系
    1. 单向1-1
     
    1.1基于外键 many-to-one 相当于 property,区别是该元素映射的关联的持久化类
    <many-to-one name="address" type ="Address" column="addressid" unique="true" />
    1.2基于外键 有连接表的 这里用join显式确定连接表
    <join table="join_table">
    <key column="personid"/>
    <many-to-one name="address" unique="true"/>
    </join> 
    1.3基于主键
    <id name="personid">
    <generator class="foreign">
    <param name="property">address</param>
    </generator> </id>
    <!--constrainted表明该类的主键根据关联类生成-->
    <one-to-one name="address" constrained="true"/>  
    2.单向N-1
     
    2.1 无连接表
    <many-to-one name="address" column="addressid"/>
    2.2有连接表
    <join table="join_table">
    <key column="personid"/>
    <many-to-one name="address" />
    </join>
    3.单向1-N
     
    3.1 无连接表的 one-to-many和element类似
    <set name="address">
    <key column="personid"/>
    <one-to-many class="Address"/>
    </set>
    3.2 有连接表 many-to-many 表明要N-N或1-N,unique=true表明这里是1-N关系
    <set name="address">
    <key column="personid"/>
    <many-to-many class="Address" unique="true"/>
    </set>

    4.单向N-N


    这与单向1-N没有区别,配置文件只需将unique="true"改为unique="false"或去掉
    <set name="address">
    <key column="personid"/>
    <many-to-many class="Address" unique="false"/>
    </set>
    ㈡双向关系
    1.双向1-N
     
    1.1无连接表
    注意: 两个配置文件都应该指定外键,且不应省略.
    Person.hbm.xml
    <set name="address">
    <key column="personid"/>
    <one-to-many class="Address"/>
    </set>
    Address.hbm.xml
    <many-to-one name="person" column="personid">
    1.2有连接表
    注意:1.两遍确定连接表的table属性值应该相等,且不可以省略
         2.两遍都制定了两个外键列,一定要保证两边映射文件的外键列名对应相同
    Person.hbm.xml
    <set name="address" table="personAddress">
    <key column="personid"/>
    <many-to-many class="Address" unique="true" column="addressid"/>
    </set>
    Address.hbm.xml  //optional表示是否可选
    <join table="PersonAddress" inverse="true" optional="true">
    <many-to-one name="person" column="personid">
    2.双向N-N
     
    双向多对多的两边都要指定table 和外键列的列名 且它们都要一致
    Person.hbm.xml
    <set name="addresses" table="jointable">
    <key column="personid"/>
    <many-to-many column="addressid" class="Address"/>
    </set>
    Address
    <set name="persons" table="jointable">
    <key column="addressid"/>
    <many-to-many column="personid" class="Person">
    </set>
    3.双向1-1
     
    3.1基于外键
    注意: 基于外键的双向1-1,外键可以放在任一端,当然需要增加many-to-one属性.而另一端就需要使用one-to-one元素,为了不让系统再为本表增加一列,而是使用外键关联可以用property-ref属性引用关联类的自身属性.注意:one-to-one映射关联属性,不会创建外键列.
    Person.hbm.xml
    <one-to-one name="address" property-ref="person"/>
    Address.hbm.xml
    <many-to-one name="person" class="Person" unique="true"/>
    3.2基于主键
    Person.hbm.xml
    <one-to-one name="address" />
    Address.hbm.xml
    <generator class="foreign">
    <param name="property">address</param></generator>
    < one-to-one name="person" constrained="true"/>
    3.3基于外键的强制连接表(不推荐)
    Person.hbm.xml
    <join table="personaddress" optional="true">
    <key column="personid" unique="true"/>
    <many-to-one name="address" column="addressid" not-null="true" unique="true">
    </join>
    Address.hbm.xml
    <join table="personaddress" optional="true" inverse="true">
    <key column=" addressid" unique="true"/>
    <many-to-one name="person" column=" personid" not-null="true" unique="true"/>
    </join>
    length 属性值得是字符个数,这个与数据库是不同的

  • 相关阅读:
    使用虚拟环境virtualenv/Virtualenvwrapper隔离多个python
    计算机硬件基本知识及Linux的常用命令
    网络电子时钟系统案例
    地铁时钟系统介绍
    北斗校时服务器装置介绍
    网络电子时钟系统成功案例
    高精度统一时钟基准特点
    IEEE1588 PTP对时系统原理及特点
    GPS轨迹发生模拟器介绍
    python urllib模块
  • 原文地址:https://www.cnblogs.com/_programmer/p/3382008.html
Copyright © 2011-2022 走看看