一、事务
1、什么是事务:
事务:事物指的是逻辑上的一组操作,组成这一组操作的逻辑单元要么全成功,要么全失败
2、事务的特性:
(1)原子性:代表事务不可分割。
(2)一致性:代表事务执行的前后,数据的完整性要保证一直。
(3)隔离性:代表的是一个事务执行的过程当中,不应该受到其他事务的干扰。
(4)持久性:代表一个事务执行完成后数据就持久到数据库当中(提交或回滚)。
3、如果我们不考虑事务的隔离性,就会引发一些安全性的问题
(一)读的问题
(1)脏读:一个事务读到另外一个事务未提交的数据
(2)不可重复读:一个事务读到了另一个事务已经提交的update的数据,导致在前一个事务多次查询结果不一致
(3)虚度/幻读:一个事务读到另外一个事务已经提交的但是insert的数据,导致在前一个事务当中多次查询的结果不一致
(二)写的问题
(1)引发两类丢失更新
4、读问题的解决
(一)设置事务的隔离级别
1、Read uncommitted:未提交读–以上的读问题都会发生
2、Read commited:解决脏读,但是不可重复读和虚读有可能发生(Oracle默认隔离级别)
3、Repeatable read:解决脏读和不可重复读,但是虚读是有可能发生的(MySQL默认隔离级别)
4、Serializable:解决所有的读问题(不能有事物的并发)(安全性高效率低)
二、Hibernate当中要设置事务的隔离级别
核心配置文件hibernate.cfg.xml当中配置对应的属性
4是mysql的默认隔离级别
8是Oracle的默认隔离级别
三、Service层事务
1、Hibernate如何解决Service的事务管理
2、使用getCurrentSession获取当前线程的session对象
(1)改写工具类
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/* Hibernate的工具类*/
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static {
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
public static Session openSession() {
return sf.openSession();
}
public static Session getCurrentSession() {
return sf.getCurrentSession();
}
}
<!-- 设置事务隔离级别 -->
<property name="hibernate.connection.isolaction">4</property>
(2)配置完成(hibernate的核心配置文件当中)
<!-- 配置当前线程来绑定的session -->
<property name="hibernate.current_session_context_class">thread</property>
getCurrentSession获取当前线程的session对象,创建session对象之后不需要调用close方法,在线程结束的时候会自动将session关闭
(3)测试类
package com.itzheng.hibernate.demo01;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
* 测试当前线程绑定的Session
*/
public class HibernateDemo04 {
@Test
public void demo01() {
//会按照配置的好的事务处理方式去存储数据
Session session = HibernateUtils.getCurrentSession();//保证每一个对象在调用该方法的时候都使用的是同一个session
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setCust_name("王西");
session.save(customer);
transaction.commit();
//session.close();不需要二次关闭session。因为在当前线程结束的时候就会关闭session对象,也就缓存
}
}
Hibernate其他API(解决事务当中的问题)
以下API在运行的时候需要配置好核心文件当中
<?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>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day02</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 配置hibernate的方言的 目的是生成对应不同数据的语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可选配置 -->
<!-- 打印SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!-- 自动创建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置C3P0连接池 -->
<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>
<!-- 设置事务隔离级别 -->
<property name="hibernate.connection.isolaction">4</property>
<!-- 配置当前线程来绑定的session -->
<property name="hibernate.current_session_context_class">thread</property>
<mapping resource="com/itzheng/hibernate/demo01/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
以及准备好对应的工具类
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static {
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
public static Session openSession() {
return sf.openSession();
}
public static Session getCurrentSession() {
return sf.getCurrentSession();
}
}
一、Query
Query接口用于接收HQL,查询多个对象。
HQL:Hibernate Query Language :Hibernate查询语言。这种语言与SQL的语法及其类似,是一个面向对象的查询语言。
1、查询所有表当中信息
public class HibernateDemo5 {
@Test
// Query
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session活动Query接口
String hql = "from Customer";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
}
2、查询指定字符的数据(条件查询)
/*
* Hibernate的其他的API
*/
public class HibernateDemo5 {
@Test
// Query
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session活动Query接口
// String hql = "from Customer";
String hql = "from Customer where cust_name like ?";
Query query = session.createQuery(hql);
query.setParameter(0, "王%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
}
分页查询
/*
* Hibernate的其他的API
*/
public class HibernateDemo5 {
@Test
// Query
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session活动Query接口
//分页查询
String hql = "from Customer";
Query query = session.createQuery(hql);
//设置分页
query.setFirstResult(0);//相当于MySQL当中limit的第一个参数
query.setMaxResults(3);
//query.setParameter(0, "王%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
}
改变初始值
@Test
// Query
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session活动Query接口
//分页查询
String hql = "from Customer";
Query query = session.createQuery(hql);
//设置分页---》会根据不同的数据库切换SQL语句
query.setFirstResult(3);//相当于MySQL当中limit的第一个参数
query.setMaxResults(3);
//query.setParameter(0, "王%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
二、Criteria
Criteria:QBC(Query By Criteria);
更加面向对象的一种查询方式。
@Test
// Criteria
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session获得Criteria接口
Criteria criteria = session.createCriteria(Customer.class);// 返回
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
条件查询
@Test
// Criteria
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session获得Criteria接口
Criteria criteria = session.createCriteria(Customer.class);//先获取到criteria的Customer对象
//criteria.add(Restrictions.like("cust_name", "王%"));//设置对应的查询的条件
criteria.add(Restrictions.like("cust_name", "王",MatchMode.START));//在这里上下这两种设置条件的方式实现的功能一致
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
分页查询
@Test
// Criteria
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session获得Criteria接口
/*
* Criteria criteria = session.createCriteria(Customer.class);// 返回
* List<Customer> list = criteria.list();
*/
Criteria criteria = session.createCriteria(Customer.class);//先获取到criteria的Customer对象
//criteria.add(Restrictions.like("cust_name", "王%"));//设置对应的查询的条件
criteria.add(Restrictions.like("cust_name", "王",MatchMode.START));//在这里上下这两种设置条件的方式实现的功能一致
criteria.setFirstResult(0);
criteria.setMaxResults(3);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
修改初始值
@Test
// Criteria
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session获得Criteria接口
/*
* Criteria criteria = session.createCriteria(Customer.class);// 返回
* List<Customer> list = criteria.list();
*/
Criteria criteria = session.createCriteria(Customer.class);//先获取到criteria的Customer对象
//criteria.add(Restrictions.like("cust_name", "王%"));//设置对应的查询的条件
criteria.add(Restrictions.like("cust_name", "王",MatchMode.START));//在这里上下这两种设置条件的方式实现的功能一致
criteria.setFirstResult(3);
criteria.setMaxResults(3);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
三、SQLQuery
SQLQuery用于接收一个SQL语句。如果是特别复杂的使用SQL
@Test
// createSQLQuery
public void demo03() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
SQLQuery query = session.createSQLQuery("select * from cst_customer");
query.addEntity(Customer.class);//设置查询返回时返回对象的元素
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}