Hibernate(三)
1.1Hibernate的检索方式
1.1.1Hibernate的检索方式概述
Hibernate提供了以下几种检索对象的方式:
- 导航对象图检索方式:根据已经家就在的对象导航到其他对象。
- Customer customer = session.get(Customer.class,1);customer.getOrders();获取客户的订单。
- OID检索方式:按照对象的OID来检索对象。
- get()/load()方法来进行检索。
- HQL检索方式:使用面向对象的HQL查询语言。
- QBC检索方式:使用QBC API来检索对象。这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口。
- 本地SQL检索方式:使用本地数据库的SQL查询语句。
1.1.2HQL
- HQL(HIbernate Query Language)是面向对象的查询语言,它和SQL查询语言有些相似,在HIbernate提供的各种检索方式中,HQL是使用最广的一种检索方式。它有如下功能:
- 在查询语句中设定各种查询条件。
- 支持投影查询,即仅查询出对象的部分属性。
- 支持分页查询。
- 支持连接查询。
- 支持分组查询,允许使用having和group by关键字。
- 提供内置聚集函数(分组函数),如sum(),min()和max()等。
- 能够调用用户定义的SQL函数或标准的SQL函数。
- 支持子查询。
- 支持动态绑定参数。
- HQL检索方式包括以下的步骤:
- 通过session的createQuery()方法创建一个Query对象,它包括一个HQL查询语句。HQL查询语句中可以包含命名参数。
- 动态绑定参数。
- 调用Query的ist()方法执行查询语句,该方法返回java.util.List类型的查询结果,在List集合中存放了符合查询条件的持久化对象。
- Query接口支持方法链编程风格,它的setXXX()方法返回自身实例,而不是void类型。
- HQL vs SQL:
- HQL查询语句是面向对象的,HIbernate负责解析HQL查询语句,然后根据对象-关系映射文件中的映射信息,把HQL查询语句翻译成相应的SQL语句,HQL查询语句中的主体是域模型中的类或类的属性。
- SQL查询语句是与关系数据库绑定在一起的。SQL查询语句中的主体是数据库表及表的字段。
1.1.3搭建环境、具体的实体类和映射文件以及核心配置文件
- 实体类
- Customer.java类
package cn.hibernate3.demo4;
import java.io.Serializable;
import java.util.HashSet;
/**
* 客户实体
*/
import java.util.Set;
public class Customer implements Serializable{
private Integer cid;
private String cname;
//一个客户有多个订单
private Set<Order> orders = new HashSet<Order>();
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
- Order.java类
package cn.hibernate3.demo4;
import java.io.Serializable;
/**
* 订单实体
*/
public class Order implements Serializable{
private Integer oid;
private String addr;
//订单属于某一个客户
private Customer customer ;
public Integer getOid() {
return oid;
}
public void setOid(Integer oid) {
this.oid = oid;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
- 映射文件
- Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入约束 -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.hibernate3.demo4.Customer" table="customer">
<!-- 配置唯一标识 -->
<id name="cid" column="cid">
<generator class="native"/>
</id>
<!-- 配置普通属性 -->
<property name="cname" column="cname" type="java.lang.String"/>
<!-- 建立映射 -->
<!-- 配置集合 -->
<!--
set标签中的name表示关联对象的属性名称
-->
<set name="orders">
<!-- key标签中的column用来一对多的多的一方的外键 -->
<key column="cno"/>
<!-- 配置一个one-to-many -->
<one-to-many class="cn.hibernate3.demo4.Order" />
</set>
</class>
</hibernate-mapping>
- Order.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入约束 -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.hibernate3.demo4.Order" table="orders">
<!-- 配置唯一标识 -->
<id name="oid" column="oid">
<generator class="native"/>
</id>
<!-- 配置普通属性 -->
<property name="addr" column="addr" type="java.lang.String"/>
<!-- 建立映射 -->
<!--
many-to-one标签
属性:
name:关联对象的属性名称。
column:表中外键的名称。
class:关联对象的全路径。
-->
<many-to-one name="customer" column="cno" class="cn.hibernate3.demo4.Customer"></many-to-one>
</class>
</hibernate-mapping>
- 核心配置文件hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置数据库的基本信息 -->
<!-- 驱动的名称 -->
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 访问数据库的url -->
<property name="hibernate.connection.url">
jdbc:mysql:///hibernate_day03
</property>
<!-- 用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 密码 -->
<property name="hibernate.connection.password">root</property>
<!-- 方言 -->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- C3P0连接池设定-->
<!-- 使用c3po连接池 配置连接池提供的供应商-->
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
<!-- 可选配置 -->
<!-- 显示SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- hbm:映射 2:to ddl:create drop alter -->
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping resource="cn/hibernate3/demo4/Customer.hbm.xml" />
<mapping resource="cn/hibernate3/demo4/Order.hbm.xml" />
</session-factory>
</hibernate-configuration>
- 工具类HibernateUtils.java
package cn.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* Hibernate抽取工具类
*/
public class HibernateUtils {
private static Configuration configuration;
private static SessionFactory sessionFactory;
static{
configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
}
public static Session openSession(){
return sessionFactory.openSession();
}
public static void main(String[] args) {
openSession();
}
}
- 初始化数据
@Test
//初始化数据
public void demo1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
customer.setCname("小金");
for (int i = 0; i < 10; i++) {
Order order = new Order();
order.setAddr("江苏"+i);
order.setCustomer(customer);
customer.getOrders().add(order);
}
session.save(customer);
tx.commit();
session.close();
}
@Test
//初始化数据
public void demo1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
customer.setCname("小名");
for (int i = 0; i < 10; i++) {
Order order = new Order();
order.setAddr("北京"+i);
order.setCustomer(customer);
customer.getOrders().add(order);
}
session.save(customer);
tx.commit();
session.close();
}
- 需要配置级联关系Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入约束 -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.hibernate3.demo4.Customer" table="customer">
<!-- 配置唯一标识 -->
<id name="cid" column="cid">
<generator class="native"/>
</id>
<!-- 配置普通属性 -->
<property name="cname" column="cname" type="java.lang.String"/>
<!-- 建立映射 -->
<!-- 配置集合 -->
<!--
set标签中的name表示关联对象的属性名称
-->
<set name="orders" cascade="save-update">
<!-- key标签中的column用来一对多的多的一方的外键 -->
<key column="cno"/>
<!-- 配置一个one-to-many -->
<one-to-many class="cn.hibernate3.demo4.Order" />
</set>
</class>
</hibernate-mapping>


1.1.4简单查询及别名查询
- HQL:简单查询
@Test
//查询所有数据
public void demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer.getCname());
}
tx.commit();
session.close();
}
- QBC:简单查询
@Test
//查询所有数据
public void demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer.getCname());
}
tx.commit();
session.close();
}
- SQL:简单查询
@Test
//查询所有数据
public void demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
SQLQuery query = session.createSQLQuery("select * from customer");
List<Customer> list = query.addEntity(Customer.class).list();
for (Customer customer : list) {
System.out.println(customer.getCname());
}
tx.commit();
session.close();
}
@Test
//查询所有数据
public void demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
SQLQuery query = session.createSQLQuery("select * from customer");
List<Object[]> list = query.list();
for (Object[] obj : list) {
System.out.println(Arrays.toString(obj));
}
tx.commit();
session.close();
}
- HQL:使用别名
@Test
//使用别名
public void demo3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer as c where c.cname = ?");
query.setString(0, "小金");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer.getCid()+","+customer.getCname());
}
tx.commit();
session.close();
}
1.1.5排序、参数绑定和投影查询
- 对查询结果进行排序
- HQL
@Test
//排序
public void demo4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c order by c.cid asc");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer.getCid()+","+customer.getCname());
}
tx.commit();
session.close();
}
@Test
//排序
public void demo4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c order by c.cid desc");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer.getCid()+","+customer.getCname());
}
tx.commit();
session.close();
}
- QBC
@Test
//排序
public void demo5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(org.hibernate.criterion.Order.asc("cid"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer.getCid()+","+customer.getCname());
}
tx.commit();
session.close();
}
@Test
//排序
public void demo5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(org.hibernate.criterion.Order.desc("cid"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer.getCid()+","+customer.getCname());
}
tx.commit();
session.close();
}
- 分页查询:
- setFirstResult(int firstResult);设置从哪一个对象开始检索,参数firstResult表示这个对象在查询结果中的索引位置。索引位置的起始值为0。默认情况下,Query从查询结果中的第一个对象开始检索。
- setMaxResult(int maxResult);设置一次最多检索出的对象的数目。在默认情况下,Query和Criteria接口检索出查询结果中的所有对象。
- HQL分页查询
@Test
//分页
public void demo6(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c ");
query.setFirstResult(0);
query.setMaxResults(1);
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer.getCid()+","+customer.getCname());
}
tx.commit();
session.close();
}
- QBC:分页查询
@Test
//分页
public void demo7(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(0);
criteria.setMaxResults(1);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer.getCid()+","+customer.getCname());
}
tx.commit();
session.close();
}
- 检索单个对象
- HQL
@Test
public void demo8(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c where c.cname = ?");
query.setString(0, "小名");
Customer customer = (Customer) query.uniqueResult();
System.out.println(customer.getCid()+","+customer.getCname());
tx.commit();
session.close();
}
- QBC
@Test
public void demo9(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("cname", "小名"));
Customer customer = (Customer) criteria.uniqueResult();
System.out.println(customer.getCid()+","+customer.getCname());
tx.commit();
session.close();
}
- 参数绑定(HQL)
- HIbernate的参数绑定机制依赖于JDBC API中的PreparedStatement的预定义SQL语句功能。
- HQL的参数绑定有两种形式:
- 按照参数位置绑定:在HQL查询语句中使用"?"来定义参数位置。
@Test
public void demo8(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c where c.cname = ?");
query.setString(0, "小名");
Customer customer = (Customer) query.uniqueResult();
System.out.println(customer.getCid()+","+customer.getCname());
tx.commit();
session.close();
}
- 使用名称方式绑定:在HQL查询语句中定义命名参数,命名参数以":"开头。
@Test
public void demo8(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c where c.cname =:name");
query.setParameter("name", "小名");
Customer customer = (Customer) query.uniqueResult();
System.out.println(customer.getCid()+","+customer.getCname());
tx.commit();
session.close();
}
- 投影查询:
- 查询结果仅仅包含实体的部分属性。通过select关键字实现。
- Query的list()方法返回的集合是包含数组类型的元素,每个对象数据代表查询结果的一条记录。
- 可以在持久化类中定义一个对象的构造器来包装投影查询返回记录,使得程序能完全运用面向对象的语义来访问查询结果集。
- 可以通过distinct关键字来保证查询结果不会返回重复元素。
- HQL:
@Test
//投影操作:查询对象的某几个属性
public void demo10(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select c.cname from Customer c ");
List<Object> list = query.list();
for (Object obj : list) {
System.out.println(obj);
}
tx.commit();
session.close();
}
@Test
//投影操作:查询对象的某几个属性
public void demo10(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select c.cname ,c.cid from Customer c ");
List<Object[]> list = query.list();
for (Object[] obj : list) {
System.out.println(Arrays.toString(obj));
}
tx.commit();
session.close();
}
- QBC
@Test
//投影操作:查询对象的某几个属性
public void demo10(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
List<Object[]> list = session.createCriteria(Customer.class).setProjection(Projections.projectionList().add(Property.forName("cname")).add(Property.forName("cid"))).list();
for (Object[] obj : list) {
System.out.println(Arrays.toString(obj));
}
tx.commit();
session.close();
}
1.1.6HQL和QBC支持的各种运算
- QBC

- HQL vs QBC


1.1.7连接查询
- SQL连接:
- 交叉连接:
- select * from A,B;
- 内连接:是两个表的交集:
- select * from A inner join B on A.字段 = B.字段;
- 隐式内连接:
- select * from A,B where A.字段 = B.字段;
- 外连接:
- 左外连接:
- select * from A left outer join B on A.字段 = B.字段;
- 右外连接:
- select * from A right outer join B on A.字段 = B.字段;
- 左外连接:
- 交叉连接:
- HQL连接:
- 交叉连接
- 内连接
- 隐式内连接
- 迫切内连接
- 左外连接
- 迫切左外连接
- 右外连接
- 示例:左外连接,返回的List<Object[]>。
@Test
//多表查询
public void demo11(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c inner join c.orders");
List<Object[]> list = query.list();
for (Object[] obj : list) {
Customer customer = (Customer) obj[0];
Order order = (Order) obj[1];
System.out.print("customer:"+customer.getCid()+","+customer.getCname());
System.out.print("order:"+order.getOid()+","+order.getAddr()+"\n");
}
tx.commit();
session.close();
}

- 为什么返回的是List<Object[]),因为查询返回的字段是好几个,Hibernate将数据封装到对象数组之中。

- 示例:迫切左外连接,返回的是List<Customer>。
@Test
//多表查询
public void demo11(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c inner join fetch c.orders ");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.print(customer.getCid()+","+customer.getCname());
Set<Order> orders = customer.getOrders();
for (Order order : orders) {
System.out.print(order.getOid()+","+order.getAddr());
}
System.out.println();
}
tx.commit();
session.close();
}

- 为什么返回的List<Object>,因为Hibernate会每查询一个表中的某个记录,就将记录封装到对象之中,这样就会产生重复的结果?怎么办?使用distinct关键字即可,消除重复的结果。
@Test
//多表查询
public void demo11(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select distinct c from Customer c inner join fetch c.orders ");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.print(customer.getCid()+","+customer.getCname());
Set<Order> orders = customer.getOrders();
for (Order order : orders) {
System.out.print(order.getOid()+","+order.getAddr());
}
System.out.println();
}
tx.commit();
session.close();
}

- 连接查询:HQL vs QBC

1.1.8离线条件查询

@Test
//多表查询
public void demo12(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//在web层
DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
criteria.add(Restrictions.eq("cname", "小名"));
//在dao层:web层将Criteria传递到service层,然后service层再将Criteria传递到dao层
//这样在dao层,就可以从session中获取离线的Criteria。
Criteria criteria2 = criteria.getExecutableCriteria(session);
List<Customer> list = criteria2.list();
for (Customer customer : list) {
System.out.println(customer.getCid()+","+customer.getCname());
}
tx.commit();
session.close();
}
1.1.9HQL和QBC检索的总结
| 比较方面 | HQL检索 | QBC检索 |
| 可读性 | 优点:和SQL相近,易读。 | 将语句肢解成一组Criteria,较差。 |
| 功能 | 支持各种查询。 | 不支持分组查询和子查询。有限制。 |
| 查询语句形式 | 基于字符串形式的HQL | 更加面向对象。 |
| 何时被解析 | 运行时被解析。 | 编译时被解析,更易排错。 |
| 可扩展性 | 不具扩展性。 | 用户可扩展Criteria接口。 |
| 对动态查询语句的支持 | 支持动态查询,编程麻烦。 | 适合动态生成查询语句。 |
1.2Hibernate的抓取(检索)策略
1.2.1区分延迟和立即检索
- 立即检索:
- 当执行某行代码的时候,马上发出SQL语句进行查询。
- get();
- 延迟检索:
- 当执行某行代码的时候,不会马上发出SQL语句进行查询。当真正使用这个对象的时候才会发送SQL语句。
- load();
- 类级别的检索和关联级别的检索。
- 类级别的检索:
- <class>标签上配置lazy="true/false"。
- 关联级别的检索:
- <set>/<many-to-one>标签上配置lazy="true/false"。
- 类级别的检索:
- 从一的一方去关联多的一方:
- <set>
- fetch:控制SQL语句的类型。
- join:发送迫切左外连接的SQL查询关联对象。fetch="join"那么lazy被忽略。
- select:默认值。发送多条SQL查询关联对象。
- subselect:发送子查询查询关联对象。(需要使用Query接口测试)。
- lazy:控制关联对象的检索是否采用延迟。
- true:默认值。查询关联对象的时候使用延迟检索。
- false:查询关联对象的时候不使用延迟检索。
- extra:极其懒惰的。
- 如果fetch是join的类型,那么lazy属性可以忽略。
- fetch:控制SQL语句的类型。
- <set>
- 从多的一方关联一的一方:
- <many-to-one>
- fetch:控制SQL语句的类型。
- join:发送一个迫切左外连接查询关联对象。fetch="join",lazy属性会被忽略。
- select:发送多条SQL检索关联对象。
- lazy:控制关联对象的检索是否采用延迟。
- false:不延迟。
- proxy:使用代理。
- no-proxy:不使用代理。
- fetch:控制SQL语句的类型。
- <many-to-one>
1.3Hibernate的事务处理
- 事务:
- 事务就是逻辑上的一组操作,要么全部成功,要么全部失败。
- 事务特性:
- 原子性:事务一组操作不可分割。
- 一致性:事务的执行前后,数据完整性要保持一致。
- 隔离性:一个事务在执行的过程中不应该受到其他事务的干扰。
- 持久性:一旦事务结束,数据就永久保存到数据库里。
- 如果不考虑事务的隔离性,会引发一些安全性问题:
- 5大类问题:3类读问题2类写问题。
- 读问题:
- 脏读:一个事务读取到另一个事务未提交数据。
- 不可重复读:一个事务已经读取到另一个事务已经提交数据(update),导致查询结果不一致。
- 虚读:一个事务读到另一个事务已经提交的数据(insert),导致查询结果不一致。
- 避免三种读的问题:
- 设置事务的隔离级别:
- 未提交读:以上三种读问题 都有可能发生。
- 已提交读:避免脏读,但是不可重复读和虚读可能发生。
- 重复读:避免脏读和不可重复读,但是虚度是有可能发生的。
- 串行读:可以避免以上三种读问题。
- 设置事务的隔离级别:
- 在Hibernate中设置事务的隔离级别:
- 在核心配置文件中:
- <property name="hibernate.connection.isolation">4</property>
- 在核心配置文件中:
- 读问题:
- 5大类问题:3类读问题2类写问题。
<!--
1—Read uncommitted isolation
2—Read committed isolation
4—Repeatable read isolation
8—Serializable isolation
-->
<property name="hibernate.connection.isolation">4</property>
- 写问题:丢失更新。
- 悲观锁:
- 乐观锁:
- 写问题:丢失更新。
- 线程绑定session:
- 在hibernate.cfg.xml中配置一个:
- <property name="hibernate.current_session_context_class">thread</property>
- 使用SessionFactory中的getCurrentSession();方法
- 底层就是ThreadLocal。
- 在hibernate.cfg.xml中配置一个:
Hibernate(三)的更多相关文章
- 简单理解Hibernate三种状态的概念及互相转化
本文描述了Hibernate三种状态的概念及互相转化.Java对象的生命周期中有三种状态,而且互相转化.它们分别是临时状态,持久化状态,以及游离状态. AD:WOT2015 互联网运维与开发者大会 热 ...
- [转]hibernate三种状态详解
本文来自 http://blog.sina.com.cn/u/2924525911 hibernate 三种状态详解 (2013-04-15 21:24:23) 转载▼ 分类: hibernate ...
- hibernate三种状态
转自:http://www.cnblogs.com/xiaoluo501395377/p/3380270.html 学过hibernate的人都可能都知道hibernate有三种状态,transien ...
- hibernate(三) 一对多映射关系
序言 前面两节讲了hibernate的两个配置文件和hello world!.还有hibernate的一级缓存和三种状态,基本上hibernate就懂一点了,从这章起开始一个很重要的知识点,hiber ...
- Hibernate三种状态的转换
hibernate的状态 hibernate的各种保存方式的区(save,persist,update,saveOrUpdte,merge,flush,lock)及 对象的三种状态 hibernate ...
- Hibernate三种状态的区分,以及save,update,saveOrUpdate,merge等的使用 引自http://www.blogjava.net/TiGERTiAN/archive/2008/10/25/236519.html
Hibernate的对象有3种状态,分别为:瞬时态(Transient). 持久态(Persistent).脱管态(Detached).处于持久态的对象也称为PO(Persistence Object ...
- Hibernate(三)——框架中的关系映射
在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系.而Hibernate时间实体类和数据库中的表进行的映射, ...
- hibernate 三种状态的转换
一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...
- SSH框架之-hibernate 三种状态的转换
一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...
- Hibernate三种状态,缓存,以及update更新问题
一. Hibernate中对象的三种状态 1. 瞬时状态(transient) 当我们通过Java的new关键字来生成一个实体对象时,这时这个实体对象就处于自由状态,此时该对象只是通过JVM获得了一块 ...
随机推荐
- Spring MVC 项目搭建 -1- 创建项目
Spring MVC 项目搭建 -1- 创建项目 1.创建 Dynamic Web project (SpringDemo),添加相关jar包 2.创建一个简单的controller类 package ...
- 把对象列表转化成json数据格式
package JsonTest; import java.util.ArrayList; import java.util.List; public class test { public stat ...
- cygwin和ffmpeg的两三事
cygwin和ffmpeg的下载地址: https://cygwin.com/install.html http://www.ffmpeg.org/download.html 标题看上去有些无厘头,然 ...
- 机器学习之支持向量机(SVM)
支持向量机 百度百科(基本看不懂):http://baike.baidu.com/link?url=Z4MU6AYlf5lOX7UGHVYg9tBvxBGOkriPtNt0DixmscnMz06q5f ...
- Luogu 1090 合并果子(贪心,优先队列,STL运用)
Luogu 1090 合并果子(贪心,优先队列,STL运用) Description 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每 ...
- js&jquery跨域详解jsonp,jquery并发大量请求丢失回调bug
URL 说明 是否允许通信 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.js http:/ ...
- Codeforces Round #423 B. Black Square
题目网址:http://codeforces.com/contest/828/problem/B 题目: Polycarp has a checkered sheet of paper of size ...
- 前端javascript中字符串的总结
1.截取方法 截取字符串的abcdefg中的efg. 注意:str.length从1的开始数 var str="abcdefg"; (1).slice() : console.lo ...
- Eclipse详细设置护眼背景色和字体颜色并导出
Eclipse详细设置护眼背景色和字体颜色并导出 Eclipse是一款码农们喜闻乐见的集成开发平台,但是其默认的主题和惨白的背景色实在是太刺激眼球了.下面,将给大家详细介绍如何设置成护眼主题的方法,也 ...
- 初识 tk.mybatis.mapper
在博客园发表Mybatis Dynamic Query后,一位园友问我知不知道通用mapper,仔细去找了一下,还真的有啊,比较好的就是abel533写的tk.mybatis.mapper. 本次例子 ...