持久化类
概念
- 一个与表建立了映射关系的Java类
- 持久化类 = JavaBean + xxx.hbm.xml
编写规则
- 提供无参构造
- 属性私有,提供get/set方法
- 属性尽量使用包装类类型
- 包装类默认值null,基本数据类型默认0,避免业务逻辑冲突
- 持久化类不要使用final进行修饰
- 使用final修饰,延迟加载(load)失效,变为立即加载(get),hibernate优化手段就没用
- 类中需要提供标识属性(OID),与表中主键建立映射关系
- Hibernate根据标识属性来判断对象是否是同一个的
- Hibernate中实体类的标识属性: Object Identifie 简称OID属性 就是配置文件中对应主键的那个实体类属性
- 作用: 让hibernate来区分对象是否是同一个
- 如果多个对象的标识属性值相同,hibernate会认为是同一个对象,存储数据会报错
持久化对象的三种状态
瞬时态
当前对象没有持久化标识OID, 没有被Session操作管理
- 获得瞬时态的对象
- User user = new User()
- 瞬时态对象转换持久态
- save()/saveOrUpdate();
- 瞬时态对象转换成脱管态
- user.setId(1)
持久态
当前对象有持久化标识OID,已经被Session操作管理
持久态对象会自动更新数据库数据(一级缓存)
- 获得持久态的对象
- get()/load();
- 持久态转换成瞬时态对象
- delete(); --- 比较有争议的,进入特殊的状态(删除态:Hibernate中不建议使用的)
- 持久态对象转成脱管态对象
- session的close()/evict()/clear();
脱管态
当前对象有持久化标识OID,没有被纳入到Session操作管理
- 获得托管态对象:不建议直接获得脱管态的对象.
- User user = new User();
- user.setId(1);
- 脱管态对象转换成持久态对象
- update();/saveOrUpdate()/lock();
- 脱管态对象转换成瞬时态对象
- user.setId(null);
注意
持久态对象有自动更新数据库的能力
hibernate主键生成策略
主键的种类
自然主键
- 对象本身的一个属性
- 创建一个人员表,每个人都有一个身份证号(唯一),使用身份证号作为表的主键,就是自然主键
- 开发中不用
代理主键
- 不是对象本身的一个属性
- 创建一个人员表,为每个人员单独创建一个字段,用这个字段作为主键,代理主键
- 开发中推荐使用代理主键创建表
主键生成策略
increment---自动增长
- Hibernate中提供一种自动增长方式,不是数据库中的自动增长。(适用于short、int、long类型的主键)
- 首先使用select max(cust_id) from cst_customer;将这个最大值+1作为下一条记录的主键
- 不适用并发访问数据库
identity---自动增长
- 适用于short、int、long类型的主键
- 使用的是数据库自动增长机制
- 不是所有数据库都支持自动增长,比如Oracle没有自动增长
sequence---序列
- 适用于short、int、long类型的主键
- 使用序列方式完成主键的生成
- 必须是支持序列的方式的数据库:Oracle的自动增长
native---本地策略
- 根据底层的数据库不同,自动选择使用identity还是sequence
uuid---随机字符串
- 适用于字符串类型的主键
assigned---Hibernate不维护主键
- 开发人员需要手动设置主键
注意
- 以后如果针对是数值型,选择用native
- 如果是varchar类型,可以选择用uuid
- 也可以不用hibernate维护,自己在程序中手动设定唯一非空(assigned)
hibernate一级缓存
什么是缓存
缓存就是一块内存空间,将数据源(数据库或者文件)中的数据存放到缓存中,再次获取的时候,直接从缓存中获取,可以提升程序的性能!
Hibernate的缓存
一级缓存
- 自带的不可卸载的
- 一级缓存的生命周期与session一致,缓存的数据,会随着session的销毁而销毁
- 一级缓存称为session级别的缓存
二级缓存
- 默认没有开启,需要手动配置才可以使用的
- 二级缓存可以在多个session中共享数据
- 二级缓存称为是sessionFactory级别的缓存
- 添加配置缓存的插件,使用ehche数据库,后来被redis取代
方法
- Session.clear() -- 清空缓存
- Session.evict(Object entity) -- 从一级缓存中清除指定的实体对象
- Session.flush() -- 刷出缓存
注意
- 增,改,查时,先去数据库操作,都会往一级缓存中留一份
- session只要关闭,一级缓存的数据全部清空
Session对象的缓存概述
- Session接口中有一系列的java的集合,这些java集合构成了Session级别的缓存(一级缓存)
- 将对象存入到一级缓存中,session没有结束生命周期,那么对象在session中存放着
- 内存中包含Session实例 --> Session的缓存(一些集合) --> 集合中包含的是缓存对象
证明一级缓存的存在
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itheima.domain.Customer;
import com.itheima.utils.HibernateUtils;
public class TestSession {
/**
* @MethodName:test01
* @Description:测试hibernate一级缓存的存在
* @throws Exception
*/
@Test
public void test01() throws Exception {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
customer.setCustName("jack");
// 保存用户,customer先往数据库中存一份,一级缓存中有一份
Serializable id = session.save(customer);
System.out.println(id);
// 获取对象,不会看到SQL语句,直接去一级缓存中查找
Customer c = session.get(Customer.class, id);
System.out.println(c.getCustName());
tx.commit();
session.close();
}
/**
* @MethodName:test02
* @Description:测试hibernate一级缓存的存在
* @throws Exception
*/
@Test
public void test02() throws Exception {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
customer.setCustName("jack");
// 查询用户,先去数据库中查,查完放在一级缓存中一份
Customer c1 = session.get(Customer.class, 1l);
System.out.println(c1.getCustName());
// 再去查询用户,不会看到SQL语句,直接去一级缓存中查找
Customer c2 = session.get(Customer.class, 1l);
System.out.println(c2.getCustName());
tx.commit();
session.close();
}
}
快照机制
import static org.junit.Assert.*;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itheima.domain.Customer;
import com.itheima.utils.HibernateUtils;
public class TestSession {
/**
* @MethodName:test04
* @Description:快照机制
* @throws Exception
*/
@Test
public void test04() throws Exception {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer = session.get(Customer.class, 1l);
customer.setCustName("隔壁老王");
tx.commit();
session.close();
}
}
绑定本地的Session
添加hibernate核心配置
<property name="hibernate.current_session_context_class">thread</property>
改造工具类
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
public static final Configuration config;
public static final SessionFactory sessionFactory;
static{
config= new Configuration().configure();
sessionFactory = config.buildSessionFactory();
}
//绑定当前线程
public static Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
}
Hibernate框架的查询方式
HQL查询
import java.util.Arrays;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itheima.domain.Customer;
import com.itheima.utils.HibernateUtils;
/**
* @ClassName: TestQuery
* @Description:测试批量查询
* @author jsz
* @date 2018年8月18日
*/
public class TestQuery {
/**
* @MethodName:test01
* @Description:测试query查询接口
* @throws Exception
*/
@Test
public void test01() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// from 实体类名
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test02
* @Description:条件查询
* @throws Exception
*/
@Test
public void test02() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer where custName =?");
// hibernate的占位符从0开始
query.setString(0, "ccc");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test03
* @Description:模糊查询
* @throws Exception
*/
@Test
public void test03() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer where custName like ?");
// hibernate的占位符从0开始
query.setString(0, "c%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test04
* @Description:分页查询
* @throws Exception
*/
@Test
public void test04() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer");
query.setFirstResult(1);// 从第几条开始查
query.setMaxResults(3);// 查几条
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test05
* @Description:查询单列数据
* @throws Exception
*/
@Test
public void test05() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select custName from Customer");
List<Object> list = query.list();
for (Object object : list) {
System.out.println(object);
}
tx.commit();
}
/**
* @MethodName:test06
* @Description:多列查询
* @throws Exception
*/
@Test
public void test06() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select custId,custName from Customer");
List<Object[]> list = query.list();
for (Object[] object : list) {
System.out.println(Arrays.toString(object));
}
tx.commit();
}
/**
* @MethodName:test07
* @Description:投影查询
* @throws Exception
*/
@Test
public void test07() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// select new 实体类(属性,custName) from 实体类
// 实体类中必须有要查询的两个字段的构造
Query query = session.createQuery("select new Customer(custId,custName) from Customer");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test08
* @Description:排序查询
* @throws Exception
*/
@Test
public void test08() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// select new 实体类(属性,custName) from 实体类
Query query = session.createQuery(" from Customer order by custId desc");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test09
* @Description:聚合查询
* @throws Exception
*/
@Test
public void test09() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select count(*) from Customer");
Object object = query.uniqueResult();// 返回只有一个值的单列的数据
System.out.println(object);
tx.commit();
}
}
QBC查询
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import com.itheima.domain.Customer;
import com.itheima.utils.HibernateUtils;
public class TestCriteria {
/**
* @MethodName:test01
* @Description:查询全部
* @throws Exception
*/
@Test
public void test01() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test02
* @Description:条件查询
* @throws Exception
*/
@Test
public void test02() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
/*
* == eq > gt >= ge < lt <= le <> ne in in like like
*
*/
criteria.add(Restrictions.eq("custName", "bbb"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test03
* @Description:模糊查询
* @throws Exception
*/
@Test
public void test03() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
/*
* == eq > gt >= ge < lt <= le <> ne in in like like
*
*/
criteria.add(Restrictions.like("custName", "b%"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test04
* @Description:分页查询
* @throws Exception
*/
@Test
public void test04() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(0);
criteria.setMaxResults(3);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test05
* @Description:排序查询
* @throws Exception
*/
@Test
public void test05() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(Order.desc("custId"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
/**
* @MethodName:test06
* @Description:聚合函数
* @throws Exception
*/
@Test
public void test06() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.setProjection(Projections.rowCount());
Object obj = criteria.uniqueResult();
System.out.println(obj);
tx.commit();
}
}