zoukankan      html  css  js  c++  java
  • hibernate学习笔记

    1.关系模型
     关系模型把世界看作是由实体(Entity)和联系(Relationship)构成的;在关系模型中实体通常是以表的形式来表现的。表的每一行描述
     实体的一个实例,表的每一列描述实体的一个特征或属性;所谓联系就是指实体之间的关系,即实体之间的对应关系;
    2.ORM-对象关系映射
     ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中;它实现了Java应用中的对象到关系数据库中的表的自动的(和透明的)持久化;当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息等。而这些代码写起来总是重复的。
      个人建议:可以去看看Spring的JdbcTemplate
    3.Hibernate-
     提供了强大的对象和关系数据库映射以及查询功能。

     持久化Java类必须遵循的原则:
         对JavaBeans风格的属性实行持久化/getter/setter/
         默认的构造方法->Constructor.newInstance()
         集合类型的属性,它的类型必须定义为集合的接口
         提供一个标识属性(identifier property)->如级联更新等(更新主键值的操作,该值由其它表的现有行中的外键列引用。在级联更新中,更新所有外键值以与新的主键值相匹配)
         ......

         持久化类(POJO)- *.hbm.xml -数据库结构(schema)【xdoclet/hbm2java(code generator)/SchemaExport(hbm2dll)/Middlegen】

     配置Hibernate:
      开发hibernate3.0必须的包:
       hibernate3.jar
       required:antlr、dom4j、CGLIB、asm、Commons Collections、Commons Logging、 EHCache->oscache
       Hibernate底层还需要Java Transaction API-jta.jar
      将\etc目录下的log4j.properties复制至Hibernate项目的Classpath下,并修改一下当中的log4j.logger.org.hibernate为error,也就是只在在错误发生时显示必要的讯息
       配置文件.xml/.properties
       hibernate.cfg.xml:

     1<?xml version="1.0" encoding="utf-8"?>
     2   <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
     3   "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
     4    <hibernate-configuration>
     5        <session-factory>
     6         <!-- 显示实际操作数据库时的SQL -->
     7      <property name="show_sql">true</property>
     8      <!-- SQL方言,这边设定的是MySQL -->
     9      <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    10       <!-- JDBC驱动程序 -->
    11      <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    12      <!-- JDBC URL -->
    13       <property name="connection.url">jdbc:mysql://localhost/demo</property>
    14      <!-- 数据库使用者 -->
    15      <property name="connection.username">root</property>
    16      <!-- 数据库密码 --> 
    17       <property name="connection.password">root</property>
    18         <!-- 以下设置对象与数据库表格映像文件 -->
    19     </session-factory>
    20    </hibernate-configuration>
    21


         *.hbm.xml-告诉 Hibernate您所定义的*实例如何映射至数据库表,以Use为例:user.hbm.xml-
        

     1 <?xml version="1.0" encoding="utf-8"?>
     2  <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"     
     3  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4   <hibernate-mapping>  
     5    <class name="com.db.hibernate.demo.User" table="user">    
     6     <id name="id" column="id" type="java.lang.Integer">
     7     <!-- 主键的生成方式由Hibernate根据数据库Dialect的定义来决定 -->
     8     <generator class="native" /> 
     9     </id>    
    10     <property name="name" column="name" type="java.lang.String" />    
    11     <property name="age" column="age" type="java.lang.Integer" />  
    12    </class>
    13  </hibernate-mapping>
    14


        需要在Hibernate配置文件hibernate.cfg.xml中指明映像文件的位置
     详见eclipse的db工程
    4.配置文件的问题:
     1.The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collection-cache)*,event*,listener*)".
      解决:1.可能是文件编码问题;我的hibernate.cfg.xml是从ppt拷贝出来的,文件编码有问题;从正确的机器上拷贝一份文件或
      者尝试重新编码或者从网上拷贝一份正确的然后修改(正确的方法是参考etc目录下的xml模板)
       2.可能是元素(element type)的顺序问题
       3.可以将hibernate-configuration-3.0.dtd下载下来,对比一下,看哪里出错
     2.hibernate.cfg.xml和*.hbm.xml目前只能放到src根目录下,放到其他目录总报错
     3.关于xml dtd,正常下载的jar包中都会有dtd文件的,如hibernate-configuration-3.0.dtd;dom4j解析的时候会优先验证本地,如果本地有,则不会连接dtd指定的服务器地址;如果没有的话,可以去那地址下载dtd,放在本地或者将地址改为本地dtd的位置;当然eclipse也由一个选项,window->preference->xml catalog,可以添加;详见xml选项
    5.Criteria
     Criteria对SQL进行封装,对于不甚了解SQL的开发人员来说,使用Criteria也可以轻易的进行各种数据的检索;Expression设定查询条件(Expression已被废弃,eclipse中添加hibernate的javadoc,方便查看)Criteria是对象导向式的查询方式,让不了解SQL的开发人员也可以轻易进行各项查询;但Criteria的API目前还不是很完善;Hibernate鼓励的查询方式,是透过HQL(Hibernate Query Language)来进行.
    6.Query接口
    7.hibernate配置文件-hibernate.cfg.xml(提供较好的结构与配置方式,hibernate建议使用,默认)/hibernate.properties
         注意:XML配置文件的位置必须在Classpath下;默认的XML配置文件名称是hibernate.cfg.xml;你可以自己指定配置文件:
         new Configuration().configure().configure("db.cfg.xml");
     在Hibernate下载档案中的etc目录下,有hibernate.cfg.xml与hibernate.properties可供设定参考properties档案中不包括映射文件的名称,需要编程方式:
     Configuration cfg = new Configuration().addClass("user.hbm.xml") .addClass(com.db.hibernate.demo.User.class);

     hibernate.properties:
     hibernate.show_sql = true
     hibernate.dialect = org.hibernate.dialect.MySQLDialect
     hibernate.connection.driver_class = com.mysql.jdbc.Driver
     hibernate.connection.url = jdbc:mysql://localhost/demo
     hibernate.connection.username = root
     hibernate.connection.password = root
    8.Configuration-
     Configuration的实例管理Hibernate的配置信息,通常用于建立SessionFactory
     SessionFactory sessionFactory = config.buildSessionFactory();
    9.SessionFactory-
     SessionFactory一旦建立,就被赋予当时Configuration的配置信息;即使改变Configuration也不会影响之前已建立的该实例,而会新建SessionFactory中包括了数据库配置及映射关系,它的建立相当复杂,所以使用时需考虑到重用已建立的SessionFactory实例SessionFactory是被设计为线程安全的(Thread-safe)
    10.设定数据库连接-
     设定connection.pool_size是Hibernate默认的连接池设定;通常只用于开发阶段测试之用
     <!-- Hibernate 预设的Connection pool -->     
     <property name="connection.pool_size">2</property> 
         使用C3P0连接池,需要包含c3p0-*.jar;也可以使用Proxool或DBCP连接池(etc目录hibernate.properties中的配置例子来参考)使用Tomcat的话,您也可以通过它提供的DBCP连接池来取得连接-配置中加入connection.datasource属性
    11.hibernate缓存
     Hibernate中Session level缓存会在使用主键加载资料或是延迟初始(Lazy Initialization) 时作用Session level缓存,Session会维护一个Map容器
     通过evict()将某个对象从缓存中移去,可以使用clear()清除缓存中的所有对象
     可以通过session的load方法和==来判断是否存在缓存

     Session在使用save()储存对象时,会将要储存的对象纳入Session level缓存管理,在进行大量数据储存时,缓存中的实例大量增加最后会导致OutOfMemoryError,可以每隔一段时间使用Session的 flush()强制储存对象,并使用clear()清除缓存

     1 1 Session session = sessionFactory.openSession();
     2 2  Transaction tx = session.beginTransaction(); 
     3 3  while(.)
     4 4  
     5 5   // 大量加载对象时的循环示意    
     6 6   .    
     7 7   session.save(someObject);    
     8 8   if(count % 100 == 0
     9 9   
    1010    // 每100笔资料        
    1111    session.flush(); 
    1212    // 送入数据库        
    1313    session.clear(); 
    1414    // 清除缓存    
    1515   }

    1616  }
     
    1717  tx.commit();
    1818  session.close();
    19


      配置中hibernate.jdbc.batch_size来控制每多少笔资料就送至数据库(MySQL中则不支持这个功能,sqlserver/oracle支持)
    12.事务
     事务是一组原子(Atomic)操作(一组SQL执行)的工作单元;事务中的所有原子操作,不是全部执行成功,就是全部失败(即使只有一个失败,所有的原子操作也要全部撤消(回滚))JDBC中通过Connection的setAutoCommit和Commit方法管理事务,异常则回滚;Hibernate本身没有事务管理功能,它依赖于JDBC或JTA(java transaction api)的事务管理功能;默认是使用JDBC事务管理
     配置中添加:hibernate.transaction.factory_class属性来指定Transaction的工厂类别
     <property name="hibernate.transaction.factory_class"> org.hibernate.transaction.JDBCTransactionFactory</property> 
     Hibernate基于JDBC的事务管理只是对JDBC作了个简单的封装:

     1 try 
     2  {     
     3   session = sessionFactory.openSession();      
     4   Transaction tx = session.beginTransaction();     
     5   .      
     6   tx.commit();  // 必须commit才会更新数据库
     7  }
     
     8  catch(HibernateException e)
     9  {    
    10   tx.rollback(); 
    11  }


      在一开始的openSession()取得Session时,JDBC的Connection实例之AutoCommit就被设定为false,在 beginTransaction()时,会再度检查Connection实例的AutoCommit为false,在操作过程中,最后要commit (),否则的话对数据库的操作不会有作用,如果操作过程中因发生例外,则最后commit()不会被执行,之前的操作取消,执行rollback()可撤消之前的操作。要使用MySQL中的事务处理,必须建立事务表类型的表格例如InnoDB的表格
    13.映射文件
     Hibernate 中将对象与数据库表格映射关系连接起来的是映射文件;通常以*.hbm.xml作为文件名称;手工撰写;通过工具程序从数据库表格自动生成;通过工具程序从Java类自动生成三部分:类名称与表格名称的映射;id属性与主键的映射;类属性与表格字段的映射

     1<?xml version="1.0" encoding="utf-8"?>
     2 <!DOCTYPE hibernate-mapping       PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"       
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
     4 <hibernate-mapping>    
     5  <!--类别名称与表格名称映像-->    
     6 <class name="onlyfun.caterpillar.User" table="user">      
     7  <!--id与主键映像-->      
     8  <id name="id" column="id" type="java.lang.Integer">        
     9   <generator class="native"/>      
    10  </id>      
    11  <!--类别属性与表格字段的映像-->      
    12  <property name="name" column="name" type="java.lang.String"/>      
    13  <property name="age" column="age" type="java.lang.Integer"/>    
    14 </class>  
    15 </hibernate-mapping> 
    16


      注:
      1.Java的数据类型与数据库的数据类型并不是一对一对应的,为此Hibernate提供它自己的数据类型,作为Java数据类型与数
      据库数据类型的连接类型
      2.<generator>设定主键的生成方式;“native”表示由Hibernate自动根据Dialect选择采用 identity、hilo、sequence等作为主键生成方
      式;可以考虑采用uuid由Hibernate根据128位UUID算法(128- bit UUID algorithm)生成16进位制数值,并编码为32位长度的字符
      串
    14.基本API
         1.Session-是Hibernate操作的基础;不是设计为线程安全;一个Session由一个线程使用;
         Hibernate在对数据库进行操作之前,必须先取得Session实例,相当于JDBC在对数据库操作之前,必须先取得Connection实例;过Session,可以对数据库进行新增、删除、更新;使用save()新增一条记录;使用get()或load()方法取得id为1的记录-User user = (User) session.get(User.class, new Integer(1));
     如果未能发现相符合的记录,则get()方法会返回null,而load()方法会丢出ObjectNotFoundException;在高级的应用中,load()方法可以返回代理对象,并可充分利用缓冲机制
     Hibernate 3中,取消了find()方法,您必须通过Query或Criteria来进行记录查询
         使用delete()删除资料
      1 User user = (User) session.get(User.class, new Integer(1));
       session.delete(user);
      2 Query q=session.createQuery(“delete User u where u.id=1”);
       q.executeUpdate();
      3 Session.delete(“from User u where u.id=1”);
         使用update()方法将对象中的资料更新至对应的数据表中
     Session提供了一个saveOrUpdate()方法:由定义映射文件时,设定<id>卷标的unsaved-value来决定
     Session如同在编写JDBC时需关心 Connection的管理,以有效的方法创建、利用与回收Connection,以减少资源的消耗,增加系统
     执行效率一样;SessionFactory是线程安全的(Thread-safe),然而Session则不是设计为线程安全的,所以试图让多个执行绪共享一个
     Session,将会发生资料共享而发生混乱的问题
     2.Session管理
      使用了ThreadLocal类来建立一个Session管理的辅助类,这是Hibernate的Session管理一个广为应用的解决方案
      Thread-Specific Stroage模式可以有效隔离线程所使用的资源,所以避开Session的多线程之间的资源共享问题
      ThreadLocal是*Thread-Specific Storage 模式*的一个运用实例
      Hibernate会在真正需要数据库操作时才(从连接池中)取得Connection
      在Web应用程序中,可以藉由Filter来进行Session管理,在需要的时候开启Session,并在Request结束之后关闭Session
     3.Criteria基本查询
      Criteria对SQL进行封装,让开发人员可以用对象的方式来对数据库进行操作
      Criteria criteria = session.createCriteria(User.class);
      // 查询user所有字段
      List<User> users = criteria.list();
      Criteria实际上只是个容器,如果想要设定查询条件,则要使用add()方法加入Restrictions的条件限制
      例如查询age大于20且小于40的资料:

    1Criteria criteria = session.createCriteria(User.class);
    2  criteria.add(Restrictions.gt("age"new Integer(20)));//greater than >
    3  criteria.add(Restrictions.lt("age"new Integer(40)));//lesser than <
    4  List<User> users = criteria.list();


      也可以使用逻辑组合来进行查询-criteria.add(Restrictions.or(Restrictions.eq(), Restrictions.isNull())
      sqlRestriction()方法来提供SQL语法作限定查询
      criteria.add(Restrictions.sqlRestriction("{alias}.name LIKE (?)", "cater%", Hibernate.STRING));//alias别名
      在SQL撰写时,不必再写WHERE
      criteria.add(Restrictions.sqlRestriction("{alias}.age BETWEEN (?) AND (?)", ages, types));
      Restrictions的几个常用限定查询方法:eq/allEq/gt/ge/lt/le/between/like/in/and/or/sqlRestriction
     4.Criteria高级查询
      使用Criteria进行查询,并使用Order对结果进行排序
      criteria.addOrder(Order.asc("age"));//desc()
      setMaxResults()方法可以限定查询回来的记录数;setFirstResult()设定传回查询结果第一个记录的位置
      这两个配合起来,就可以实现简单的分页
      对查询结果进行统计动作,使用Projections的avg()、rowCount()、count()、max()、min()、countDistinct()等方法
      criteria.setProjection(Projections.avg("age"));
      可以配合Projections的groupProperty()来对结果进行分组
      criteria.setProjection(Projections.groupProperty("age"));
      想结合统计与分组功能,则可以使用ProjectionList

    1ProjectionList projectionList = Projections.projectionList();
    2   projectionList.add(Projections.groupProperty("age"));
    3   projectionList.add(Projections.rowCount()); 
    4   Criteria criteria = session.createCriteria(User.class);
    5   criteria.setProjection(projectionList);


      使用Example对象,可以将一个已知的对象作为查询的依据
      criteria.add(Example.create(user));
      Criteria可以进行复合查询
      Criteria与Session绑定,其生命周期跟随着Session结束而结束;使用Criteria时进行查询时,每次都要于执行时期动态建立对象
      能够重复使用Criteria对象,在Hibernate 3.0中新增了DetchedCriteria对象;您可以先建立DetchedCriteria实例,并加入各种查询条
      件,并于需要查询时再与Session绑定,获得一个绑定Session的Criteria对象

    1// 先建立DetchedCriteria对象
    2   DetachedCriteria detchedCriteria=DetachedCriteria.forClass(User.class);
    3   // 加入查询条件
    4   detchedCriteria.add(Restrictions.ge("age",new Integer(25)));        
    5   Session session = sessionFactory.openSession();
    6   // 绑定Session并返回一个Criteria实例
    7   Criteria criteria = detchedCriteria.getExecutableCriteria(session); 
    8


        5.Query接口
      使用org.hibernate.Query接口的实例来进行查询;
      透过Query接口,您可以先设定查询参数,使用setXXX()等方法,将指定的参数值填入,而不用每次都撰写完整的HQL
      在设定参数值时,必须依照 ? 所设定的顺序,并使用对应类型的setXXX()方法
      也可以使用命名参数(Named Parameter)
      将HQL撰写在程序之;避免硬编码(Hard code)在程序之中,在需要修改HQL时就很方便;
      在*.hbm.xml中使用<query/>卷标,并在<![CDATA[与]] >之间撰写HQL,撰写的位置是在</hibernate-mapping>之前
      (CDATA-character data)

     1 <?xml version="1.0" encoding="utf-8"?>
     2  <!DOCTYPE hibernate-mapping      
     3  PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"       
     4  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
     5 <hibernate-mapping>    
     6  <class name="model.User" table="user">       
     7   <id name="id" column="id“ type="java.lang.Integer">         
     8   <generator class="native"/>      
     9   </id>      
    10   <property name="name" column="name" type="java.lang.String"/>   
    11   <property name="age" column="age" type="java.lang.Integer"/>   
    12  </class>    
    13  <query name=“model.QueryUser">       
    14   <![CDATA[
    15   select user.name from User as user where user.age >:minAge 
    16   ]]>         
    17  </query>  
    18 </hibernate-mapping>
    19


       <query>的name属性用来设定查询外部HQL时的名称依据
      Query query = session.getNamedQuery(“model.QueryUser");
      query.setInteger("minAge", 25); 
    15.HQL
     1.HQL基本查询
      查询指定类对应表格的所有记录
      Query query = session.createQuery("from User"); //也可以指定类的全称
      List names = query.list();
      HQL本身不区分大小写,不过要注意类的名称必须区分大小写
      Hibernate会自动判定继承关系,如果查询的类是某类的父类,则会返回与父类、子类对应的所有表格记录
      针对某个属性作查询-Query query = session.createQuery("select user.name from User as user"); 
      查询两个以上的属性,查询的结果会以数组的方式返回
      Query query = session.createQuery("select user.age, user.name from User as user"); Object[] obj = (Object[]) iterator.next();
      如果User类提供有适当的构建方法,则可以在使用HQL时直接指定新建一个对象传回-
      Query query = session.createQuery("select new User(user.name, user.age) from User as user");
      List names = query.list();User user= (User) iterator.next(); //这个返回的User实例并未与数据库有任何关联
      使用distinct去除资料重复的记录-Query query = session.createQuery("select distinct user.age from User as user");
      在HQL中使用函数-Query query = session.createQuery("select count(*) from User as user"); 
      使用avg()取得属性的平均值-Query query = session.createQuery("select avg(user.age) from User as user");
      使用upper()函数将字符串转为大写:Query query = session.createQuery("select upper(user.name) from User as user"); 
     2.where 子句
      使用where子句来限定查询的条件,除了 = 运算之外,还有 >、>=、<、<=、!= 或 <>等比较运算
      Query query = session.createQuery("from User user where user.name=‘cjy'"); 
      where子句上进行表达式-Query query = session.createQuery("from User user where (user.age / 10 = 3)");
      在where子句上使用and、or-Query query = session.createQuery("from User user where (user.age > 20) and (user.name = ‘cjy')");
      is not nullL与is null则可以测试字段值是否为空值Query query = session.createQuery("from User user where user.name is not null");
      between可以测试字段值是否在指定的范围之内-session.createQuery("from User user where user.age between 20 and 30");
      使用in或not in来测试字段值是否在您指定的集合中-session.createQuery("from User user where user.name in(‘cjy', ‘abc')");
      like或not like可以让您进行模糊条件搜寻-session.createQuery("from User user where user.name like ‘c%'");
      查询结果使用order by进行排序-session.createQuery("from User user order by user.age");
      可使用desc反排序-session.createQuery("from User user order by user.age desc");
      同时指定两个以上的排序方式-
      session.createQuery("from User user order by user.age desc, user.name");//先按照"age"反序排,"age"相同,则按照"name"顺序排列
      使用GROUP BY子句,自动将指定的字段依相同的内容群组-
      session.createQuery("select user.sex, avg(user.age) from User user group by user.sex");
      结合having子句-session.createQuery("select user.sex, avg(user.age) from User user group by user.sex having avg(user.age) > 20");
      在Hibernate 3中,HQL新增了update与delete语句,可以直接使用HQL指定更新或删除
      update子句进行更新-session.createQuery("update User set name=‘abc' where name=‘cjy'");query.executeUpdate();
      delete子句进行资料删除-session.createQuery("delete User where name=‘cjy'");query.executeUpdate();
    16.SQL支持
     Hibernate提供了对SQL的支持,您可以指定您所要建立的SQL,并将实体类与资料表格关联;
      // SQL,并指定别名为user

    1String sql = "select {user.*} from User user where user.age > 20";
    2  Session session = sessionFactory.openSession();
    3  // 建立 SQLQuery
    4  SQLQuery sqlQuery = session.createSQLQuery(sql);
    5  // 将别名user与实体类User关联在一起
    6  sqlQuery.addEntity("user", User.class);
    7  Iterator iterator = sqlQuery.list().iterator();
    8


       addEntity()是将实体类与别名连结在一起的方法,大括号指定要查询的记录
     也可以将SQL语句定义在映射文件中*.hbm.xml
     <sql-query name="model.QueryUser">    
     <![CDATA[                   
      select {user.*} from User user where user.age > 20             
     ]]>             
     <return alias="user" class="model.User"/>  
     </sql-query> 
      Query query = session.getNamedQuery(“model.QueryUser");
      Iterator iterator = query.list().iterator();
      可以设定查询参数;
       <sql-query name=“model.QueryUser">
       <![CDATA[
        select {user.*} from User user where user.age > :age
       ]]>
       <return alias="user" class=“model.User"/>
       </sql-query>
        Query query = session.getNamedQuery("model.QueryUser");
        query.setInteger("age", 20); 
     Hibernate 3的映射文件中新增了<sql-insert>、<sql-update>与<sql-delete>三个卷标,您可以在这三个卷标中使用SQL自定义您的
     INSERT、UPDATE、DELETE

    1 <sql-insert>       
    2   INSERT INTO user (name, age) VALUES (?, ?)              
    3  </sql-insert>     
    4  <sql-update>       
    5   UPDATE user SET name=?, age=?, WHERE id=?              
    6  </sql-update>      
    7  <sql-delete>       
    8    DELETE FROM user WHERE id=?              
    9  </sql-delete>

        
      ? (参数) 对应的顺序是映像文件中属性出现的顺序
    17.映射基础
         Hibernate中的实体对象可以分为三种状态:Transient、Persistent、Detached。
         Transient-如User类所衍生出之对象,在还没有使用save()之前都是暂存对象,这些对象还没有与数据库发生任何的关系,不对应于数据库中的任一条记录。 
         Persistent-当对象与数据库中的记录有对应关系,并且与Session实例有关联而Session 实例尚未关闭(close),则它是在Persistent状态;Persistent状态的对象对应于数据库中的一条记录,对象的id值与记录的主键值相同,并且Session实例尚未失效;在这期间您对对象的任何状态变动,在Session实例关闭(close)或Transaction实例执行commit()之后,数据库中对应的记录也会跟着更新Session实例关闭(close),则Persistent状态的对象会成为Detached状态;使用Session的实例delete()方法删除记录,Persistent状态的对象由于失去了对应的记录,则它会成为Transient状态。
         Detached-Detached状态的对象,其id与数据库的主键值对应;Detached状态的对象之任何属性变动,不会对数据库中的记录造成任何的影响;Detached状态的对象可以使用update()方法使之与数据库中的对应记录再度发生关联,此时Detached状态的对象会变为 Persistent状态。

         Transient与Detached状态的对象未受Hibernate持久层管理员管理,对这两个状态的对象作任何属性变动,不会对数据库中的记录有任何的影响;而Persistent状态的对象受Hibernate持久层管理,对对象的属性变动,在Session实例关闭(close)或 Transaction实例执行commit()之后,数据库中对应的记录也会跟着更新。在对象为Persistent时,如果对象的属性发生变化,并且尚未提交之前,对象所携带的资料称之为Dirty Data,Hibernate会在持久层
     维护对象的最近读取版本,并在资料提交时检查两个版本的属性是否有变化,如果有的话,则将数据库中的记录进行更新。

     对象识别:
      要有必要比较透过查询后两个对象的资料是否相同(例如当对象被储存至Set时)您必须重写 equals()与hashCode()
      重写方法之一,equals()与hashCode()的方法是根据数据库的identity,就是透过getId()方法取得对象的id值并加以比较

     1public class User 
     2  {    
     3   .     
     4   public boolean equals(Object o) 
     5   {        
     6    if(this == o) return true;       
     7    if(id == null || !(o instanceof User)) 
     8     return false;         
     9    final User user == (User) o;        
    10    return this.id.equals(user.getId());    
    11    }
         
    12   public int hasCode() 
    13   {        
    14    return id == null ? System.identityHashCode(this):id.hashcode();    
    15   }
     
    16  }

    17

      
      上面的例子是个不被鼓励的例子,因为当一个对象被new出来而还没有save()时,它并不会被赋予id值,这时候就不适用这
      个方法;
     比较被采用的方法是根据对象中真正包括的的属性值来作比较;
     可以使用org.apache.commons.lang.builder.EqualsBuilder与 org.apache.commons.lang.builder.HashCodeBuilder来协助定义equals()与
     hashCode();
      Return new EqualsBuilder().append(this.name,user.getName()).append(this.phone, user.getPhone()).isEquals();
      return new HashCodeBuilder().append(this.name).append(this.phone).toHashCode();
    18.实体映射/集合映射/关系映射/继承映射/缓存/锁定/回调与拦截/工具
    19.Annotation-
     可以不通过*.hbm.xml,完全通过annotation搞定
     hibernate.cfg.xml-
     <!-- 以下设置对象与数据库表格映像类别 -->
            <mapping class="com.db.hibernate.demo.User"/>

     实体标识,主键生成,以及相关映像,都可以使用Annotation来完成;

     1@Entity
     2 @Table(name="user"// 非必要,在表格名称与类别名称不同时使用
     3 public class User
     4 {
     5  @Id
     6  @GeneratedValue(strategy=GenerationType.AUTO)
     7   private Integer id;
     8
     9  @Column(name="name"// 非必要,在字段名称与属性名称不同时使用
    10  private String name;
    11  
    12  @Column(name="age"
    13  private Integer age; // 非必要,在字段名称与属性名称不同时使用
    14    
    15   // 必须要有一个预设的建构方法
    16    // 以使得Hibernate可以使用Constructor.newInstance()建立对象
    17   public User() {    }
    18 }

    19


      注意:import javax.persistence.*中的注解

     使用Annotation时,需要的是AnnotationConfiguration类;

    1// 需要AnnotationConfiguration读取Annotation讯息
    2  Configuration config = new AnnotationConfiguration().configure();
    3  // 根据 config 建立 SessionFactory
    4  // SessionFactory 将用于建立 Session
    5   SessionFactory sessionFactory = config.buildSessionFactory();
  • 相关阅读:
    Linux下配置Tomcat服务器
    Octopress + GitHub Page 搭建个人博客
    Cocoapods报错Unable to satisfy the following requirements
    类方法load和initialize的区别
    AFNetworking3.0 Post JSON数据
    iOS防止button重复点击
    iOS与H5交互遇到的坑
    cocoapods安装
    平时做的一些好玩或者测试的 项目 特效,动画
    webpack那些事儿
  • 原文地址:https://www.cnblogs.com/a1280055207/p/2823252.html
Copyright © 2011-2022 走看看