JavaWeb学习之Hibernate框架(三)

hibernate中实体的规则

  实体类创建的注意事项

  1、持久化类提供无参构造

  2、成员变量私有,需要提供属性(get/set方法)访问

  3、持久化类中的属性,应尽量使用包装类(可以比基本数据类型多存一个null值)

  4、持久化类需要提供oid,与数据库中的主键列对应(oid不是本表中的字段,只为传值使用)

  5、不要用final修饰class---hibernate使用cglib代理生成代理对象,代理对象是继承被代理对象,如果被final修饰,将无法生成代理。

       主键类型

        自然主键(少见)---表的业务列中,有某业务列符合必须有,并且不重复的特征时,该列可以作为主键使用。

        代理主键(常见)---表的业务列中,没有某业务列符合,必须有,并且不重复的特征时,创建一个没有业务意义的列作为主键。

        主键生成策略

         代理主键:identity:主键自增,由数据库来维护主键值,录入时不需要指定主键

                          sequence:Oracle中的主键生成策略

                           native:hilo+sequence+identity  自动三选一策略

                           uuid:产生随机字符串作为主键,主键类型必须为string 类型

        自然主键:assigned:自然主键生成策略。hibernate不会管理主键值,由开发人员自己录入

                        

hibernate中的对象状态

  对象分为三种状态

        瞬时状态:没有id,没有在session缓存中

        持久化状态:有id,在session缓存中

        游离/托管状态:有id,没有在session缓存中

   三种状态的转换图

    

package com.test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.domain.Customer;
import com.util.HibernateUtil;

public class Test01 {
	@Test
	//save方法实际作用:其实不能理解为保存,理解成将瞬时状态或者游离状态--->持久化状态
	//sql实际上是为了生成主键id,将对象转为持久化状态,必须有id值(数据库中的id)
	public void method1() {
		// 获取会话对象
		Session session = HibernateUtil.openSession();
		// 开启事务
		Transaction tx = session.beginTransaction();
		Customer c = new Customer(); //瞬时状态(没有id,与session没有关联)
		//c.setCust_id("1");//瞬时状态(id是数据库里面的id)
		c.setCust_name("张三");//瞬时托管状态
		session.save(c);//持久化状态(有id,与session有关联)
		//insert只是为了生成id 
		tx.commit();
		session.close();
	}
}
@Test
	//持久化状态的特点:持久化状态的对象的任何变化都会自动同步到数据库中
	//update方法真正作用是:将游离状态的对象转为持久化对象
	public void method2(){
		Session session=HibernateUtil.openSession();
		Transaction tx=session.beginTransaction();
		Customer c=session.get(Customer.class, 1l);//持久化状态
		c.setCust_name("李四");
		//session.update(c);
		tx.commit();
		session.close();//c游离状态托管状态
	}

hibernate进阶---一级缓存

       缓存:提高效率,hibernate中的一级缓存也是为了提高操作数据库的效率

       提高效率的手段1:提高查询效率

@Test
	public void method3(){
		Session session=HibernateUtil.openSession();
		Transaction tx=session.beginTransaction();
		
		Customer c1=session.get(Customer.class, 1L);
		Customer c2=session.get(Customer.class, 1L);
		Customer c3=session.get(Customer.class, 1L);
		Customer c4=session.get(Customer.class, 1L);
		
		System.out.println(c1==c2);//true
		tx.commit();
		session.close();//c游离状态托管状态
	}

    提高效率手段2:减少不必要的修改语句发送

@Test
	public void method4(){
		Session session=HibernateUtil.openSession();
		Transaction tx=session.beginTransaction();
		
		Customer c1=session.get(Customer.class, 1L);
		c1.setCust_name("小明");
		c1.setCust_name("李四");
		
		tx.commit();
		session.close();//c游离状态托管状态
	}

hibernate中的事务

    事务的特性:原子性、一致性、隔离性、持久性

    事务的并发问题:1、脏读,2、不可重复读,3、幻/虚读

    事务的隔离级别:读未提交--1、2、3

                                读已提交--2、3

                                可重复(mysql默认级别)--3

                                 串行化--没有问题  

    如何在hibernate中指定数据库的隔离级别

    在项目中如何管理事务

     1、业务开始之前打开事务,业务执行之后提交事务,执行过程中出现异常就回滚事务

      2、在dao层操作数据库需要用到session对象,在service层控制事务,也就是使用session对象完成。我们要确保dao层和service层使用的是同一个session对象。

      3、在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了,我们开发人员只需要调用sf.getCurrentSession()方法即可获得与当前线程绑定的                         session对象

     注意1、调用getCurrentSession方法必须配合主配置中的一段配置

    注意2、通过getCurrentSession方法获得的session对象,当事务提交时,session会自动关闭,不要手动调用close关闭

     例如:

    在service层

   

    在dao层

  

hibernate中的批量查询

HQL查询--hibernate  query  language(多表查询,但不复杂时使用)

基本查询

条件查询

分页、查询

设置总记录数

原生SQL查询(复杂的业务查询)

    基本查询  ---返回数组List

     

      返回对象List

    

    条件查询

  

   分页查询

     

package com.test;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.domain.Customer;
import com.util.HibernateUtil;

public class Test02 {
	@Test
	public void method1() {
		// 获得与当前线程绑定的session,是同一个session对象
		Session s1 = HibernateUtil.getCurrentSession();
		Session s2 = HibernateUtil.getCurrentSession();
		System.out.println(s1 == s2);// true
	}

	@Test
	public void method2() {
		// 创建一个新的session对象
		Session s1 = HibernateUtil.openSession();
		Session s2 = HibernateUtil.openSession();
		System.out.println(s1 == s2);// false
	}

	@Test
	// hql基本查询
	public void method3() {
		Session session = HibernateUtil.openSession();
		Transaction tx = session.beginTransaction();
		// 查询
		// Customer c=session.get(Customer.class, 1l);
		// String sql="select * from cst_customer";
		// 书写HQL语句
		String hql = "from Customer";
		// 根据HQL语句创建查询对象
		Query query = session.createQuery(hql);
		// 根据查询对象获得查询结果
		List<Customer> list = query.list();
		System.out.println(list);
		// 关闭事务
		tx.commit();
		session.close();
	}

	@Test
	// hql条件查询
	public void method4() {
		Session session = HibernateUtil.openSession();
		Transaction tx = session.beginTransaction();
		// ?占位符
		String hql = "from Customer where cust_name=?";
		// 根据HQL语句创建查询对象
		Query query = session.createQuery(hql);
		// 设置参数
		// query.setLong(0, 1l);
		// 增强版
		query.setParameter(0, "aaa");
		// 执行查询获得结果,唯一的一条结果
		Customer c = (Customer) query.uniqueResult();
		System.out.println(c);
		// 关闭事务
		tx.commit();
		session.close();
	}

	@Test
	// hql条件查询
	public void method5() {
		Session session = HibernateUtil.openSession();
		Transaction tx = session.beginTransaction();
		// 命名占位符
		String hql = "from Customer where cust_name=:aa";
		Query query = session.createQuery(hql);
		query.setParameter("aa", "aaa");
		Customer c = (Customer) query.uniqueResult();
		System.out.println(c);
		tx.commit();
		session.close();
	}

	@Test
	// hql分页查询
	public void method6() {
		Session session = HibernateUtil.openSession();
		Transaction tx = session.beginTransaction();
		// 书写hql语句
		String hql = "from Customer";
		//创建查询对象
		Query query = session.createQuery(hql);
		// 设置分页信息limit 0,2
		query.setFirstResult(0);
		query.setMaxResults(2);
		// 根据查询对象获取查询结果
		List<Customer> list = query.list();
		System.out.println(list);

		tx.commit();
		session.close();
	}
}

  

猜你喜欢

转载自www.cnblogs.com/Java-125/p/9140298.html
今日推荐