hibernate基础

来源:互联网 发布:士族知乎 编辑:程序博客网 时间:2024/06/05 08:34

Hibernate 对象的关系映射框架 ,对象编程思维操作数据库。

Hibernate驱动包  antlr-2.7.7  dom4j-1.6.1  hibernate-commons-annotations-4.0.4.Final     hibernate-core-4.3.5.Final   hibernate-jpa-2.1-api-1.0.0.Final     jandex-1.1.0.Final

javassist-3.18.1-GA     jboss-logging-3.1.3.GA   jboss-logging-annotations-1.2.0.Beta1     jboss-transaction-api_1.2_spec-1.0.0.Final

mysql-connector-java-3.1.12-bin


hibernate.cfg.xml  默认名字

 <?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">


<hibernate-configuration>


    <session-factory>


        <!--数据库连接设置 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  驱动
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property> 地址链接的数据库
        <property name="connection.username">root</property> 
        <property name="connection.password">123456</property>


       
        <!-- 方言 -->
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> 方言 底层解析根据mysql 写oracle的方言

        <!-- 控制台显示SQL -->
        <property name="show_sql">true</property>


        <!-- 自动更新表结构 -->
        <property name="hbm2ddl.auto">update</property> 配置了好几个表数据库没有更新表结构
        
  <mapping resource="com/java1234/model/Student.hbm.xml"/> 映射文件配置好后添加
               <mapping class="com.java1234.model.Teacher"/> 注解的

    </session-factory>


</hibernate-configuration>


package com.java1234.model;


public class Student {


private long id;
private String name;

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}


}

Student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">package是类 在这个包下


<class name="Student" table="t_student"> name类名 映射到数据库的表
<id name="id" column="stuId"> 表中字段的映射 类里面的字段 column table表的字段
<generator class="native"></generator> 主键生产策略 根据本地来自增长
</id>

<property name="name"></property> 普通字段
</class>


</hibernate-mapping>



package com.java1234.service;


import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;


import com.java1234.model.Student;


public class StudentTest {


public static void main(String[] args) {

Configuration configuration=new Configuration().configure(); // 实例化配置文件
ServiceRegistry serviceRegistry=new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); // 实例化服务登记
   SessionFactory sessionFactory=configuration.buildSessionFactory(serviceRegistry); // 获取Session工厂
   Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Student s=new Student();
   s.setName("张三");
   session.save(s); Hibernate自动设置的sql
   
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
   sessionFactory.close(); // 关闭session工厂
}
}

不用重复写测试 封装

package com.java1234.util;


import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;


public class HibernateUtil {

private static final SessionFactory sessionFactory=buildSessionFactory(); 静态字段


private static SessionFactory buildSessionFactory(){
Configuration configuration=new Configuration().configure(); // 实例化配置文件
ServiceRegistry serviceRegistry=new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); // 实例化服务登记
   return configuration.buildSessionFactory(serviceRegistry); // 返回Session工厂
}

public static SessionFactory getSessionFactory(){ 拿到的永远是单例
return sessionFactory;
}
}


CIUD操作

package com.java1234.service;


import java.util.List;


import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;


import com.java1234.model.Student;
import com.java1234.util.HibernateUtil;


public class StudentTest {

private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();

private void add(){
   Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Student s=new Student();
   s.setName("张三");
   session.save(s);
   
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}

private void delete(){
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Student student=(Student)session.get(Student.class, Long.valueOf(1)); session get方法主键 类和  主键Long型的 返回一个对象强制类型转换
   session.delete(student); 直接删除对象
   
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}

private void update(){
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Student student=(Student)session.get(Student.class, Long.valueOf(2));
   student.setName("张三2");
   session.save(student);
   
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}

private void getAllStudent(){ 获取所有的
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   String hql="from Student"; hql 面向对象的sql 类Student
   Query query=session.createQuery(hql); 返回query对象
   List<Student> studentList=query.list(); 通过query获取对象
   for(Student student:studentList){
    System.out.println(student); 要重写toString方法
   }
   
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}


public static void main(String[] args) {
StudentTest studentTest=new StudentTest();
// studentTest.add();
// studentTest.delete();
// studentTest.update();
studentTest.getAllStudent();
}
}


注解版CIUD 不用hbm.xml 配置文件

package com.java1234.model;


import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;


import org.hibernate.annotations.GenericGenerator;


@Entity 代表是一个映射实体
@Table(name="t_teacher") 映射到某一个表
public class Teacher {


private long id;
private String name;

@Id
@GeneratedValue(generator="_native")
@GenericGenerator(name="_native",strategy="native") 之后要在Hibernate.cfg.xml中配置一下
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher [id=" + id + ", name=" + name + "]";
}


}


单元测试运行方法有结果 junit4.4

package com.java1234.service;


import java.util.List;


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


import com.java1234.model.Teacher;
import com.java1234.util.HibernateUtil;


public class TeacherTest2 {

private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();

@Test
public void testAdd() {
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Teacher s=new Teacher();
   s.setName("张三");
   session.save(s);
   
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}


@Test
public void testDelete() {
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Teacher Teacher=(Teacher)session.get(Teacher.class, Long.valueOf(2)); 空的实体
   session.delete(Teacher);
   
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}


@Test
public void testUpdate() {
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Teacher Teacher=(Teacher)session.get(Teacher.class, Long.valueOf(3));
   Teacher.setName("张三2");
   session.save(Teacher);
   
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}


@Test
public void testGetAllTeacher() {
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   String hql="from Teacher";
   Query query=session.createQuery(hql);
   List<Teacher> TeacherList=query.list();
   for(Teacher Teacher:TeacherList){
    System.out.println(Teacher);
   }
   
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}


}


映射对象标识符OID 类似主键来区分事物

package com.java1234.service;


import org.hibernate.Session;
import org.hibernate.SessionFactory;


import com.java1234.model.Student;
import com.java1234.util.HibernateUtil;


public class StudentTest {

public static void main(String[] args) {
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Student s1=(Student)session.get(Student.class, Long.valueOf(1)); 获取Student
   Student s2=(Student)session.get(Student.class, Long.valueOf(2)); 主键为2的Student
   Student s3=(Student)session.get(Student.class, Long.valueOf(1)); 没有去数据库查从session缓存中查有主键为1的Student
   System.out.println(s1==s2); false 指向对象不一样
   System.out.println(s1==s3); true 同一个对象
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}
}

代理主键 准编号1,2,3不具有任何业务性  取的是学号唯一的有业务性

数据库建完业务不经常变动用业务主键不需要额外阻断,业务经常变动用代理主键 

主键的分类 业务主键 VS 代理主键 代理主键是不具有业务性的;

 

1,increment Hibernate 自动以递增的方式生成标识符,适用代理主键;

 

2,identity 由底层数据库生成标识符;适用代理主键;

 

3,sequcence Hibernate 根据底层数据库的序列来生成标识符;适用代理主键;

 

4,hilo Hibernate 根据 high/low 算法来生成标识符。适用代理主键

 

5,native 根据底层数据库对自动生成标识符的支持能力,来选择 identity,sequence  hilo;适用代理主键;


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Student" table="t_student">
<id name="id" column="stuId">
<generator class="native"></generator> increment 首先到数据库寻找最大自增 identity 
</id>

<property name="name"></property>
</class>
</hibernate-mapping>



一对多单向 学生端n管理班级1  班级不关联学生

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Class" table="t_class">
<id name="id" column="classId">
<generator class="native"></generator>
</id>

<property name="name" column="className"></property>
</class>


</hibernate-mapping>


package com.java1234.model;


public class Student {


private long id;
private String name;
private Class c;  Class是1 学生是多 单向管理在多的一方   学生是属于某一个班级

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}


public Class getC() {
return c;
}
public void setC(Class c) {
this.c = c;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}


}


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Student" table="t_student">
<id name="id" column="stuId">
<generator class="native"></generator>
</id>

<property name="name" column="stuName"></property>

<many-to-one name="c" column="classId" class="com.java1234.model.Class" cascade="save-update"></many-to-one> 学生端多对一  name是 return的c column是数据库学生表多一个外键关联学生表的主键  瞬态不级联保存   


</class>


</hibernate-mapping>


多加一个映射文件

<mapping resource="com/java1234/model/Class.hbm.xml"/>

package com.java1234.service;


import org.hibernate.Session;
import org.hibernate.SessionFactory;


import com.java1234.model.Class;
import com.java1234.model.Student;
import com.java1234.util.HibernateUtil;


public class StudentTest {

public static void main(String[] args) {
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Class c=new Class();
   c.setName("08计本");
   session.save(c);
   
   Student s1=new Student();
   s1.setName("张三");
   s1.setC(c); 设置的班级08级
   
   Student s2=new Student();
   s2.setName("李四");
   s2.setC(c);
   
   session.save(s1);
   session.save(s2);
  
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
}
}


不用写 session

Junit test case setup 安装 tearDown 卸载 beforeClass 类初始化前调用  

package com.java1234.service;


import static org.junit.Assert.*;


import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;


public class StudentTest2 {


@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("类初始化前调用...");
}


@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("类初始化后调用...");
}


@Before
public void setUp() throws Exception {
System.out.println("在测试方法前调用...");
}


@After
public void tearDown() throws Exception {
System.out.println("在测试方法后调用...");
}


@Test
public void test() {
System.out.println("测试方法");
}


}


-----------------------------------------------------------------

package com.java1234.service;


import static org.junit.Assert.*;


import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;


import com.java1234.model.Class;
import com.java1234.model.Student;
import com.java1234.util.HibernateUtil;


public class StudentTest3 {


private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
private Session session; 引用每一个方法都要用

@Before
public void setUp() throws Exception {
session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
}


@After
public void tearDown() throws Exception {
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
}


@Test
public void testSaveClassAndStudent() {
Class c=new Class();
   c.setName("08计本");
   session.save(c);
   
   Student s1=new Student();
   s1.setName("张三");
   s1.setC(c);
   
   Student s2=new Student();
   s2.setName("李四");
   s2.setC(c);
   
   session.save(s1);
   session.save(s2);
}

@Test
public void testSaveClassAndStudentWithCascade() {
Class c=new Class();
   c.setName("08计本");
   
   Student s1=new Student();
   s1.setName("张三");
   s1.setC(c);
   
   Student s2=new Student();
   s2.setName("李四");
   s2.setC(c);
   
   session.save(s1);
   session.save(s2);
}
}


双向 班级一的一端获取学生 

package com.java1234.model;


import java.util.HashSet;
import java.util.Set;


public class Class {


private long id;
private String name;
private Set<Student> students=new HashSet<Student>(); 通过班级获取学生 学生是一个集合

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Class" table="t_class">
<id name="id" column="classId">
<generator class="native"></generator>
</id>

<property name="name" column="className"></property>

<set name="students" cascade="delete" inverse="true"> set配置 name是定义的对象  在一的一端inverse 相当于在多的一端学生端维护操作
<key column="classId"></key> columb是student配置文件的外键column 
<one-to-many class="com.java1234.model.Student"/>  对应的是学生的
</set>
</class>


</hibernate-mapping>


@Test
public void getStudentsByClass(){
Class c=(Class)session.get(Class.class, Long.valueOf(2));
Set<Student> students=c.getStudents();
Iterator it=students.iterator(); 遍历器遍历
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testAdd(){
Class c=new Class();
   c.setName("09计本");
   
   Student s1=new Student();
   s1.setName("王五");
   
   session.save(c); 保存2个数据
   session.save(s1);
}

@Test 要加注解
public void testInverse(){ 外键没有关系 要有关系
Class c=(Class)session.get(Class.class, Long.valueOf(1)); session获取的是持久化对象了
Student s=(Student)session.get(Student.class, Long.valueOf(1));

s.setC(c); 2个持久化对象学生设置班级
c.getStudents().add(s); 班级设置学生 有关系了
}


@Test
public void testDeleteClassCascade(){  cascade=”delete” 否则报错   先删除关联的学生再删除class
Class c=(Class)session.get(Class.class, Long.valueOf(1));
session.delete(c);
}


配置在一起:

把自己当做多的一端 多的一端要配老子 在name=“parentNode”是private Node parentNode  Class是自生 

set把自己当做老子的一端大的一端 要配置集合 name=“childNodes” key column对应上面的 many-to-one 的name主键

private long id;
private String name;

private Node parentNode;

private Set<Node> childNodes=new HashSet<Node>();


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Node" table="t_node">
<id name="id" column="nodeId">
<generator class="native"></generator>
</id>

<property name="name" column="nodeName"></property>

<many-to-one name="parentNode" column="parentId" class="com.java1234.model.Node" cascade="save-update"></many-to-one>

<set name="childNodes"  inverse="true">
<key column="parentId"></key>
<one-to-many class="com.java1234.model.Node"/>
</set>
</class>


</hibernate-mapping>


@Test
public void testSaveMenu() {
Node node=new Node();
node.setName("根节点");

Node subNode1=new Node();
subNode1.setName("子节点1");

Node subNode2=new Node();
subNode2.setName("子节点2");
   
subNode1.setParentNode(node); 设置父节点
subNode2.setParentNode(node);

session.save(subNode1);
session.save(subNode2);
}


Hibernate 中四种对象状态

 

临时状态(transient):刚用 new 语句创建,还没有被持久化,并且不处于 Sesssion 的缓存中。处于临时状态的 Java 对象被称为临时对象。

 

持久化状态(persistent):已经被持久化,并且加入到 Session 的缓存中。处于持久化状态的 Java 对象被称为持久化对象。

 

删除状态(removed):不再处于 Session 的缓存中,并且 Session 已经计划将其从数据库中删除。处于删除状态的 Java 对象被称为删除对象。

 

游离状态(detached):已经被持久化,但不再处于 Session 的缓存中。处于游离状态的 Java 对象被称为游离对象。


常用的session方法

package com.java1234.service;


import java.util.Iterator;
import java.util.Set;


import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


import com.java1234.model.Class;
import com.java1234.model.Student;
import com.java1234.util.HibernateUtil;


public class StudentTest {


private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
private Session session;

@Before
public void setUp() throws Exception {
session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
}


@After
public void tearDown() throws Exception {
session.getTransaction().commit(); // 提交事务 刷新session缓存执行sql
session.close(); // 关闭session 变为游离对象
}


@Test
public void testSaveClassAndStudent() {
Class c=new Class();
   c.setName("08计本");
  
   Student s1=new Student();
   s1.setName("张三");
   s1.setC(c);
   
   Student s2=new Student();
   s2.setName("李四");  都是临时对象
   s2.setC(c);
  
   session.save(s1);  变为持久化对象
   session.save(s2);
   
}

@Test
public void testLoadClass(){ 数据库不存在OID对应字段load会返回异常 get是null 默认采用延迟加载策略  获取对象是为了删除load直接用引用 
// Class c=(Class)session.load(Class.class, Long.valueOf(2)); 代理类用的时候才会访问加载
Class c=(Class)session.load(Class.class, Long.valueOf(1));
System.out.println(c.getStudents());
}

@Test
public void testGetClass(){ 采用立即检索策略  获取数据是为了访问属性用get
// Class c=(Class)session.get(Class.class, Long.valueOf(2));
Class c=(Class)session.get(Class.class, Long.valueOf(1));
System.out.println(c.getStudents());
}

@Test
public void testUpdateClass(){
Session session1=sessionFactory.openSession();
session1.beginTransaction();
Class c=(Class)session1.get(Class.class, Long.valueOf(1));
session1.getTransaction().commit(); // 提交事务
session1.close();

Session session2=sessionFactory.openSession();
session2.beginTransaction();
c.setName("08计算机本科2");
session2.update(c);
session2.getTransaction().commit(); // 提交事务
session2.close();
}

@Test
public void testSaveOrUpdateClass(){
Session session1=sessionFactory.openSession();
session1.beginTransaction();
Class c=(Class)session1.get(Class.class, Long.valueOf(1));
session1.getTransaction().commit(); // 提交事务
session1.close();

Session session2=sessionFactory.openSession();
session2.beginTransaction();
c.setName("08计算机本科3");

Class c2=new Class();
c2.setName("09计算机本科3");
session2.saveOrUpdate(c);
session2.saveOrUpdate(c2);
session2.getTransaction().commit(); // 提交事务
session2.close();
}

@Test
public void testMergeClass(){
Session session1=sessionFactory.openSession();
session1.beginTransaction();
Class c=(Class)session1.get(Class.class, Long.valueOf(1));
session1.getTransaction().commit(); // 提交事务
session1.close();

Session session2=sessionFactory.openSession();
session2.beginTransaction();

Class c2=(Class)session2.get(Class.class, Long.valueOf(1));
c.setName("08计算机本科4");

session2.merge(c);


session2.getTransaction().commit(); // 提交事务
session2.close();
}

@Test
public void testDeleteStudent(){
Student student=(Student)session.load(Student.class, Long.valueOf(1));
session.delete(student);
}
}


hibernate映射类型

package com.java1234.model;


import java.sql.Blob;
import java.util.Date;


public class Book {


private int id;
private String bookName; // 图书名称
private float price; // 图书价格
private boolean specialPrice; // 是否是特价
private Date publishDate; // 发布日期
private String author; // 作者
private String introduction; // 简介
private Blob bookPic; // 图书图片 以前驱动不支持 mysql

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public boolean isSpecialPrice() {
return specialPrice;
}
public void setSpecialPrice(boolean specialPrice) {
this.specialPrice = specialPrice;
}
public Date getPublishDate() {
return publishDate;
}
public void setPublishDate(Date publishDate) {
this.publishDate = publishDate;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getIntroduction() {
return introduction;
}
public void setIntroduction(String introduction) {
this.introduction = introduction;
}
public Blob getBookPic() {
return bookPic;
}
public void setBookPic(Blob bookPic) {
this.bookPic = bookPic;
}


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Book" table="t_book">
<id name="id" column="bookId">
<generator class="native"></generator>
</id>

<property name="bookName" column="bookName" length="40"></property> 字符串类型
<property name="price" column="price" type="float"></property>  float类型 对应数据库也是FLOAT
<property name="specialPrice" column="specialPrice" type="boolean"></property> 
<property name="publishDate" column="publishDate" type="date"></property>
<property name="author" column="author" length="20"></property>
<property name="introduction" column="introduction" type="text"></property>
<property name="bookPic" column="bookPic" type="blob"></property> 大的二进制文件
</class>


</hibernate-mapping>

}


package com.java1234.service;


import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.text.SimpleDateFormat;


import org.hibernate.LobHelper;
import org.hibernate.Session;
import org.hibernate.SessionFactory;


import com.java1234.model.Book;
import com.java1234.util.HibernateUtil;


public class BookTest {

public static void main(String[] args) throws Exception{
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
Session session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
   
   Book book=new Book();
   book.setBookName("java编程思想");
   book.setPrice(100);
   book.setSpecialPrice(true);
   book.setPublishDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-1-1"));
   book.setAuthor("埃克尔");
   book.setIntroduction("简介...");
   
   LobHelper lobHelper=session.getLobHelper(); hibernate提供的接口
   InputStream in=new FileInputStream("c://java编程思想.jpg");
   Blob bookPic=lobHelper.createBlob(in, in.available()); 长度可用的 返回对象
   book.setBookPic(bookPic);
  
   session.save(book); 保存
   session.getTransaction().commit(); // 提交事务
   session.close(); // 关闭session
 
}
}


集合映射

不包含生命周期和OID

1,Set 无序 元素不可重复

 

2,List 有序 元素可重复

 

3,Bag 无序 元素可重复

 

4,Map 键值对


private Set<String> images;

<set name="images" table="t_image">
<key column="studentId"></key> 外键 image表的studentid关联 student表的主键
<element column="imageName" type="string"></element>
</set>


@Test
public void testSetSave(){
Set<String> imageSet=new HashSet<String>();
imageSet.add("image1.png");
imageSet.add("image2.png");
imageSet.add("image3.png");
imageSet.add("image3.png");

Student s1=new Student();
s1.setImages(imageSet);
session.save(s1);
}


@Test
public void testSetFetch(){ 获取值
Student student=(Student)session.get(Student.class, Long.valueOf(1));
Iterator it=student.getImages().iterator(); 集合遍历器方便
while(it.hasNext()){
System.out.println(it.next());
}
}

private List<String> images; list数据库多一个索引

<list name="images" table="t_image2">
<key column="studentId"></key>
<list-index column="imageIndex"></list-index> 索引列

<element column="imageName" type="string"></element>
</list>



@Test
public void testListSave(){
List<String> imageList=new ArrayList<String>();
imageList.add("image1.png");
imageList.add("image2.png");
imageList.add("image3.png");
imageList.add("image3.png");

Student2 s2=new Student2();
s2.setImages(imageList);
session.save(s2);
}

@Test
public void testListFetch(){
Student2 student2=(Student2)session.get(Student2.class, Long.valueOf(2));
Iterator it=student2.getImages().iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}


private List<String> images;

<idbag name="images" table="t_image3">
<collection-id type="long" column="imageId">
<generator class="increment"></generator>
</collection-id>
<key column="studentId"></key> 主键
<element column="imageName" type="string"></element> 元素
</idbag>


@Test
public void testBagSave(){
List<String> imageList=new ArrayList<String>();
imageList.add("image1.png");
imageList.add("image2.png");
imageList.add("image3.png");
imageList.add("image3.png");

Student3 s3=new Student3();
s3.setImages(imageList);
session.save(s3);
}

@Test
public void testBagFetch(){
Student3 student3=(Student3)session.get(Student3.class, Long.valueOf(3));
Iterator it=student3.getImages().iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}


private Map<String,String> images;

<map name="images" table="t_image4">
<key column="studentId"></key>
<map-key column="imageKey" type="string"></map-key>
<element column="imageName" type="string"></element>
</map>

@Test
public void testMapSave(){
Map<String,String> imageMap=new HashMap<String,String>();
imageMap.put("i1", "image1.png");
imageMap.put("i2", "image2.png");
imageMap.put("i3", "image3.png");
imageMap.put("i4", "image4.png");

Student4 s4=new Student4();
s4.setImages(imageMap);
session.save(s4);
}

@Test
public void testMapFetch(){
Student4 student4=(Student4)session.get(Student4.class, Long.valueOf(4));
Map<String,String> imageMap=student4.getImages();
Set keys=imageMap.keySet();
Iterator it=keys.iterator();
while(it.hasNext()){
String key=(String)it.next();
System.out.println(key+":"+imageMap.get(key));
}
}


hibernate映射关系

一对一

一个用户对一个地址

public class User {


private int id;
private String name;
private Address address;


public class Address {


private int id;
private String address;
private String zipcode;
private User user;


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="User" table="t_user">
<id name="id" column="userId">
<generator class="native"></generator>
</id>

<property name="name" column="userName"></property>

<one-to-one name="address" class="com.java1234.model.Address" cascade="all"></one-to-one> 级联保存更新删除都有 用户删除地址也删除
</class>


</hibernate-mapping>


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Address" table="t_address">
<id name="id" column="addressId"> 和user的主键是一样的name=id  既做主键又做外键 一对一
<generator class="foreign"> 
<param name="property">user</param> user对象
</generator>
</id>

<property name="address" column="address"></property>
<property name="zipcode" column="zipcode"></property>

<one-to-one name="user" class="com.java1234.model.User" constrained="true"></one-to-one>  共享主键true约束
</class>


</hibernate-mapping>


多对赌映射 

单向 学生 课程  通过学生获取所有课程 

public class Student {


private int id;
private String name;
private Set<Course> courses=new HashSet<Course>();


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Student" table="t_student">
<id name="id" column="studentId">
<generator class="native"></generator>
</id>

<property name="name" column="studentName"></property> 主键

<set name="courses" table="student_course" cascade="save-update"> 是一个集合 借助第三张表
<key column="student_id"></key>student_course的外键关联学生表的主键
<many-to-many class="com.java1234.model.Course" column="course_id"></many-to-many> 映射的另外一张表 student_course的外键关联course表的主键
</set>
</class>


</hibernate-mapping>


多向

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Student2" table="t_student2">
<id name="id" column="studentId">
<generator class="native"></generator>
</id>

<property name="name" column="studentName"></property>

<set name="courses" table="student_course2" cascade="save-update">
<key column="student_id"></key>
<many-to-many class="com.java1234.model.Course2" column="course_id"></many-to-many>
</set>
</class>


</hibernate-mapping>




public class Course2 {


private int id;
private String name;
private Set<Student2> students=new HashSet<Student2>();  也要加上集合  单向不用加


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Course2" table="t_course2">
<id name="id" column="courseId">
<generator class="native"></generator>
</id>

<property name="name" column="courseName"></property>

<set name="students" table="student_course2" inverse="true" >  双向的 inverse由学生端来维护主外键关系
<key column="course_id"></key>
<many-to-many class="com.java1234.model.Student2" column="student_id"></many-to-many>
</set>

</class>


</hibernate-mapping>


hibernate检索策略

检索策略属性 Lazy

 

Lazy:true (默认) 延迟检索 set 一对多 Lazy:false 立即检索;set 一对多

 Lazy:extra 增强延迟检索; 只求数量

 set 一对多Lazy:proxy(默认) 延迟检索;many-to-one 多对一

 

Lazy:no-proxy 无代理延迟检索;many-to-one 多对一 (需要编译时字节码增强)

  <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Class" table="t_class">
<id name="id" column="classId">
<generator class="native"></generator>
</id>

<property name="name" column="className"></property>

<set name="students" cascade="delete" inverse="true" lazy="false" batch-size="3" fetch="join" > lazy true只会查询班级关联的student不会查询等到用的时候查询

 batch-size="3" 分别去查三个班级 批量延迟检索 
<key column="classId"></key>
<one-to-many class="com.java1234.model.Student"/>
</set>
</class>


</hibernate-mapping>

 


第二节:检索策略属性 batch-size

 

1,批量延迟检索;

 

2,批量立即检索;


  @Test
public void testBatch1(){
List<Class> classList=session.createQuery("from Class").list();
Iterator it=classList.iterator();
Class c1=(Class)it.next();
Class c2=(Class)it.next();
Class c3=(Class)it.next();
c1.getStudents().iterator();
c2.getStudents().iterator();
c3.getStudents().iterator();
}

@Test
public void testBatch2(){
List<Class> classList=session.createQuery("from Class").list();

}

 lazy="false" batch-size="3"  直接查询出来

检索策略属性 Fetch

 

1,Fetch:select(默认) 查询方式;

 

2,Fetch:subselect 子查询方式;

 

3,Fetch:join 迫切左外连接查询方式;




<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Student" table="t_student">
<id name="id" column="stuId">
<generator class="native"></generator>
</id>

<property name="name" column="stuName"></property>

<many-to-one name="c" column="classId" class="com.java1234.model.Class" cascade="save-update" lazy="no-proxy"></many-to-one> lazy 代理类不包含数据用到的时候通过代理类去数据库查询
</class>


</hibernate-mapping>


@Test
public void testFetch1(){
List<Class> classList=session.createQuery("from Class").list();
Iterator it=classList.iterator();
Class c1=(Class)it.next();
Class c2=(Class)it.next();
Class c3=(Class)it.next();
c1.getStudents().iterator();
c2.getStudents().iterator();
c3.getStudents().iterator();
}

@Test
public void testFetch2(){
Class c=(Class)session.get(Class.class, Long.valueOf(1));
}
}


HQL

package com.java1234.service;




import java.util.Iterator;
import java.util.List;


import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


import com.java1234.model.Student;
import com.java1234.util.HibernateUtil;


public class StudentTest {


private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
private Session session;

@Before
public void setUp() throws Exception {
session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
}


@After
public void tearDown() throws Exception {
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
}


@Test
public void testSQLQuery() {
String sql="select * from t_student";
Query query=session.createSQLQuery(sql).addEntity(Student.class);
List studentList=query.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testSQLQuery2() {
String sql="select * from t_student where stuName like :stuName and stuAge=:stuAge";  加条件本地sql根据数据库的字段 :开头的是参数类似?
Query query=session.createSQLQuery(sql).addEntity(Student.class);
query.setString("stuName", "张%"); 参数:后面的
query.setInteger("stuAge", 10);
List studentList=query.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testHQLQuery() { 
String hql="from Student"; 绑定对象
Query query=session.createQuery(hql);
List<Student> studentList=(List<Student>)query.list(); 泛型已经能够确定是Student类型
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testHQLQuery2() {
String hql="from Student where name like :stuName and age=:stuAge"; 待条件的 属性:左边的是类中的属性
Query query=session.createQuery(hql);
query.setString("stuName", "张%");
query.setInteger("stuAge", 10);
List<Student> studentList=(List<Student>)query.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testHQLQuery3() {
String hql="from Student as s where s.name like :stuName and s.age=:stuAge"; 对象点.
Query query=session.createQuery(hql);
query.setString("stuName", "张%");
query.setInteger("stuAge", 10);
List<Student> studentList=(List<Student>)query.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testHQLQuery4() {
String hql="from Student order by age desc"; 对结果排序 按照id
Query query=session.createQuery(hql);
List<Student> studentList=(List<Student>)query.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testHQLQuery5() { 分页查询
String hql="from Student";
Query query=session.createQuery(hql);
query.setFirstResult(1); 类似于limit
query.setMaxResults(2); 最大记录条数
List<Student> studentList=(List<Student>)query.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testHQLQuery6() {
String hql="from Student";
Query query=session.createQuery(hql);
query.setFirstResult(1);
query.setMaxResults(1);
Student student=(Student)query.uniqueResult(); 确定只有一条记录 查询总记录数
System.out.println(student);
}


@Test
public void testHQLQuery7() { 链式写法
String hql="from Student as s where s.name like :stuName and s.age=:stuAge";
Query query=session.createQuery(hql);
List<Student> studentList=(List<Student>)query
.setString("stuName", "张%")
.setInteger("stuAge", 10)
.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}
}


QBC查询方式 接口来实现的查询方式

@Test
public void testQBCQuery1(){
Criteria criteria=session.createCriteria(Student.class); 要查询的类
List<Student> studentList=criteria.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testQBCQuery2(){ 待条件的
Criteria criteria=session.createCriteria(Student.class);
Criterion c1=Restrictions.like("name", "张%");
Criterion c2=Restrictions.eq("age", 10);
criteria.add(c1);
criteria.add(c2);
List<Student> studentList=criteria.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test 
public void testQBCQuery3(){ 排序
Criteria criteria=session.createCriteria(Student.class);
criteria.addOrder(Order.desc("age"));
List<Student> studentList=criteria.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testQBCQuery4(){ 分页
Criteria criteria=session.createCriteria(Student.class);
criteria.setFirstResult(2);
criteria.setMaxResults(2);
List<Student> studentList=criteria.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}

@Test
public void testQBCQuery5(){
Criteria criteria=session.createCriteria(Student.class);
criteria.setFirstResult(2);
criteria.setMaxResults(1);
Student student=(Student)criteria.uniqueResult(); 单个对象
System.out.println(student);
}


@Test
public void testQBCQuery6(){
Criteria criteria=session.createCriteria(Student.class);
List<Student> studentList=criteria
.setFirstResult(0)
.setMaxResults(2)
.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
}


配置数据库连接池

直接是jsp servlet JDBC每次请求创建链接用完关闭 访问量很大

C3P0 jar包 c3p0-0.9.2.1  hibernate-c3p0-4.3.5.Final  mchange-commons-java-0.2.3.4


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">


<hibernate-configuration>


    <session-factory>


        <!--数据库连接设置 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>


       
        <!-- 方言 -->
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- 控制台显示SQL -->
        <property name="show_sql">true</property>


        <!-- 自动更新表结构 -->
        <property name="hbm2ddl.auto">update</property>
        
        <!-- 最小连接数 --> 
  <property name="c3p0.min_size">7</property> 
  <!-- 最大连接数 -->   
  <property name="c3p0.max_size">42</property> 
  <!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 -->  
  <property name="c3p0.timeout">1800</property> 
  <!-- 最大的PreparedStatement的数量 -->   
  <property name="c3p0.max_statements">50</property> 
        
  <mapping resource="com/java1234/model/Student.hbm.xml"/>
 
 


    </session-factory>


</hibernate-configuration>



日志框架

log4j.properties


log4j.rootLogger=info,appender1,appender2


log4j.appender.appender1=org.apache.log4j.ConsoleAppender 


log4j.appender.appender2=org.apache.log4j.FileAppender 
log4j.appender.appender2.File=C:/logFile.txt
 
log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout
log4j.appender.appender2.layout=org.apache.log4j.TTCCLayout  


private Logger logger=Logger.getLogger(StudentTest.class);


@Test
public void testSQLQuery() {
String sql="select * from t_student";
Query query=session.createSQLQuery(sql).addEntity(Student.class);
List studentList=query.list();
Iterator it=studentList.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s);
}
logger.debug("这是一个debug信息");
logger.info("这是一个info信息");
logger.error("这是一个错误信息");
}


二级缓存 

1,缓存的概念:

 

缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存或者硬盘中的容器,其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能。Hibernate 在进行读取数据的时候,根据缓存机制在相应的缓存中查询,如果在缓存中找到了需要的数据(我们把这称做“缓存命 中"),则就直接把命中的数据作为结果加以利用,避免了大量发送 SQL 语句到数据库查询的性能损耗。

 

2,Hibernate 缓存的分类:

 

一、Session 缓存(又称作事务缓存):Hibernate 内置的,不能卸除。

 

缓存范围:缓存只能被当前 Session 对象访问。缓存的生命周期依赖于 Session 的生命周期,当 Session 被关闭后,缓存也就结束生命周期。

 

二、SessionFactory 缓存(又称作应用缓存):使用第三方插件,可插拔。

 

缓存范围:缓存被应用范围内的所有 session 共享,不同的 Session 可以共享。这些 session 有可能是并发访问缓存,因此必须对缓存进行更新。缓存的生命周期依赖于应用的生命周期,应用结束时,缓存也就结束了生命周期,二级缓存存在于应用程序范围。

 

3,二级缓存策略提供商:

 

提供了 HashTable 缓存,EHCache,OSCache,SwarmCache,jBoss Cathe2,这些缓存机制,其中 EHCache OSCache 是不能用于集群环境(Cluster Safe)的,而 SwarmCache,jBoss Cathe2 是可以的。HashTable 缓存主要是用来测试的,只能把对象放在内存中,EHCache,OSCache 可以把对象放在内存(memory)中,也可以


4,什么数据适合放二级缓存中:(1)经常被访问(2)改动不大(3)数量有限

 

(4)不是很重要的数据,允许出现偶尔并发的数据。比如组织机构代码,列表信息等;


private long id;
private String name;


package com.java1234.service;


import static org.junit.Assert.*;


import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;


import com.java1234.model.Class;
import com.java1234.model.Student;
import com.java1234.util.HibernateUtil;


public class StudentTest {


private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
private Session session;

/*@Before
public void setUp() throws Exception {
session=sessionFactory.openSession(); // 生成一个session
   session.beginTransaction(); // 开启事务
}


@After
public void tearDown() throws Exception {
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
}*/


@Test
public void testCache1() {  执行性一条sql 第二次有session缓存一级缓存 去缓存中找直接从内存中拿
Class c=(Class)session.get(Class.class, Long.valueOf(1)); long型的class
System.out.println(c.getName());
Class c2=(Class)session.get(Class.class, Long.valueOf(1));
System.out.println(c2.getName());
System.out.println(c==c2); true
}

@Test
public void testCache2(){ 限定在同一个事物 不同事物中是否有缓存 
Session session1=sessionFactory.openSession();
session1.beginTransaction();
Class c=(Class)session1.get(Class.class, Long.valueOf(1)); 1
System.out.println(c.getName());
session1.getTransaction().commit();
session1.close();

Session session2=sessionFactory.openSession();
session2.beginTransaction();
Class c2=(Class)session2.get(Class.class, Long.valueOf(1));2
System.out.println(c2.getName());
session2.getTransaction().commit();
session2.close();

System.out.println(c==c2); false 不同事物一级缓存不能共用 二级缓存不同事物共享数据
}



}


二级缓存jar包

ehcache-core-2.4.3    hibernate-ehcache-4.3.5.Final  slf4j-api-1.6.1

ehcache.xml

<ehcache>
   
    <!-- 指定一个文件目录,当EHCache把数据写到硬盘上时,将把数据写到这个目录下 -->
    <diskStore path="c:\\ehcache"/>
    
    <!--  
    设置缓存的默认数据过期策略 
    -->    
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />


<!-- 
name 设置缓存的名字,他的取值为类的完整名字或者类的集合的名字;
maxElementsInMemory 设置基于内存的缓存可存放的对象的最大数目
eternal 如果为true,表示对象永远不会过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds,默认为false;
timeToIdleSeconds 设定允许对象处于空闲状态的最长时间,以秒为单位;
timeToLiveSeconds 设定对象允许存在于缓存中的最长时间,以秒为单位;
overflowToDisk 如果为true,表示当基于内存的缓存中的对象数目达到maxElementsInMemory界限,会把溢出的对象写到基于硬盘的缓存中;
-->




<!-- 设定具体的第二级缓存的数据过期策略 -->
    <cache name="com.java1234.model.Class"
        maxElementsInMemory="1"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />
 


</ehcache>


hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">


<hibernate-configuration>


    <session-factory>


        <!--数据库连接设置 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>


       
        <!-- 方言 -->
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- 控制台显示SQL -->
        <property name="show_sql">true</property>


        <!-- 自动更新表结构 -->
        <property name="hbm2ddl.auto">update</property>
        
         <!-- 启用二级缓存 -->
<property name="cache.use_second_level_cache">true</property>
   
    <!-- 配置使用的二级缓存的产品 -->
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
   
    <!-- 配置启用查询缓存 -->
    <property name="cache.use_query_cache">true</property>
        
  <mapping resource="com/java1234/model/Student.hbm.xml"/>
 
  <mapping resource="com/java1234/model/Class.hbm.xml"/>


    </session-factory>


</hibernate-configuration>


@Test
public void testCache2(){ 2个sql
Session session1=sessionFactory.openSession();
session1.beginTransaction();
Class c=(Class)session1.get(Class.class, Long.valueOf(1));
System.out.println(c.getName());
session1.getTransaction().commit();
session1.close();

Session session2=sessionFactory.openSession();
session2.beginTransaction();
Class c2=(Class)session2.get(Class.class, Long.valueOf(1));
System.out.println(c2.getName());
session2.getTransaction().commit();
session2.close();

System.out.println(c==c2); false 只有一条sql


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


<hibernate-mapping package="com.java1234.model">


<class name="Class" table="t_class"> 开启二级缓存
<cache usage="read-only"/>
<id name="id" column="classId">
<generator class="native"></generator>
</id>

<property name="name" column="className"></property>
</class>


</hibernate-mapping>

原创粉丝点击