hibernate_day02

持久化类

概念

  • 一个与表建立了映射关系的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_day02_第1张图片

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();
	}
}

hibernate_day02_第2张图片
快照机制

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();
	}
}

 

hibernate_day02_第3张图片

绑定本地的Session

添加hibernate核心配置

thread

 改造工具类

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 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 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 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 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 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 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 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 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 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 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 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 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 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();
	}

}

 

你可能感兴趣的:(SSH框架)