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:
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-
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()清除缓存
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作了个简单的封装:
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属性与主键的映射;类属性与表格字段的映射
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的资料:
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
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对象
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)
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
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
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值并加以比较
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来完成;
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类;
2 Configuration config = new AnnotationConfiguration().configure();
3 // 根据 config 建立 SessionFactory
4 // SessionFactory 将用于建立 Session
5 SessionFactory sessionFactory = config.buildSessionFactory();