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缓存中

   三种状态的转换图

    

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
@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:提高查询效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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:减少不必要的修改语句发送

1
2
3
4
5
6
7
8
9
10
11
12
@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

    

    条件查询

  

   分页查询

     

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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();
    }
}

  

 

posted @   低调的小孩儿  阅读(438)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示