Java 框架 01 — Hibernate 02(主键种类、主键生成策略、Hibernate对象状态、HQL/Criteria/SQL查询、事务回顾)

0 回顾:

0.1 hibernate -> 操作数据库Dao

  1. 导包 - required/驱动包

  2. 准备数据库/实体类

  3. 配置文件

    1. 主配置文件 src/hibernate.cfg.xml

      1. property: project/etc/hibernate.properties
        • 5[数据库连接信息+方言] + 3[showformatauto]
        • 连接池
        • mapping - 引入ORM元数据
    2. ORM元数据配置 - 映射文件 - mapping

      • 类、表的映射关系

        <class name="" table>
          	<id name column>
          		<genertor class="native">
          	<property name>
        
  4. 使用

    1. 加载配置文件 Configuration configure()
    2. 获得 SessionFactory
    3. 获得 Session
    4. 开启事务 Transaction
    5. session.get/load/save/delete/update
    6. 关闭事务 commit/rollback
    7. 关闭资源 Session.close()

一、JavaBean规范:

  1. 属性私有化,提供get/set
  2. 提供无参构造器
  3. 基本数据类型建议使用包装类
  4. 必须有主键oid对应属性
  5. 不能用final修饰 -> CGlib代理

二、主键

2.1 主键种类

​ 代理主键:业务无关、对象无关,不能修改
​ 自然主键:表中存在非空并且唯一的字段,例如身份证号

2.2 主键生成策略

  • 主键生成策略 - 新增数据时,主键生成的方式
  • 代理主键:
    1. identity:数据库维护,自增长,不需要手动录入
    2. sequence:数据库维护,seq.nextVal 序列方式,需要指定参数[序列名],不需要手动录入
    3. increment:Hibernate维护,自增长,不需要录入
      • 在插入之前先查找ID最大值,+1插入hilo:自增长算法
    4. nativehilo + identity + sequence
      • 自动检测
    5. uuid:hibernate维护,id类型设置为varchar(32)
  • 自然主键:必须手动录入
    1. assigned

三、Hibernate对象状态

在这里插入图片描述

3.1 瞬时状态

  • 瞬时状态:对象没id,并且没有在session缓存中

3.2 持久化状态

  • 持久化状态:对象有id,并且在session缓存中
    • 内容发生修改,在事务提交时,都会同步到数据库中

3.3 游离/托管状态

  • 游离|托管状态:对象有id,没有不在session缓存中
    • session中对对象的操作,其实就是改变对象状态

四、session缓存与快照

4.1 session缓存

  • session缓存作用:为了提高查询效率
    • hibernate一级缓存
	@Test
	public void test01() {
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// 5.Session操作数据库 增删改查
		// -----------------------
		Customer c1 = session.get(Customer.class, 7l);
		Customer c2 = session.get(Customer.class, 7l);
		Customer c3 = session.get(Customer.class, 7l);
		Customer c4 = session.get(Customer.class, 7l);
		Customer c5 = session.get(Customer.class, 7l);
		Customer c6 = session.get(Customer.class, 8l);
		// Session 是有缓存的
		System.out.println(c5 == c6);//true
		// -----------------------
		// 6.关闭事务
		tx.commit();
		// 7.关闭资源 
		session.close();
	}

在这里插入图片描述

4.2 session快照

  • session快照:为了节省不必要的update操作
    • 懒加载:load方法懒加载,lazy="true"
    • 结论:默认设置,就是最佳优化方案
	@Test
	public void test02() {
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// -----------------------
		Customer c = session.get(Customer.class, 7l);
		c.setCust_name("阿里爸爸");
		c.setCust_name("阿里爸爸1");
		c.setCust_name("阿里爸爸2");
		c.setCust_name("阿里爸爸3");
		
		// 快照,节省不必要的操作,提高效率
		c.setCust_name("阿里妈妈");
		
		// -----------------------
		// 6.关闭事务
		tx.commit();
		// 7.关闭资源 
		session.close();
	}

在这里插入图片描述

Redis:缓存数据库,非关系型数据库

五、3种查询方式(重要)

5.1 HQL查询

  • HQL查询:Hibernate Query Language
    • 永远不会出现和表相关信息
    • 单表、简单的多表查询
    • session.createQuery(hql);
	@Test
	// 使用HQL查询全部Customer对象
	public void test01() {
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// -----------------------
		// 1> 通过hql获得query对象
		// select * from cst_customer;
		// from Customer
		Query query = session.createQuery("from Customer");
		// 2> 获得查询集合列表
		List<Customer> list = query.list();
		
		System.out.println(list);
		// -----------------------
		tx.commit();
		session.close();
	}
//-----------------------------------------------------------------------------------
	@Test
	// 使用HQL根据name查询Customer对象
	public void test02() {
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// -----------------------
		// 1> 通过hql获得query对象
		// select * from cst_customer;
		// from Customer where cust_name = ?
//		Query query = session.createQuery("from Customer where cust_id = ? and cust_name=?");
        //命名占位符
		Query query = session.createQuery("from Customer where cust_id=:id and cust_name=:name");
		// 2> 设置占位符参数
//		query.setString(0, "阿里巴巴");
//		query.setParameter(0, "阿里巴巴");
		// :id :name - 命名占位符
		query.setParameter("name", "阿里巴巴");
		query.setParameter("id", 8l);
		
		// 3> 获得结果集 - 唯一结果
		Customer c = (Customer) query.uniqueResult();
		
		System.out.println(c);
		// -----------------------
		tx.commit();
		session.close();
	}

5.2 Criteria查询

  • Criteria查询:单表条件查询
    • 只能做单表查询
    • session.createCriteria(Class);
	@Test
	// 使用Criteria查询全部Customer对象
	public void test01() {
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// -----------------------
		// 1> 通过session获得Criteria对象
		Criteria criteria = session.createCriteria(Customer.class);
		
		// 2> 获得结果
		List<Customer> list = criteria.list();
		
		System.out.println(list);
		// -----------------------
		tx.commit();
		session.close();
	}

//-----------------------------------------------------------------------------------
	@Test
	// 使用Criteria根据name查询Customer对象
	public void test02() {
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// -----------------------
		// 1> 获得criteira对象
		Criteria criteria = session.createCriteria(Customer.class);
		// 2> 设置查询条件 - 静态方法Restrictions
		criteria.add(Restrictions.eq("cust_name", "阿里巴巴"))
		.add(Restrictions.idEq(8l));
		
		// 3> 获得结果集 - 唯一结果
		Customer customer = (Customer) criteria.uniqueResult();
		System.out.println(customer);
		// -----------------------
		tx.commit();
		session.close();
	}

5.3 SQL查询

  • SQL查询
    • session.createSQLQuery(sql);
      • [Ljava.lang.Object;@2416a51,未addEntity(),输出的是这个,不是封装对象
    • addEntity(); -> 才能封装对象
    • list() -> 集合
    • uniqueResult() -> 单条记录
	@Test
	// 使用SQL查询全部Customer对象
	public void test01() {
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// -----------------------
		// 0> sql语句
		String sql = "select * from cst_customer";
		// 1> 通过session获得SQLQuery对象
		SQLQuery sqlQuery = session.createSQLQuery(sql);
		
		// 2> 获得结果 - 所有的记录,每一条封装为一个数组
		List<Object[]> list = sqlQuery.list();
		
		for (Object[] os:list) {
			System.out.println(Arrays.toString(os));
		}
		
		// -----------------------
		tx.commit();
		session.close();
	}
//----------------------------------------------------------------------------------
	@Test
	// 使用SQL查询全部Customer对象 - 封装对象
	public void test03() {
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// -----------------------
		// 0> sql语句
		String sql = "select * from cst_customer";
        
		// 1> 通过session获得SQLQuery对象
		SQLQuery sqlQuery = session.createSQLQuery(sql);
		// 在查询之前,添加实体类型
		sqlQuery.addEntity(Customer.class);
        
		// 2> 获得结果 - 按照实体类型,封装对象
		List<Customer> list = sqlQuery.list();
		System.out.println(list);
		// -----------------------
		tx.commit();
		session.close();
	}
//----------------------------------------------------------------------------------
	@Test
	// 使用sql根据name查询Customer对象
	public void test02() {
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// -----------------------
		// 0> sql语句,占位符只能用?
		String sql = "select * from cst_customer where cust_name=?";
		// 1> 获得SQLQuery对象
		SQLQuery sqlQuery = session.createSQLQuery(sql);
		// 2> 设置查询条件 - 静态方法Restrictions
		sqlQuery.setParameter(0, "阿里巴巴");
		
		// 3> 获得结果集 - 唯一结果
		Customer customer = (Customer) sqlQuery.uniqueResult();
		System.out.println(customer);
		// -----------------------
		tx.commit();
		session.close();
	}

六、事务回顾

  • 事务:业务层面上,不能分割的最小单位

6.1 特点

  • 特点:
    • 原子性
    • 一致性
    • 持久性
    • 隔离性

6.2 并发问题

  • 并发问题:
    • 脏读:别人没提交的事务,被我读到了
    • 幻读:我刚删完的数据,别人又读出来了,感觉出现幻觉了
    • 不可重复读:第一次读的数据和第二次读的不一样
  • 隔离级别:
    • 读未提交。0001
    • 读已提交。0010
    • 可重复读。0100
    • 串行化。1000
  • mysql默认级别 isolution:4
    • hibernate可以设置隔离级别 - 主配置文件
		<!-- 设置隔离级别 -->
		<!-- #hibernate.connection.isolation 4 -->
		<property name="hibernate.connection.isolation">4</property>
		
		<!-- 配置session和当前线程绑定
			"current_session_context_class" thread
		 -->
		<property name="current_session_context_class">thread</property>

6.3 误区

  1. 隔离级别设置
  2. session无需关闭
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值