zoukankan      html  css  js  c++  java
  • 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();
    	}
    }
    

      

  • 相关阅读:
    经典回溯问题- 迷宫
    关于二叉树的一点补充。
    二叉树重难点总结(判断完全二叉树,非递归前、中、后序遍历的实现等...)
    栈、队列常规操作
    贪吃蛇小游戏
    链表重点问题(下)
    链表常见问题(上)
    动态顺序表
    时间 空间复杂度小结(斐波那契 二分查找举例)
    每天一个linux命令-id,输出用户的uid、gid
  • 原文地址:https://www.cnblogs.com/Java-125/p/9140298.html
Copyright © 2011-2022 走看看