Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate 可以应用在任何使用 JDBC 的场合,既可以在 Java 的客户端程序使用,也可以在 Servlet/JSP 的 web 应用中使用,最具革命意义的是,Hibernate 可以在应用 EJB 的 J2EE 架构中取代 CMP,完成数据持久化的重任。
本文主要介绍了 Hibernate 三种状态和 Session 常用的方法,具有很好的参考价值,下面跟着小编一起来看下吧
我们知道 hibernate 的核心就是对数据库的操作,里面的核心接口就是 org.hibernate.Session 接口。要想对数据库操作我们就要理清楚对象在整个操作中的所属的状态(Transient,Persistent,Detached)。就像马士兵老师在视频中所说的,我们并不必死抠这些字眼,我们通过自己编写测试类就可以他们之间不同的区别。
其实三种状态各自的不必总结那么多,只是一个重要的地方就是 Transient 状态里面的对象是没有 id 的。
session 中常用的方法是 save(),update(),saveOrUpdate(),get(),load(),delete(),clear(),flush() 这些
其中大学期间我其实对 get 和 load 方法都不是太熟悉,死记硬背才在考试中答题,现在想起完全没有这个必要。我们可以根据配置好的 hibernate 环境来进行 junit 测试。
首先我们进行 get() 方法进行测试。
这里我们首先建立一个实体类,StudentEntity.Java 和数据库中 student 所对应
- package com.cwnu.entities;
- import javax.persistence.*;
- import java.io.Serializable;
- /**
- * Created by yangy on 2015/12/19.
- */
- @Table(name = "student")
- @Entity
- public class StudentEntity implements Serializable{
- private int id;
- private String name;
- @Id
- @Column(name = "id")
- @GeneratedValue(strategy = GenerationType.AUTO)
- private int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- @Column(name = "name")
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
junit 类都是 idea 编译环境给我们配置好了,这里我们要注意,要使用 getCurrentSession() 来操作的话,我们首先要在 Junit 类中加上 @Transaction 注解,下面是相关的测试方法:
- @Test
- public void testGetOrLoad() {
- Session session = sessionFactory.getCurrentSession();
- StudentEntity student = (StudentEntity)session.get(StudentEntity.class, 1);
- //StudentEntity student_load = (StudentEntity)session.load(StudentEntity.class,1); String name = student.getName();
- }
先测试 get 方法,我们发现一旦我们只是拿 student 这个实体操作,get 方法是会输出相关的 sql 查询语句的,而我们注释掉 get 方法,换 load 方法的话,load 方法执行拿 student 这个实体的数据是没有输出相应的 sql 语句的。但是我们在对 student 类进行操作的时候,这时才输出相关的语句.
所以我们看出 get() 和 load() 之间的差别:
get() 每次执行都会执行 sql 语句,不会延迟。load() 方法只是会在我们对拿到的实体进行操作的时候才去执行查询,拿到相应的实体信息。load 方法返回的是一个代理对象(马士兵老师视频)。无论是 get 还是 load 首先都会查一级缓存(session)中有没有相应的对应值,如果没有,再去数据库进行查找。
clear() 方法是对 session 里面的缓存进行了清理,测试这个方法我们可以根据下面的 Junit 进行测试:
- @Test
- public void testClear() {
- Session session = sessionFactory.getCurrentSession();
- session.get(StudentEntity.class,1);
- session.clear();
- session.get(StudentEntity.class,1);
- }
如果我们把 session.clear() 注释掉的话,我们就可以看到只执行了一条 sql 语句
flush() 方法是是对数据库同步的一条语句,执行完这个后立即刷新到数据库。粗浅的来看哈,其实里面还是有很多东西,比如 FlushMode 这个类,我们默认设置的是 FlushMode.AUTO,这个一般不修改,只是为了以后的性能调优。其实我们在执行事务的时候,事务完成之后它会帮我们执行 flush() 方法。只是我们在进行大规模插入的时候,我们经常可以看到下面的操作:
这样做的目的就是避免大量插入,造成 session 里面内存溢出,所以我们定时清理一下就可以避免这个问题。
- Session session = sessionFactory.openSession();
- Transaction tx = session.beginTransaction();
- for ( int i=0; i<100000; i++ ) {
- Customer customer = new Customer(.....);
- session.save(customer);
- if ( i % 20 == 0 ) {
- //20, same as the JDBC batch size
- //flush a batch of inserts and release memory:
- session.flush();
- session.clear();
- }}
- tx.commit();session.close();
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持 PHPERZ!
来源: http://www.phperz.com/article/18/0104/357983.html