Hibernate核心编程


Hibernate核心编程
ORM:指的是对象关系映射(object/Relation Mapping)。
 
Hibernate:指的是对象关系映射的一种框架工具。
 
PO:持久化对象(Persistent Object),作用是完成持久化操作,即以面向对象的方式操作(增删改查)数据库。
 
POJO:(Plain Old Java Objects)简单的Java对象,实际就是普通JavaBeans.
 
注意:为了使其具有持久化能力,还需创建该它的映射文件xml,如user.xml
 
同时在Hibernate.cfg.xml中添加<mapping resource="user.xml"/>
 
PO有3个状态:瞬时(transient)、持久化(persist)、脱管(detached)。


一、核心类
Configuration接口:负责配置并启动Hibernate,创建SessionFactory对象。Hibernate启动过程中,Configuration类的实例首先定位映射文件位置和读取位置,然后创建SessionFactory对象。
Configuration cfg=new Configuration().configure();    //读取hibernate.cfg.xml文件
SessionFactory factory=cfg.buildSessionFactory();    //初始化对象factory
附configure函数源码:
public Configuration configure() throws HibernateException {


configure( "/hibernate.cfg.xml" );


return this;


}
public Configuration configure(String resource) throws HibernateException {


LOG.configuringFromResource( resource );


InputStream stream = getConfigurationInputStream( resource );


return doConfigure( stream, resource );


}
SessionFactory接口:负责初始化Hibernate,充当数据存储源的代理,并负责创建Session对象。
Session session=factory.openSession();    //创建Session
Session接口:负责持久化对象的CRUD操作
Transaction接口:负责事务相关操作
Query接口和Criteria接口:负责执行各种数据库查询
注意:Configuration实例是一个启动期间的对象,一旦SessionFactory创建完成,它就被丢弃了。


二、Session的3个状态
(1)自由状态(瞬时态):不曾持久化,未与任何Session相关联
瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系
session的save()或saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。 
(2)持久化对象:仅与一个Session相关联
1. 和session实例关联; 
2. 在数据库中有与之关联的记录
hibernate的delete()方法,对应的持久对象就变成瞬时对象,因数据库中的对应数据已被删除,该对象不再与数据库的记录关联。 
当一个session执行close()或clear()、evict()之后,持久对象变成托管对象,此时持久对象会变成托管对象,此时该对象虽然具有数据库识别值,但它已不在HIbernate持久层的管理之下。
(3)游离状态(托管态):已经进行过持久化,但当前未与任何Session相关联
托管对象拥有数据库的识别值,可通过update()、saveOrUpdate()等方法,转变成持久对象。 
1. 本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收; 
2. 比瞬时对象多了一个数据库记录标识值


三、Session操作
保存对象
save()
装载对象
load()
装载对象
get()
强制提交并刷新
flush()
提交游离状态的对象
update()
移除持久化对象
delete()
强制装载对象
refresh()
四、Query查询
不带参数查询
session.createQuery("from user");
带参数的查询
session.createQuery("from user where userid=:userid");
query.setString("userid","admin");
带集合的查询
session.createQuery("from user where userid in(:userList)");
query.setString("userList",userList);//userList是一个List
取得List结果集
query.list();
取得iterator
query.iterate();
取得一个对象
query.uniqueResult();
标量查询
session.createQuery("select u.username from user u group by u.username");
分页查询
Query query=session.createQuery("from user");
query.setFirstResult(10);//设置起始范围
query.setMaxResult(20);//设置结束范围
List list=query.list();
创建SQL查询
List users=session.createSQLQuery("select {u.*} from User {u}").list();
五、使用Criteria进行条件查询
创建Criteria实例
Criteria criteria=session.createCriteria(User.class);
criteria.setMaxResult(50);
List users=criteria.list();
添加查询条件
Criteria criteria=session.createCriteria(User.class);
criteria.add(Restrictions.like("username","admin%"));
criteria.add(Restrictions.between("ID",1,10));
List users=criteria.list();
或直接用sql
Criteria criteria=session.createCriteria(User.class)
.add(Restrictions.sql("lower({alias}.username) like lower(?)","admin%",Hibernate.STRING));
添加排序条件
Criteria criteria=session.createCriteria(User.class);
.add(Restrictions.like("username","admin%"))
.addOrder(Order.asc("username"))
.addOrder(Order.desc("password"))
.setMaxResult(50)
.list();
构造条件查询
User user=new User();
user.setUsername("admin");
List results=session.createCriteria(User.class).add(Example.create(user)).list();
 
 
六、hibernate主键生成机制
1) assigned
主键由外部程序负责生成,无需Hibernate参与。


2) hilo
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。


3) seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle。


4) increment
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。因此,如果同一数据库有多个实例访问,此方式必须避免使用。


5) identity
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL中的主键生成机制。


6) sequence
采用数据库提供的sequence 机制生成主键。如Oralce 中的Sequence。


7) native
由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。


8) uuid.hex
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。


9) uuid.string
与uuid.hex 类似,只是生成的主键未进行编码(长度16)。在某些数据库中可能出现问题(如PostgreSQL)。


10) foreign
使用外部表的字段作为主键。一般而言,利用uuid.hex方式生成主键将提供最好的性能和数据库平台适应性。


另外由于常用的数据库,如Oracle、DB2、SQLServer、MySql 等,都提供了易用的主键生成机制(Auto-Increase 字段或者Sequence)。我们可以在数据库提供的主键生成机制上,采用generator-class=native的主键生成方式。不过值得注意的是,一些数据库提供的主键生成机制在效率上未必最佳,大量并发insert数据时可能会引起表之间的互锁。数据库提供的主键生成机制,往往是通过在一个内部表中保存当前主键状态(如对于自增型主键而言,此内部表中就维护着当前的最大值和递增量),之后每次插入数据会读取这个最大值,然后加上递增量作为新记录的主键,之后再把这个新的最大值更新回内部表中,这样,一次Insert操作可能导致数据库内部多次表读写操作,同时伴随的还有数据的加锁解锁操作,这对性能产生了较大影响。因此,对于并发Insert要求较高的系统,推荐采用uuid.hex 作为主键生成机制。

你可能感兴趣的:(Hibernate)