Hibernate学习笔记2

Hibernate–2

学习内容:

  1. 实体类的编写规范(也称作为持久化类)

    实体类的编写规范

    • 类的成员变量声明为private
  • 有默认的无参构造方法

  • 可生成具有唯一标志oid的实例

  • 提供get和set方法(也可以只设置只读方法或者只写方法)

  • 用包装型数据类型替代基本类型,比如id类型应该用Long类型替代long类型

  • 不要用final关键字修饰(否则延迟加载机制会失效)

    JavaBean

    指的是用Java语言编写的可重用

  1. hibernate中的对象标识符

    Hibernate中oid的:指的是表字段中的主键,这个主键交给数据库底层或者Hibernate去生成,这样能够保证oid的一致性,同时对于持久化类,应该将id对应的set方法设置成private类型的(反射能够访问private类型的成员)

  2. hibernate中主键的生成方式

    1. Hibernate的主键生成方式
    2. 自然主键和代理主键的区别
      • 自然主键:区分记录,参与业务逻辑
      • 代理主键:区分记录,不参与业务逻辑
  3. hibernate的一级缓存和快照机制

    • 调用Session的update(),save(),saveOrUpdate()方法时,如果Session缓存中没有相应的对象,Hibernate会自动的将刚刚添加进(更新)的数据添加到Session缓存中,以防临近时机调用不用再重复访问数据库
    • 注意:如果设置了主键自动增长,此时再给对象设置主键字段是无效的
    • 快照区其实相当于数据库的一部分数据的拷贝,他保存了数据库真实的数据,每次commit时,都会检查缓存和快照区的数据时候一致,如果不一致,更新数据库,同时更新快照去
  4. hibernate中的对象状态(三种状态/四种状态)

    • 瞬时状态:没有OID,没有和Session建立关系
    • 持久状态:有OID,有缓存,并且对应的Session也没有关闭,在数据库中有对应的记录,每条记录对应一个唯一的持久态对象,注意它是在事务未提交之前形成的持久态的
    • 脱管状态:某个持久态的实例与其相关联的Session被关闭时就形成了脱管状态,此时他就是一条独立于Hibernate的数据,它的改变与数据库没有什么关系
  5. hibernate中的事务控制

    1. 解决的问题:让Session对象也符合使用原则(即一个线程只有一个Session对象)
  6. hibernate中的查询方式

    1. 查询多条记录的方式

    2. 共5种查询方式

      • OID查询

        使用session的get(),load()方法进行查询

      • SQL查询

        • 第一种:SQLQuery方式(使用的很少)
        • 第二种:Session通过doWork()方法,可以拿到Connection对象
      • HQL查询(官方推荐的查询方式)

        Hibernate Query Language,使用Query对象查询

      • QBC查询

        Query By Criteria,使用Criteria对象执行查询

      • 对象导航查询

        ……

  7. hibernate中的Query对象(重点)

    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    /**
    * @CreateAuthor: KingIsHappy
    * @CreateDate: 2018/4/10
    * @Description: 使用Session中的Query进行查询
    * SQL:select * from cst_customer
    * HQL:select * from Customer
    * 将SQL中的表名换成映射的实体的类名,将将查询的字段名换成实体中对应的属性名
    * <p>
    * 基本查询
    * 条件查询
    * 分页查询
    * 排序查询
    * 统计查询
    * 投影查询
    */
    public class Demo2 {

    /*
    基本查询
    */
    @Test
    public void test1() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    // Query query = session.createQuery("from Customer"); // 查询Customer实体对应的表中的所有的数据
    Query query1 = session.createQuery("select cname,cage from Customer"); // 查询两个指定字段

    List<Object[]> list = query1.getResultList();
    for (Object[] ol : list) {
    for (Object o : ol) {
    System.out.println(o);
    }
    }
    transaction.commit();
    }

    /**
    * 条件查询
    */
    @Test
    public void test2() {
    Session session = HibernateUtils.openSession();
    Transaction ts = session.beginTransaction();
    Query query = session.createQuery("from Customer where cname = ?");
    query.setParameter(0, "马云"); // 从0开始(0代表第一个替换位置)

    // Query query = session.createQuery("from Customer where cname like ?");
    // query.setString(0,"%马%");

    // 在HQL中将参数设置别名,然后再给参数赋值
    // Query query = session.createQuery("from Customer where cname like :likename");
    // query.setString("likename", "%马%");
    List<Customer> list = query.list();
    for (Customer c : list) {
    System.out.println(c);
    }
    ts.commit();
    }

    /**
    * 分页查询
    */

    @Test
    public void test3() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    Query query = session.createQuery("select cid,cname from Customer ");
    query.setFirstResult(5);// 从索引为5的位置开始查
    // 假如数据库中有1000条记录,你以此想把这1000条记录查出来,设置了setFetchSize(100)
    // 数据库每次回返回100条记录,当你需要下面的100条记录的时候,数据库才会加载下面的100条记录
    // query.setFetchSize(2);
    query.setMaxResults(2);// 每次查询返回的条数
    List<Object[]> list = query.getResultList();

    for (Object[] ol : list) {
    for (Object o : ol) {
    System.out.println(o);
    }
    }

    transaction.commit();
    }

    /**
    * 排序查询
    */
    @Test
    public void test4() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    Query query = session.createQuery("from Customer order by cid desc ");

    List<Customer> list = query.list();
    for (Customer c : list) {
    System.out.println(c);
    }

    transaction.commit();
    }

    /**
    * 统计查询
    */

    @Test
    public void test5() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    // Query query = session.createQuery("select count (*) from Customer ");
    Query query = session.createQuery("select avg (cage) from Customer ");
    // getSingleResult()只能接收一个结果,当结果超过1一个时就会报错
    Object result = query.getSingleResult();
    Object o = query.uniqueResult();// 效果和getSingleResult一样
    System.out.println(result);

    transaction.commit();
    }

    /**
    * 投影查询
    */

    @Test
    public void test6() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    // 给HQL传参的时候,创建一个新的对象,指定要查询的字段的名称,执行查询以后,默认返回一个封装好了的实体
    Query query = session.createQuery("select new Customer (cname,cage) from Customer where cid = ?");
    query.setParameter(0, 1L);
    Object result = query.getSingleResult();
    System.out.println(result);
    transaction.commit();
    }
    }

  8. hibernate中的Criteria(标准、准则)对象

    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    /**
    * @CreateAuthor: KingIsHappy
    * @CreateDate: 2018/4/10
    * @Description: 使用Session创建的Criteria进行查询(QBC查询)
    * Criteria是一个完全面向对象,可扩展的条件查询API,他完全不用考虑数据库底层是如何实现,以及SQL如何编写
    * <p>
    * 基本查询
    * 条件查询
    * 分页查询
    * 排序查询
    * 统计查询
    * 离线查询(不依赖Session产生一个DetachedCriteria对象(new得到),然后设置查询参数及条件)
    */
    public class Demo3 {
    // * 基本查询(查询所有)
    @Test
    public void test1() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    // 查询所有
    Criteria criteria = session.createCriteria(Customer.class);
    List<Customer> list = criteria.list();
    for (Customer c : list) {
    System.out.println(c);
    }

    transaction.commit();
    session.close();

    }

    /**
    * 基本查询(session的createCriteria()方法已经过时的解决办法),官方建议使用Query,这相当于一个折中的方案,CriteriaQuery可以向Criteria一样
    * 不用关心SQL怎么写,它可以像Criteria一样进行设置查询条件
    */
    @Test
    public void test11() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    // 查询所有
    CriteriaQuery<Customer> cquery = session.getCriteriaBuilder().createQuery(Customer.class);
    cquery.from(Customer.class);
    cquery.where();
    // cquery.where();
    Query<Customer> query = session.createQuery(cquery);
    List<Customer> list = query.list();
    for (Customer c : list) {
    System.out.println(c);
    }

    transaction.commit();
    session.close();

    }

    // * 条件查询
    @Test
    public void test2() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    Criteria criteria = session.createCriteria(Customer.class);
    criteria.add(Restrictions.eq("cname", "马云"));
    List<Customer> list = criteria.list();
    for (Customer c : list) {
    System.out.println(c);
    }
    transaction.commit();
    session.close();
    }

    // * 分页查询
    @Test
    public void test3() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    Criteria criteria = session.createCriteria(Customer.class);
    criteria.setFirstResult(0);
    criteria.setMaxResults(5);
    List<Customer> list = criteria.list();
    for (Customer c : list) {
    System.out.println(c);
    }

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

    // * 排序查询
    @Test
    public void test4() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    Criteria criteria = session.createCriteria(Customer.class);
    criteria.addOrder(Order.desc("cid")); // 降序查询
    List<Customer> list = criteria.list();
    for (Customer c : list) {
    System.out.println(c);
    }
    transaction.commit();
    session.close();
    }

    // * 统计查询(投影查询)
    @Test
    public void test5() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    Criteria criteria = session.createCriteria(Customer.class);
    // 使用投影查询指定条目的个数
    criteria.setProjection(Projections.count("cname"));
    Object o = criteria.uniqueResult();
    System.out.println(o);
    transaction.commit();
    session.close();
    }

    /**
    * 使用投影查询,查询指定的列
    */
    @Test
    public void test55() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();
    Criteria criteria = session.createCriteria(Customer.class);
    criteria.setProjection(Projections.property("cname"));

    List list = criteria.list();
    for (Object o : list) {
    System.out.println(o);
    }

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

    // * 离线查询

    /**
    * 思路:在表现层封装一个DetachedCriteria,将要封装的查询数据到其中
    * 传递给服务层,服务层再传递给DAO层,DAO层将DetachedCriteria激活,编程Criteria对象,然后执行查询
    */
    @Test
    public void test6() {
    List list = testServlet();
    for (Object o : list) {
    System.out.println(o);
    }
    }

    // 模拟Servlet
    public List testServlet() {
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
    detachedCriteria.add(Restrictions.eq("cname", "马云"));
    List list = null;
    try {
    list = testService(detachedCriteria);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return list;
    }

    // 模拟Service
    // 在服务中开启事务,事务的处理在业务层
    public List testService(DetachedCriteria detachedCriteria) throws Exception {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = null;
    try {
    transaction = session.beginTransaction();
    List list = testDao(detachedCriteria);
    transaction.commit();
    return list;
    } catch (HibernateException e) {
    transaction.rollback();
    throw new Exception(e);
    }
    }

    // 模拟DAO
    private List testDao(DetachedCriteria detachedCriteria) {
    Session session = HibernateUtils.getCurrentSession();
    Criteria executableCriteria = detachedCriteria.getExecutableCriteria(session);
    return executableCriteria.list();
    }
    }