Hibernate --- 核心API
2018-01-09 17:08
267 查看
一、Configuration --- 配置启动Hibernate,创建SessionFactory
Configuration 类的作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate 的启动过程中,Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。虽然Configuration
类在整个Hibernate 项目中只扮演着一个很小的角色,但它是启动hibernate 时所遇到的第一个对象。
1.1 Configuration加载配置方式:
(1) 自动加载配置
方式一:
方式二:
(2) 手动加载配置
方式一:
方式二:
1.2 Configuration创建SessionFactory:
二、SessionFactory --- 工厂对象,用来创建Session
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
一个SessionFactory的内部状态是不可变的,一旦创建了这个内部状态的内部设置便不再与Configuration对象关联,这种状态包括所有关于对象/关系映射数据。SessionFactory在Hibernate中起到一个缓冲区的作用,它缓冲了Hibernate自动生成的SQL语句和一些其他的映射数据。
2.1 SessionFactory可以通过两种方法产生Session:
(1)getCurrentSession() --- 线程安全
(2)openSession() --- 非线程安全
2.2 两种产生Session方法的区别有:
(1) openSession()每次打开都是新的Session,并且需要人为的调用close方法关闭Session。
(2) getCurrentSession()是从当前上下文中获取Session并且会绑定到当前线程,第一次调用会自动创建一个Session实例,如果未手动关闭多次获取的是同一个Session,事物提交或者回滚时会自动关闭Session。
(3)使用getCurrentSession时,需要在配置文件中添加如下:
如果使用的是本地事务(JDBC事务)
如果使用的是全局事务(JTA事务)
注意:SessionFactory它不是轻量级的,不要频繁创建关闭它。在一个项目中一般创建一个SessionFactory就可以,通过SessionFactory来获取Session进行操作。
三、Session --- 负责执行CRUD操作
Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。这里当使用session这个术语时,其实指的是Hibernate中的session,而以后会将HttpSession对象称为用户session。
Session的生命周期是以一个逻辑事物的开始和结束为边界,Session的主要功能是提供创建、读取和删除映射的实体类的操作,实体可能存在于三种状态:
(1) 瞬时状态(Transient)
(2) 持久化状态(Persistent)
(3) 脱管状态(Detached)
Hibernate对象的三种状态:
http://blog.csdn.net/ka_ka314/article/details/79017306
Session中有一个缓存,被称为hibernate的第一级缓存,它存放被当前工作单元加载的对象,这块缓存中有一map,在执行save方法后,会生成一个id,这个id会保存在map的key中,与之对应的value值就是该是该对象的引用,执行commit()方法后,数据库就有对应这条数据了,此时该实体处于持久化状态,当执行完Session.close()后,处于托管状态。
Session常用方法:
(1) save() : 保存对象
(2) update() : 修改对象
(3) delete() : 删除对象
(4) get()/load() : 根据id进行查询
get()和load()方法的区别:
--- 从返回结果上对比:
load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常
get方法检索不到的话会返回null
--- 从检索执行机制上对比:
get方法和find方法都是直接从数据库中检索 而load方法的执行则比较复杂首先查找session的persistentContext中是否有缓存,如果有则直接返回
如果没有则判断是否是lazy,如果不是直接访问数据库检索,查到记录返回,查不到抛出异常 如果是lazy则需要建立代理对象,对象的initialized属性为false,target属性为null在访问获得的代理对象的属性时,检索数据库,如果找到记录则把该记录的对象复制到代理对象的target上,并将initialized=true,如果找不到就抛出异常。
get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。
--- get()和load()只根据主键查询,不能根据其他字段查询,如果想根据非主键查询,可以使用HQL
(5) saveOrUpdate : 执行save或update操作
在执行的时候hibernate会检查,如果对象在数据库中已经有对应的记录(是指主键),则会更新update,否则会添加数据save
(6) createQuery() : 获取一个Query对象
获取指定列信息
分页查询
条件查询
(7) createSQLQuery() : 获取一个可以操作SQL的SQLQuery对象
(8) createCriteria() : 获取一个Criteria对象
QBC查询对照表:
(9) clear() : 清除session缓存
无论是load还是get,都会首先查找缓存(一级缓存,也叫session级缓存),如果没有,才会去数据库查找,调用clear()方法可以强制清除session缓存
(10) flush()
在hibernate中也存在flush这个功能,在默认的情况下session.commit()之前时,其实执行了一个flush命令。
Session.flush功能:
清理缓存;
执行sql(确定是执行SQL语句(确定生成update、insert、delete语句等),然后执行SQL语句。)
注意:
flush时,可以自己设定,使用session.setFlushMode(FlushMode)来指定,
FlushMode的取值:
FlushMode.ALWAYS : 任意一条SQL语句,都会flush一次
FlushMode.AUTO : 自动flush(默认)
FlushMode.COMMIT : 只有在commit时才flush
FlushMode.MANUAL : 手动flush
FlushMode.NEVER : 永远不flush,此选项在性能优化时可能用,比如session取数据为只读时用,这样就不需要与数据库同步了
设置flush模式时,需要在session开启事务之前设置。
如果主键生成策略是uuid等不是由数据库生成的,则session.save()时并不会发出SQL语句,只有flush时才会发出SQL语句,但如果主键生成策略是native由数据库生成的,则session.save的同时就发出SQL语句。
(11) evict() : 从session缓存中逐出对象
四、Transaction --- 管理事务
Transaction 接口是一个可选的API,可以选择不使用这个接口,取而代之的是Hibernate 的设计者自己写的底层事务处理代码。 Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA
中的UserTransaction、甚至可以是CORBA 事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移植。
五、Query --- 执行数据库查询
Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。
参考Session.createQuery() or Session.creatSQLQuery()
六、Criteria --- 执行数据库查询
Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。值得注意的是Criteria接口也是轻量级的,它不能在Session之外使用。
参考Session.createCriteria()
Configuration 类的作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate 的启动过程中,Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。虽然Configuration
类在整个Hibernate 项目中只扮演着一个很小的角色,但它是启动hibernate 时所遇到的第一个对象。
1.1 Configuration加载配置方式:
(1) 自动加载配置
方式一:
Configuration config=newConfiguration().config(); //常用:主要加载src下的hibernate.cfg.xml
方式二:
//主要加载的src下的hibernate.properties Configuration config = new Configuration();
(2) 手动加载配置
方式一:
//加载指定的名称的配置文件 Configuration config = new Configuration().configure("hibernate.cfg.xml");
方式二:
//加载配置文件hibernate.cfg.xml Configuration config = new Configuration().configure(); //如果hibernate.cfg.xml配置文件中没有指明映射文件,则可以通过如下方式手动加载映射文件 config.addResource("com/hibernate/domain/Customer.hbm.xml"); config.addClass(Customer.class);
1.2 Configuration创建SessionFactory:
SessionFactory sessionFactory = config.buildSessionFactory();
二、SessionFactory --- 工厂对象,用来创建Session
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
一个SessionFactory的内部状态是不可变的,一旦创建了这个内部状态的内部设置便不再与Configuration对象关联,这种状态包括所有关于对象/关系映射数据。SessionFactory在Hibernate中起到一个缓冲区的作用,它缓冲了Hibernate自动生成的SQL语句和一些其他的映射数据。
2.1 SessionFactory可以通过两种方法产生Session:
(1)getCurrentSession() --- 线程安全
Session session = sessionFactory.getCurrentSession();
(2)openSession() --- 非线程安全
Session session = sessionFactory.openSession();
2.2 两种产生Session方法的区别有:
(1) openSession()每次打开都是新的Session,并且需要人为的调用close方法关闭Session。
(2) getCurrentSession()是从当前上下文中获取Session并且会绑定到当前线程,第一次调用会自动创建一个Session实例,如果未手动关闭多次获取的是同一个Session,事物提交或者回滚时会自动关闭Session。
(3)使用getCurrentSession时,需要在配置文件中添加如下:
如果使用的是本地事务(JDBC事务)
<property name="current_session_context_class">thread</property>
如果使用的是全局事务(JTA事务)
<property name="current_session_context_class">jta</property>
注意:SessionFactory它不是轻量级的,不要频繁创建关闭它。在一个项目中一般创建一个SessionFactory就可以,通过SessionFactory来获取Session进行操作。
三、Session --- 负责执行CRUD操作
Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。这里当使用session这个术语时,其实指的是Hibernate中的session,而以后会将HttpSession对象称为用户session。
Session的生命周期是以一个逻辑事物的开始和结束为边界,Session的主要功能是提供创建、读取和删除映射的实体类的操作,实体可能存在于三种状态:
(1) 瞬时状态(Transient)
(2) 持久化状态(Persistent)
(3) 脱管状态(Detached)
Hibernate对象的三种状态:
http://blog.csdn.net/ka_ka314/article/details/79017306
Session中有一个缓存,被称为hibernate的第一级缓存,它存放被当前工作单元加载的对象,这块缓存中有一map,在执行save方法后,会生成一个id,这个id会保存在map的key中,与之对应的value值就是该是该对象的引用,执行commit()方法后,数据库就有对应这条数据了,此时该实体处于持久化状态,当执行完Session.close()后,处于托管状态。
Session常用方法:
(1) save() : 保存对象
session.save(Object);// session的save方法是向数据库中保存一个对象
(2) update() : 修改对象
session.update(Object);// session的update方法是向数据库中更新一个对象
(3) delete() : 删除对象
session.delete(Object);//Object对象需要有ID。对象删除后,对象状态为Transistent状态
(4) get()/load() : 根据id进行查询
get()和load()方法的区别:
--- 从返回结果上对比:
load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常
get方法检索不到的话会返回null
--- 从检索执行机制上对比:
get方法和find方法都是直接从数据库中检索 而load方法的执行则比较复杂首先查找session的persistentContext中是否有缓存,如果有则直接返回
如果没有则判断是否是lazy,如果不是直接访问数据库检索,查到记录返回,查不到抛出异常 如果是lazy则需要建立代理对象,对象的initialized属性为false,target属性为null在访问获得的代理对象的属性时,检索数据库,如果找到记录则把该记录的对象复制到代理对象的target上,并将initialized=true,如果找不到就抛出异常。
get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。
--- get()和load()只根据主键查询,不能根据其他字段查询,如果想根据非主键查询,可以使用HQL
(5) saveOrUpdate : 执行save或update操作
在执行的时候hibernate会检查,如果对象在数据库中已经有对应的记录(是指主键),则会更新update,否则会添加数据save
(6) createQuery() : 获取一个Query对象
获取指定列信息
// 查询指定列信息 @Test public void test4() { Session session = HibernateUtils.openSession(); session.beginTransaction(); //方式一: // Query query = session.createQuery("select name,address from Customer"); //这时我们得到的不在是Customer对象,而是Object[] // List<Object[]> list = query.list(); //可以使用hibernate中投影查询获取List<Customer>。我们只需要在Customer类中提供name与address做为参数的构造方法 //注意:必须还要提供一个无参构造方法 Query query = session.createQuery("select new Customer(name,address) from Customer"); List<Customer> list = query.list(); session.getTransaction().commit(); session.close(); }
分页查询
// 分页查询 一页显示10条 要得到第二页数据 @Test public void test3() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 一页显示10条 要得到第二页数据 Query query = session.createQuery("from Customer"); query.setFirstResult(10); // 开始位置 query.setMaxResults(10); // 本次查询结果回显的条数 List<Customer> list = query.list(); session.getTransaction().commit(); session.close(); }
条件查询
// 条件查询 @Test public void test5() { Session session = HibernateUtils.openSession(); session.beginTransaction(); //方式一: //Query query = session.createQuery("from Customer where name=?"); //query.setParameter(0, "姓名0"); //方式二: Query query = session.createQuery("from Customer where name=:myname"); // 有名称参数 // 对有名称参数进行赋值 query.setParameter("myname", "姓名0"); // 如果能保证结果就是唯一的,那么可以使用 Customer c = (Customer) query.uniqueResult(); session.getTransaction().commit(); session.close(); }
(7) createSQLQuery() : 获取一个可以操作SQL的SQLQuery对象
// 执行本地sql----查询全部 @Test public void test6() { Session session = HibernateUtils.openSession(); session.beginTransaction(); SQLQuery sqlQuery = session.createSQLQuery("select * from t_customer"); // 想要将结果封装到Customer对象中 sqlQuery.addEntity(Customer.class); List<Customer> list = sqlQuery.list(); session.getTransaction().commit(); session.close(); }
(8) createCriteria() : 获取一个Criteria对象
@Test public void test8() { Session session = HibernateUtils.openSession(); session.beginTransaction(); // 得到Criteria Criteria criteria = session.createCriteria(Customer.class); // 查询所有 // List<Customer> list = criteria.list(); // System.out.println(list); // 分页查询 // criteria.setFirstResult(firstResult) // criteria.setMaxResults(maxResults) // 多条件查询 // 1.查询name='姓名1' //criteria.add(Restrictions.eq("name", "姓名1")); // where name='姓名1'; // 2.查询address='上海' //criteria.add(Restrictions.eq("address", "上海")); //Customer c = (Customer) criteria.uniqueResult(); //System.out.println(c); //查询name='姓名1' 或者 address='上海' criteria.add(Restrictions.or(Restrictions.eq("name", "姓名1"),Restrictions.eq("address","上海"))); List<Customer> list = criteria.list(); System.out.println(list); session.getTransaction().commit(); session.close(); }
QBC查询对照表:
(9) clear() : 清除session缓存
无论是load还是get,都会首先查找缓存(一级缓存,也叫session级缓存),如果没有,才会去数据库查找,调用clear()方法可以强制清除session缓存
(10) flush()
在hibernate中也存在flush这个功能,在默认的情况下session.commit()之前时,其实执行了一个flush命令。
Session.flush功能:
清理缓存;
执行sql(确定是执行SQL语句(确定生成update、insert、delete语句等),然后执行SQL语句。)
注意:
flush时,可以自己设定,使用session.setFlushMode(FlushMode)来指定,
FlushMode的取值:
FlushMode.ALWAYS : 任意一条SQL语句,都会flush一次
FlushMode.AUTO : 自动flush(默认)
FlushMode.COMMIT : 只有在commit时才flush
FlushMode.MANUAL : 手动flush
FlushMode.NEVER : 永远不flush,此选项在性能优化时可能用,比如session取数据为只读时用,这样就不需要与数据库同步了
设置flush模式时,需要在session开启事务之前设置。
如果主键生成策略是uuid等不是由数据库生成的,则session.save()时并不会发出SQL语句,只有flush时才会发出SQL语句,但如果主键生成策略是native由数据库生成的,则session.save的同时就发出SQL语句。
(11) evict() : 从session缓存中逐出对象
session.evict(customer);
四、Transaction --- 管理事务
Transaction 接口是一个可选的API,可以选择不使用这个接口,取而代之的是Hibernate 的设计者自己写的底层事务处理代码。 Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA
中的UserTransaction、甚至可以是CORBA 事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移植。
五、Query --- 执行数据库查询
Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。
参考Session.createQuery() or Session.creatSQLQuery()
六、Criteria --- 执行数据库查询
Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。值得注意的是Criteria接口也是轻量级的,它不能在Session之外使用。
参考Session.createCriteria()
相关文章推荐
- JAVAWEB开发之Hibernate详解(一)——Hibernate的框架概述、开发流程、CURD操作和核心配置与API以及Hibernate日志的使用
- hibernate学习之三——hibernate核心API
- hibernate教程--常用配置和核心API详解
- hibernate_核心API
- hibernate核心api
- 第五章 Hibernate核心API介绍与其使用
- Hibernate核心API
- Hibernate的五个核心API
- hibernate框架(2)---Hibernate的核心API
- 框架 day31 Hibernate入门(log4j简介,核心配置,映射配置,核心api,OID映射)
- hibernate---核心API-JTA/对象的三种状态
- hibernate核心api
- hibernate--4.核心api
- hibernate-核心API-saveOrUpdate-claar-flush
- (02)Hibernate核心API
- Hibernate基础配置及核心API概述
- hibernate核心API
- Hibernate的核心API
- Hibernate3 核心API
- Hibernate API及核心接口简介