Hibernate简介以及简单使用

Hibernate

1 Hibernate简介

   Hibernate是一个开放源代码的对象关系映射框架(ORM),它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

 

ORM   Object Relational Mapping

 持久层框架: Mybatis  Hibernate  OJB  JDO  Toplink...

 Hibernate版本:  2.x,3.x,4.x,5.x(目前最高版本 5.2.10)

2 hibernate使用

2.1 jar包导入

           hibernate3.jar

lib/required/*.jar

lib/jpa/*.jar   JPA  Java Persistance API

数据库驱动包

2.2 hibernate配置文件

2.2.1 总体配置文件(hibernate.cfg.xml)

      作用: 配置数据连接信息,加载映射配置文件等

<!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>  <!-- 一个sessionFactory 就表示一个数据库连接 -->

        <!-- 数据库方言 -->

        <property name="dialect">

         org.hibernate.dialect.MySQLDialect

        </property>      

        <!-- 数据库连接信息 -->

        <property name="connection.driver_class">

           com.mysql.jdbc.Driver

        </property>

        <property name="connection.url">

           jdbc:mysql:///db0729

        </property>

        <property name="connection.username">root</property>

        <property name="connection.password">mysql</property>

        <!-- 数据库连接信息 -->

        <property name="show_sql">true</property>

        <property name="format_sql">true</property>

        <!-- 加载映射配置文件 -->

        <mapping resource="com/zrgk/entity/User.hbm.xml" />

    </session-factory>

</hibernate-configuration>

 

2.2.2 映射配置文件(***.hbm.xml)

      作用:配置数据库表和实体类,表的字段和实体类属性的对应关系

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="com.zrgk.entity.User" table="user">

       <id name="id" column="id">

          <generator class="native"></generator>

       </id>

       <property name="name" column="name" type="string"></property>

       <property name="age" type="java.lang.Integer"></property>

       <property name="birthday"  type="java.util.Date"></property>

    </class>

</hibernate-mapping>

2.3 Hibernate入门程序

 

2.3.1 添加操作

//1 Configuration  加载hibernate总体配置文件

Configuration cfg = new Configuration().configure();

//2 创建SessionFactory

SessionFactory sf = cfg.buildSessionFactory();

//3 创建Session

Session session  = sf.openSession();

//4 开启事务  Transaction

Transaction tx = session.beginTransaction();

User user = new User();

user.setName("李四");

user.setAge(20);

user.setBirthday(new Date());

//5保存数据

session.save(user);//返回新添加的数据的主键值

//6提交事务

tx.commit();

//7关闭session

session.close();

 

 

 

2.3.2 根据主键(OID)查询

Load:

Configuration cfg = new Configuration().configure();

SessionFactory sf = cfg.buildSessionFactory();

Session session  = sf.openSession();

 

//查询  有无事务都可

 

User user = (User)session.load(User.class, 10);

 

//System.out.println(user.getId()+"\t"+user.getName()+"\t"+user.getAge()+"\t"+user.getBirthday());

 

user.getName();

 

session.close();

 

System.out.println(user.getId()+"\t"+user.getName()+"\t"+user.getAge()+"\t"+user.getBirthday());

 

Get:

Configuration cfg = new Configuration().configure();

SessionFactory sf = cfg.buildSessionFactory();

Session session  = sf.openSession();

User user = (User)session.get(User.class, 10);

//System.out.println(user.getId()+"\t"+user.getName()+"\t"+user.getAge()+"\t"+user.getBirthday());

 

session.close();

System.out.println(user.getId()+"\t"+user.getName()+"\t"+user.getAge()+"\t"+user.getBirthday());

 

get方法和load方法的区别:

         1  get方法查询时是立即加载(执行get方法后,立即向数据库发送sql语句查询回数据)

    load方法查询时才用的是延时加载(执行load方法时,并没有向数据库发送sql语句查询数据,而是返回一个代理对象。load方法是在第一次获取代理对象中,非主键的属性时,才发送sql语句进行查询)

 

         2  当根据所给主键,查不到数据时,  get方法 返回 null

                                   load方法  抛异常

 

2.3.3 封装获取Session的工具类

public class HibernateUtil {

/*

 * SessionFactory是一个重量级对象(创建和销毁时都要消耗比较多的内存和资源)

 *

 *   1 加载映射配置文件

 *   2 生成预定义的sql

 *   3 为创建Session准备环境

 *   

 *   SessionFactory 设置成 静态的

 *

 * */

private static SessionFactory factory;

public static SessionFactory getSessionFactory(){

if(factory==null){

Configuration cfg = new Configuration().configure();

factory = cfg.buildSessionFactory();

}

return factory;

}

public static Session getSession(){

return getSessionFactory().openSession();

}

}

 

2.4 实体对象在hibernate中的三种状态

1 瞬时(临时) Transient

 new出来的对象

 1、生命周期没有被session管理

2、不和数据库中的任何一条数据对应(这里所谓的对应就是指主键对应)

2 持久化     Persistent

1 对象的生命周期被session管理

2 和数据库中的一条数据对应

3 脱管(游离) Detached

1 对象的生命周期没有被session管理

2 和数据库中的一条数据对应

 

             new

 

 

 

 

get()                          save()              delete()

load()                  saveOrupdate()

iterate()

 

 

 

 

 

                      evict()                      update()

                      close()                      saveOrUpdate()

                      clear()                      lock() (过时)

 

 

 

 

2.5 更新操作

Session session = HibernateUtil.getSession();

 

Transaction tx = session.beginTransaction();

 

session.update(user); // 这里user对象持久化状态的对象(即,主键值和数据库中的一条数据对应)

 

tx.commit();

 

session.close();

 

2.6 删除操作

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.delete(user); // 这里user对象持久化状态的对象(即,主键值和数据库中的一条数据对应)

tx.commit();

session.close();

2.7 saveOrUpdate方法

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.saveOrUpdate(user);   // 返回值是所添加的数据的主键值

//如果主键值和数据库中的一条数据对应,则执行更新操作没有对应,执行添加操作

tx.commit();

session.close();

 

 

 

2.8 关于快照

User user= new User();

user.setName(“张三”);

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();   

session.save(user);   // 持久化

user.setName("李四");  // 持久化

tx.commit();

session.close();

 

生成insert update语句。

 

 

 

 

 

 

               session.save(user)

 

 

 

 

Persist

 

 

 

 

 

 

 

 

 

 

commit()      提交时,hibernate会拿持久化对象和照片做对比,如果有不同,则生成update语句 

close()

 

 

 

 

2.9将图片(二进制文件)入数据库

修改MySQL允许上传文件的大小,在my.ini文件中添加

max_allowed_packet=500M

 

 

<class name="com.zrgk.domain.User" table="user">

 

<id name="id" column="id">

<generator class="native"/>

</id>

 

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

        <property name="age"></property>

        <property name="birthday" ></property>

        <property name="photo" type="binary"></property>

</class>

 

User user = new User();   // 瞬时

user.setName("张三");

user.setAge(20);

user.setBirthday(new Date());

InputStream is = new FileInputStream("D:/img-12.jpg");

byte[] b = new byte[is.available()];

is.read(b);

user.setPhoto(b);

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(user);   // 持久化

tx.commit();

session.close();

3 主键生成策略

3.1 increment

整数类型的主键,采用取最大值+1的策略

集群环境不适合使用   

3.2 identity 

整数类型的主键, 支持自增的数据库 ---- 把主键的维护交给数据库,hibernate不维护主键

3.3 sequence  

整数类型的主键,支持序列的数据库

<id name="id">

<generator class="sequence"></generator>

</id>

默认使用的是  hibernate_sequence 这个序列

如何指定其他序列???

<id name="id">

<generator class="sequence">

<param name="sequence">user_seq</param>

</generator>

</id>

3.4 UUID

   字符串类型的主键

3.5 guid

   SQLServer、MySQL支持,字符串类型的主键

 

3.6 native    

根据数据库选择    identity   hilo    sequence

   

3.7assigned

   手动分配主键

3.8  联合主键

composite-id      包含联合主键的类,必须实现 Serializable接口

方式1:

class Person{

private String firstName;

private String lastName;

private int age;

}

 

<composite-id>

<key-property name="firstName" column="first_name"></key-property>

<key-property name="lastName" column="last_name"></key-property>

</composite-id>

 

   

方式2   

class Name{

private String firstName;

private  String lastName;

}

 

class Teacher{

private Name name;

private int age;

}

  

<composite-id name="name">

<key-property name="firstName" column="first_name"></key-property>

<key-property name="lastName" column="last_name"></key-property>

</composite-id>

3.9自定义主键生成策略

public class MyGenerator implements IdentifierGenerator,Configurable {

private String formatStr="yyyyMMddhhmmss";

@Override

public Serializable generate(SessionImplementor arg0, Object arg1)

throws HibernateException {

Date date = new Date();

SimpleDateFormat sdf = new SimpleDateFormat(formatStr);

//Connection conn = arg0.connection();

String str = sdf.format(date);

return str;

}

@Override

public void configure(Type arg0, Properties arg1, Dialect arg2)

throws MappingException {

formatStr = (String)arg1.get("formatStr");

 

}

}

 

 

 

<hibernate-mapping package="com.zrgk.domain">

<class name="Student">

<id name="num">

<!-- <generator class="uuid"/> -->

<generator class="com.zrgk.util.MyGenerator">

   <param name="formatStr">yyyy-MM-dd-hh-mm-ss</param>

</generator>

</id>

        <property name="name"></property>

        <property name="age"></property>

</class>

</hibernate-mapping>

4 hibernate一级缓存

   Session级别的缓存,自动开启,不能关闭。

Session session = HibernateUtil.getSession();

User user = (User)session.get(User.class, 1);

User user2 = (User)session.get(User.class,1);  // 从缓存中取

session.close();

System.out.println(user.getId()+"\t"+user.getName()+"\t"+user.getAge());

System.out.println(user2.getId()+"\t"+user2.getName()+"\t"+user2.getAge());

 

 

Session session2 = HibernateUtil.getSession();

User user3 = (User)session2.get(User.class, 1);

session2.close();

System.out.println(user3.getId()+"\t"+user3.getName()+"\t"+user3.getAge());

清除缓存:

session.flush()   清session的缓存,把数据同步到数据库中。

session.clear()   清session的缓存,数据不会同步到数据库中。

session.evict(user)   把指定对象从session的缓存中清除,数据不会同步到数据库中。

 

因为在添加数据(调用save方法)时,对象会被存入一级缓存中,因此,当大批量添加数据时,需要定时清除缓存

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

long begin = System.currentTimeMillis();

for(int i=1;i<=100000;i++){

User user = new User();

user.setName("test"+i);

user.setAge(20);

session.save(user);

if(i%50==0){

session.flush();

}

}

tx.commit();

session.close();

long end = System.currentTimeMillis();

System.out.println("共用了"+(end-begin)/1000+"秒");

 

 

 

 

5 关联关系映射

5.2 对一

配置方式:

<many-to-one name="多方存一方时对象名" class="一方的类名" column="外键列名">

</many-to-one>

 

<many-to-one name="department" class="Department" column="dept_id" cascade="delete">  

</many-to-one>

属性说明:

cascade(级联操作):

none (默认) 不级联

    save-update 级联保存和更新

delete      级联删除

    all         包括  save-update 和 delete     

    delete-orphan  删除孤儿

all-delete-orphan

lazy(延时加载):

      proxy       默认  延时加载

      no-proxy    延时加载

   false       立即加载

@Test

public void test1(){   // 只保存employee  

Employee e1 = new Employee();

e1.setName("小毛");

e1.setSalary(1000);

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(e1);  // 保存成功

tx.commit();

session.close();

}

@Test

public void test2(){   

Employee e1 = new Employee();

e1.setName("小邓");

e1.setSalary(1000);

Department d = new Department();  

d.setName("研发部");  // 这时表中还没有这个部门

e1.setDepartment(d);  // 建立员工和部门的关系

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(e1);  // 保存失败,外键无法赋值

tx.commit();

session.close();

}

@Test

public void test3(){

Employee e1 = new Employee();

e1.setName("小邓");

e1.setSalary(1000);

Department d = new Department();  

d.setId(1); // 脱管对象,  --研发部

e1.setDepartment(d);  // 建立员工和部门的关系     

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(e1);  //  添加成功!!! (当部门已经存在时,保存成功)

tx.commit();

session.close();

}

@Test

public void test4(){   // 级联保存   cascade="save-update"

Employee e1 = new Employee();

e1.setName("小江");

e1.setSalary(1000);

Department d = new Department();  

d.setName("测试部");

e1.setDepartment(d);  // 建立员工和部门的关系

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(e1);  //级联保存,先存部门,再存员工

tx.commit();

session.close();

}

@Test

public void test5(){   // 删除

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Employee e = (Employee)session.get(Employee.class,4);

session.delete(e);

tx.commit();       // 只删多方,可以删除

session.close();

 

}

@Test

public void test6(){   // 级联删除   cascade="delete"    “一般不用!!!!”

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Employee e = (Employee)session.get(Employee.class,1);

session.delete(e);  //级联删除,也会删除对应的部门,如何这个部门被其他员工,会把其他员工的外键更新为null

tx.commit();

session.close();

 

}

@Test

public void test7(){  //解除关系   解除小江和研发部的关系

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Employee e = (Employee)session.get(Employee.class,3);

e.setDepartment(null);  // 解除关系

// session.update(e);  //这句可以省略

tx.commit();

session.close();

}

@Test

public void test8(){  //把小江从研发部调到测试部

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Employee e = (Employee)session.get(Employee.class,3);

Department d = (Department)session.get(Department.class, 2);

e.setDepartment(d);  // 调职

session.update(e);  

tx.commit();

session.close();

}

@Test

public void test9(){  // 查询

Session session = HibernateUtil.getSession();

 

Employee e = (Employee)session.get(Employee.class,3);        System.out.println(e.getId()+"\t"+e.getName()+"\t"+e.getSalary()+"\t"+e.getDepartment().getName());

        // 多对一时,关联对象会被直接查询出来 (只查employee时,对应的department会被查询

session.close();

 

}

@Test

public void test10(){  // 查询

Session session = HibernateUtil.getSession();

Employee e = (Employee)session.get(Employee.class,3);

//e.getDepartment().getName();

session.close();

 

System.out.println(e.getId()+"\t"+e.getName()+"\t"+e.getSalary());

System.out.println(e.getDepartment().getName()); // 关联对象默认是延时加载的(懒加载)

}

 

5.2

<set name="employeeSet" cascade="save-update,delete">

<key column="dept_id"></key>

<one-to-many class="Employee" />

</set>

属性说明:

       cascade

   save-update   delete   delete-orphan

 

    lazy     

 true 默认,延时加载

  false 立即加载

extra   延时加载    (比lazy="true"还懒)

inverse

                      true

                     多数一对多(多对一)操作,都会把inverse 设置为true , 让一方放弃对外键的维护

@Test

public void test1(){  //添加  ---  只添加一方

Department d = new Department();

d.setName("市场部");

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(d);

tx.commit();

session.close();

}

@Test

public void test2(){  //添加  

Department d = new Department();

d.setName("人事部");

Employee e1 =  new Employee();

e1.setName("老大");

e1.setSalary(1000);

Employee e2 =  new Employee();

e2.setName("老二");

e2.setSalary(1000);

e1.setDepartment(d);  // 建立关系

e2.setDepartment(d);  // 建立关系

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(d);   // 只会保存 d  和e1 e2 没有任何关系

tx.commit();

session.close();

}

@Test

public void test3(){  //级联保存   cascade="save-update"  

 

Department d = new Department();

d.setName("人事部");

Employee e1 =  new Employee();

e1.setName("老大");

e1.setSalary(1000);

Employee e2 =  new Employee();

e2.setName("老二");

e2.setSalary(1000);

e1.setDepartment(d);  // 建立关系

e2.setDepartment(d);  // 建立关系

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(d);   //没有级联的效果!!! 原因是,建立关系是在多方建立的

tx.commit();

session.close();

}

 

@Test

public void test4(){  //级联保存   cascade="save-update"  

Department d = new Department();

d.setName("人事部");

Employee e1 =  new Employee();

e1.setName("老大");

e1.setSalary(1000);

Employee e2 =  new Employee();

e2.setName("老二");

e2.setSalary(1000);

    d.getEmployeeSet().add(e1);

    d.getEmployeeSet().add(e2);

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(d);   //可以级联保存

tx.commit();

session.close();

}

@Test

public void test6(){  //删除    没有被多方参照的一方

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Department d = (Department)session.get(Department.class,3);

session.delete(d);  // 可以删除

tx.commit();

session.close();

}

@Test

public void test7(){  //删除      有被多方参照的一方

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Department d = (Department)session.get(Department.class,6);

session.delete(d);  // 可以删除, 也可以被删除,多方的外键被更新为null

tx.commit();

session.close();

}

@Test

public void test8(){  //级联删除   cascade="delete"

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Department d = (Department)session.get(Department.class,2);

session.delete(d);  //

tx.commit();

session.close();

}

@Test

public void test9(){  // 解除关系   解除研发部和小邓的关系

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Department d = (Department)session.get(Department.class,1); // 研发部

Employee e = (Employee)session.get(Employee.class,2);  // 小邓

d.getEmployeeSet().remove(e);  // 解除关系

session.update(d);

tx.commit();

session.close();

}

@Test

public void test10(){  // 解除关系   解除研发部下的所有关系

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Department d = (Department)session.get(Department.class,1); // 研发部

d.setEmployeeSet(null);

session.update(d);

tx.commit();

session.close();

}

@Test

public void test11(){  // 删除孤儿  cascade="delete-orphan"

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Department d = (Department)session.get(Department.class,1); // 研发部

Employee e = (Employee)session.get(Employee.class,2);  // 小邓

d.getEmployeeSet().remove(e); // 解除了研发部和小邓的关系, 小邓就变成了孤儿

// 由于是删除孤儿,所以 小邓会被删除

// 这里的删除孤儿,之后删除由于解除关系操作变成的孤儿,原有的孤儿是不会被删除的

session.update(d);

tx.commit();

session.close();

}

@Test

public void test12(){  // 只查一方

Session session = HibernateUtil.getSession();

Department d = (Department)session.get(Department.class,1); // 研发部

System.out.println(d.getName());

session.close();

}

@Test

public void test13(){  // 查询

Session session = HibernateUtil.getSession();

Department d = (Department)session.get(Department.class,1); // 研发部

System.out.println(d.getName());

for(Employee e:d.getEmployeeSet()){

System.out.println(e.getName());

}

session.close();

}

@Test

public void test14(){  // 查询  -----  关联对象延时加载

Session session = HibernateUtil.getSession();

Department d = (Department)session.get(Department.class,1); // 研发部

System.out.println(d.getName());

session.close();

    for(Employee e:d.getEmployeeSet()){

System.out.println(e.getName());

}

}

@Test

public void test15(){  // 查询  -----  关联对象延时加载

 

Session session = HibernateUtil.getSession();

 

Department d = (Department)session.get(Department.class,1); // 研发部

 

System.out.println(d.getName());

d.getEmployeeSet().size(); // 在session关闭之前取  ---  lazy="extra" 当取集合的size时,只会生成 count语句

session.close();

    for(Employee e:d.getEmployeeSet()){

System.out.println(e.getName());

}

}

@Test

public void test16(){  // inverse="true"    把小毛调到测试部

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Department d = (Department)session.get(Department.class,2); // 测试部

Employee e = (Employee)session.get(Employee.class,1);

e.setDepartment(d);

d.getEmployeeSet().add(e);   // 其实这句话是一个多余的操作~~~ 但这句话引起了一个update语句

// 能够反映出,一方,多方都会去维护外键列

// 一般情况下,不站在一方操作外键。  inverse="true" 是指,一方放弃对外键的维护

session.update(e);

tx.commit();

session.close();

}

@Test

public void test17(){  // inverse="true"   级联保存 cascade="save-update"

Department d = new Department();

d.setName("人事部");

Employee e1 =  new Employee();

e1.setName("老大");

e1.setSalary(1000);

Employee e2 =  new Employee();

e2.setName("老二");

e2.setSalary(1000);

    d.getEmployeeSet().add(e1);

    d.getEmployeeSet().add(e2);

    e1.setDepartment(d);

    e2.setDepartment(d);

    

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

session.save(d);     // 虽然级联保存成功,但多方外键没有值,因为一方放弃了对外键的维护

tx.commit();

session.close();

}

 

 

5.2

  <set name="本方存对方集合的名称" table="中间表表名">

<key column="中间表中参照本方的外键列名"></key>

<many-to-many class="集合中数据的类型" column="中间表中参照对方的外键列名"></many-to-many>

</set>

 

<set name="courseSet" table="student_course" cascade="save-update,delete" lazy="false">

           <key column="student_id"></key>

           <many-to-many class="Course" column="course_id"></many-to-many>

</set>

 

属性说明:

cascade

lazy

inverse  多对多时,比较少站在哪一端操作,就把哪一端的inverse设置为true

@Test

public void test1(){  // 添加 Student

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Student s = new Student();

s.setName("张三");

session.save(s);

tx.commit();

session.close();

}

 

@Test

public void test2(){  // 添加 Course

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Course c = new Course();

c.setName("数学");

session.save(c);

tx.commit();

session.close();

}

@Test

public void test3(){  // 级联保存

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Student s = new Student();

s.setName("李四");

Course c1 = new Course();

c1.setName("语文");

Course c2 = new Course();

c2.setName("英语");

s.getCourseSet().add(c1);

s.getCourseSet().add(c2);

session.save(s);

tx.commit();

session.close();

}

@Test

public void test4(){  // 删除

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Student s =(Student)session.get(Student.class,2);

session.delete(s);  // 可以删除,外键会被更新为null

tx.commit();

session.close();

}

@Test

public void test5(){  // 级联删除  cascade="delete"

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Student s =(Student)session.get(Student.class,2);

session.delete(s);   // 课程被其他学生参照时,不能实现级联删除

tx.commit();

 

session.close();

}

@Test

public void test6(){  // 修改张三所选课程

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Student s =(Student)session.get(Student.class,1);

Course c1  = (Course)session.get(Course.class,1);

Course c2  = (Course)session.get(Course.class,2);

s.setCourseSet(null);

/*s.getCourseSet().add(c1);

s.getCourseSet().add(c2);*/

Set<Course> set = new HashSet<Course>();

set.add(c1);

set.add(c2);

s.setCourseSet(set);

session.update(s);  

tx.commit();

session.close();

 

}

@Test

public void test7(){  // 查询

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Student s =(Student)session.get(Student.class,1);

System.out.println(s.getName());

for(Course c:s.getCourseSet()){

System.out.println(c.getName());

}

tx.commit();

session.close();

 

}

@Test

public void test8(){  // 查询  ---- 关联关系,延时加载

Session session = HibernateUtil.getSession();

Student s =(Student)session.get(Student.class,1);

System.out.println(s.getName());

session.close();

    for(Course c:s.getCourseSet()){

  System.out.println(c.getName());

}

}

@Test

public void test9(){  // 查询  ---- 关联关系,延时加载   lazy="false"

Session session = HibernateUtil.getSession();

Student s =(Student)session.get(Student.class,1);

System.out.println(s.getName());

session.close();

    for(Course c:s.getCourseSet()){

  System.out.println(c.getName());

}

}

 

5.2 对一

5.2.1 主键关联

主控方:

<!-- id被wife参照    主控方-->

<class name="Husband">

<id name="id">

   <generator class="native"></generator>

</id>

     <property name="name"></property>

    <one-to-one name="wife" class="Wife" lazy="proxy"></one-to-one>

</class>

 

被控方:

<!-- id参照husband  被控方-->

<class name="Wife">

 <id name="id">

     <generator class="foreign">

        <param name="property">husband</param>

      </generator>

    </id>

        <property name="name"></property>

        <one-to-one name="husband" class="Husband" constrained="true" cascade="delete"></one-to-one>

</class>

 

@Test

public void test1(){  // 添加 Wife

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Wife w = new Wife();

w.setName("小红");

session.save(w);   // 先添加wife 不可以的

tx.commit();

session.close();

}

 

@Test

public void test2(){  // 添加 Husband

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Husband h = new Husband();

h.setName("小明");

session.save(h);   

tx.commit();

session.close();

}

@Test

public void test3(){  // 添加 Wife

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Wife w = new Wife();

w.setName("小红");

Husband h = (Husband)session.get(Husband.class,1);

w.setHusband(h);

session.save(w);   

tx.commit();

session.close();

}

@Test

public void test4(){  // 添加 Wife

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Wife w = new Wife();

w.setName("小栏");

Husband h = new Husband();

h.setName("小强");

w.setHusband(h);

session.save(w);     // 不需要配置,就会级联保存

tx.commit();

session.close();

}

@Test

public void test5(){  // 添加 Husband

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Wife w = new Wife();

w.setName("小花");

Husband h = new Husband();

h.setName("小刚");

h.setWife(w);   

session.save(h);    // 不会有级联的效果  (保存主控方时)

tx.commit();

session.close();

}

@Test

public void test6(){  // 添加 Husband  cascade="save-update"

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Wife w = new Wife();

w.setName("X");

Husband h = new Husband();

h.setName("Y");

h.setWife(w);   

session.save(h);    //  husband都不能保存

tx.commit();

session.close();

}

@Test

public void test7(){  // 删除

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Husband h = (Husband)session.get(Husband.class,3);

session.delete(h);    // 没有被参照的,可以删除

tx.commit();

session.close();

}

 

 

@Test

public void test8(){  // 删除

 

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Husband h = (Husband)session.get(Husband.class,1);

session.delete(h);    // 有被参照的,不能删除

tx.commit();

session.close();

}

@Test

public void test9(){  // 级联删除

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Husband h = (Husband)session.get(Husband.class,1);

session.delete(h);    // 可以

tx.commit();

session.close();

}

@Test

public void test10(){  // 删除被控方

 

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Wife w = (Wife)session.get(Wife.class,2);

session.delete(w);    // 可以

tx.commit();

session.close();

 

}

@Test

public void test11(){  // 级联删除被控方

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Wife w = (Wife)session.get(Wife.class,2);

session.delete(w);    // 可以

tx.commit();

session.close();

}

@Test

public void test12(){  

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Husband h = (Husband)session.get(Husband.class,1);

Wife w = (Wife)session.get(Wife.class,1);

h.setWife(null);

session.update(h);    

tx.commit();

session.close();

}

 

@Test

public void test13(){    // 关联关系 默认使用左外连接方式查询, 延时加载失效

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Husband h = (Husband)session.get(Husband.class,1);

tx.commit();

session.close();

System.out.println(h.getName());

System.out.println(h.getWife().getName());

}

@Test

public void test14(){    // 查被控方,关联关系 默认延时加载

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Wife w = (Wife)session.get(Wife.class,1);

tx.commit();

session.close();

System.out.println(w.getName());

System.out.println(w.getHusband().getName());

 

}

5.2.2 唯一外键关联

<class name="Person">

<id name="id">

    <generator class="identity"/>

</id>

        <property name="name"></property>

        <one-to-one name="idcard" class="IdCard"  property-ref="person" cascade="save-update,delete"></one-to-one>

          <!-- property-ref 对方存本方时,属性名 -->

</class>

 

 

 

 

<class name="IdCard">

    <id name="id">

       <generator class="identity"/>

    </id>

        <property name="num"></property>

        <many-to-one name="person" class="Person" unique="true" column="person_id" cascade="save-update,delete"></many-to-one>

</class>

 

@Test

public void test1(){  // 添加Person

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Person p = new Person();

p.setName("xxx");

session.save(p);   

tx.commit();

session.close();

}

@Test

public void test2(){  // 添加idcard

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

IdCard ic = new IdCard();

ic.setNum("88888888888888");

session.save(ic);   

tx.commit();

session.close();

}

@Test

public void test3(){  // 添加

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

    Person p = new Person();

p.setName("yyy");

IdCard ic = new IdCard();

ic.setNum("99999999999999999999");

p.setIdcard(ic);

session.save(p);    // 不会级联

tx.commit();

session.close();

}

 

@Test

public void test4(){  // 级联添加

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

    Person p = new Person();

p.setName("");

IdCard ic = new IdCard();

ic.setNum("6666666666666");

p.setIdcard(ic);

session.save(p);   // OK

tx.commit();

session.close();

}

@Test

public void test5(){   

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

    Person p = new Person();

p.setName("ttt");

IdCard ic = new IdCard();

ic.setNum("777777777777");

//ic.setPerson(p);  //建立关系后,双方都不能保存

session.save(ic);   

tx.commit();

session.close();

}

@Test

public void test6(){  // 级联

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

    Person p = new Person();

p.setName("ttt");

IdCard ic = new IdCard();

ic.setNum("777777777777");

ic.setPerson(p);

session.save(ic);   // OK  

tx.commit();

session.close();

}

@Test

public void test7(){  // 删除Person

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Person p = (Person)session.get(Person.class,1);

session.delete(p);    // 没有被参照的,可以删除

tx.commit();

session.close();

}

@Test

public void test8(){  // 删除Person

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Person p = (Person)session.get(Person.class,4);

session.delete(p);    // 被参照的,不能删除

tx.commit();

session.close();

}

@Test

public void test9(){  // 级联删除

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Person p = (Person)session.get(Person.class,4);

session.delete(p);    // 可以

tx.commit();

session.close();

}

@Test

public void test10(){  // 删除IdCard

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

IdCard ic = (IdCard)session.get(IdCard.class,1);

session.delete(ic);    // 可以

tx.commit();

session.close();

}

@Test

public void test11(){  // 级联删除idcard

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

IdCard ic = (IdCard)session.get(IdCard.class,5);

session.delete(ic);    // 可以

tx.commit();

session.close();

}

@Test

public void test12(){   // 解除关系

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

IdCard ic = (IdCard)session.get(IdCard.class,2);

ic.setPerson(null);

session.update(ic);    

tx.commit();

session.close();

}

@Test

public void test13(){    // 关联关系----- 立即加载,lazy失效

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

Person p = (Person)session.get(Person.class,3);

tx.commit();

session.close();

System.out.println(p.getName());

System.out.println(p.getIdcard().getNum());

}

@Test

public void test14(){    // 查被控方,延时加载

Session session = HibernateUtil.getSession();

Transaction tx = session.beginTransaction();

IdCard ic = (IdCard)session.get(IdCard.class,2);

tx.commit();

session.close();

System.out.println(ic.getNum());

System.out.println(ic.getPerson().getName());

}

6 封装Hibernate的DAO模板类

接口:

public interface BaseDao<T,PK extends Serializable> {

 

  public void insert(T t);

  public void update(T t);

  public void delete(T t);

  public T findById(PK id);

}

 

实现类:

public class BaseDaoImpl<T,PK extends Serializable> implements BaseDao<T, PK> {

Class entityClass;

public Class getEntityClass() {

return entityClass;

}

public void setEntityClass(Class entityClass) {

this.entityClass = entityClass;

}

 

@Override

public void insert(T t) {

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

session.save(t);

tx.commit();

session.close();

}

 

@Override

public void update(T t) {

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

session.update(t);

tx.commit();

session.close();

}

@Override

public void delete(T t) {

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

session.delete(t);

tx.commit();

session.close();

}

@Override

public T findById(PK id) {

Session session = HibernateSessionFactory.getSession();

T t = (T)session.get(entityClass, id);

session.close();

return t;

}

}

 

使用:

public class UserDaoImpl extends BaseDaoImpl<User,Integer> implements UserDao {

 public UserDaoImpl(){

 this.entityClass=User.class;

 }

……

}

7 hibernate中的查询

7.1根据idOID)的查询(get或load方法)

7.2 Hql(Hibernate Query Language)

sql语句的区别:关系型数据库的表名换成类名列名换成成员变量的名字

Query q=session.createQuery(“from Customer c where c.name=:name and c.age=:age”);

q.setString(“name”,”aaa”);// q.setParameter("name","aaa");

q.setInteger(“age”,23);

List result = q.list();

 

(参数绑定的两种方式,也可以使用问号)  索引从零开始

可以写成一条语句:

List result = session.createQuery(“from Customer c where c.name=:name and c.age=:age”).setString(“name”,”aaa”).setInteger(“age”,23).list();

 

当能确定是只返回一条时:

User user = session.createQuery(hql).setParameter("userName","zhangsan").uniqueResult();

当使用hql语句查询数据 做了投影时,将不会返回对象,将返回Object数组

可以这样来解决这个问题:

String hql = "select new domain.User(u.name,u.age) from User u where u.name like :uName";

User类中要有对应的构造方法(建议,查询时不做投影)

查询结果排序:

Query q=session.createQuery(“from User u order by u.name desc”);

 

关于分页查询:

q.setFirstResult(0);      //从哪条开始

q.setMaxResults(10);    // 取几条

 

使用setParameter方法绑定任意类型的参数:

Query q=session.createQuery("from Order o where o.customer=:customer"+"and  o.orderNumber like :orderNumber");

q.setParameter("customer",customer,Hibernate.entity(Customer.class));

q.setParameter("orderNumber",orderNumber,Hibernate.STRING);

 

 

 

使用setProperties方法绑定参数:

Customer c=new Customer();

c.setName(“zhangsan”);

c.setAge(33);

Query q=session.createQuery(“from Customer c where c.name=:name and c.age=:age”);

q.setProperties(c);

 

在配置文件中编写hql语句:

<hibernate-mapping>

<class name=“mypack.Customer” table=“CUSTOMERS”>

</class>

<query name=“aFind”><![CDATA[

from Customer c where c.name like :name]]></query>

</hibernate-mapping>

 

Query q=session.getNamedQuery(“aFind”);

q.setString(“name”,name);

List result=q.list();

 

使用 group by

  String hql = "select distinct u.id from User u join u.orders o group by u.id having sum(o.price)>:price";

 Query q = s.createQuery(hql);

      q.setParameter("price", price);

      List list = q.list();

    String hql2 = "select * from User u where u.id in (:userIds)";

    Query q2 = s.createQuery(hql2);

    q2.setParameter("userIds", list);

String hql = "from User u where u.orders is not empty";

 

 

 

 

 

7.3 QBC(Query By Criteria)

Criteria c=session.createCriteria(Customer.class);

SimpleExpression c1=Restrictions.like(“name”,”zhang%”);

SimpleExpression c2=Restrictions.eq(“age”,new Integer(99));

c=c.add(c1).add(c2);

List result=c.list();

 

查询结果排序:

Criteria c=session.createCriteria(Customer.class);

c.addOrder(Order.asc(“name”));

c.addOrder(Order.desc(“age”));

 

关于分页查询:

c.setFirstResult(0);

c.setMaxResults(10);

 

Criteria中的查询结果比较

检索年龄大于18的Customer:

Criteria c=session.createCriteria(Customer.class);

c.add(Restrictions.gt(“age”,18));

检索年龄不等于18的Customer:

c.add(Restrictions.not(Restrictions.eq(“age”,new Integer(18))));

not (age=18)

检索姓名为空的Customer:

c.add(Restrictions.isNull(“name”));

 

检索不属于任何客户的订单:

c.add(Restrictions.isNull(“customer”));

 

检索名字为zhangsan的客户:

c.add(Restrictions.eq(“name”,”zhangsan”).ignoreCase());

ge---------------------->=

le----------------------<=

 

Criteria中的OR

Restrictions.or(Restrictions.eq(),Restrictions.or(Restrictions.between(),Resctions.like()))

String[] names={“Tom”,”Mike”,”Jack”};

c.add(Restrictions.in(“name”,names));

 

between and

检索年龄不在18到30的客户:

c.add(Restrictions.between(“age”,new Integer(18),new Integer(30));

not

检索年龄不在18到30的客户:

c.add(Restrictions.not(Restrictions.between(“age”,new Integer(18),new Integer(30)));

 

count和分组

Critieria c = s.createCriteria(Customer.class)

 c.setProjection(Projections.rowCount());

 c.setProjection(Projections.groupProperty("sex"));

 

 

 

 

//Select count(*)  from customer group by sex

Critieria c = s.createCriteria(Customer.class).setProjection(Projections.ProjectionList().add(Projections.rowCount()).add(Projections.groupProperty("sex")))

 c.setProjection(Projections.rowCount());

 c.setProjection(Projections.groupProperty("sex"));

 

 

7.4 QBE(Query By Example)

Customer c=new Customer();

c.setAge(99);

c.setName("aaa");

List result=session.createCriteria(Customer.class).add(Example.create(c)).list();

 

QBE只支持=和like,不支持or > <之类的查询

7.5 使用SQL

String sql = "select * from users u where u.name like :name";

        Query q = s.createSQLQuery(sql).addEntity(User.class);

        q.setParameter("name", name);

8 二级缓存

SessionFactory级别的缓存,需要手动开启。一般使用第三方提供的缓存。

8.1 开启二级缓存

hibernate.cfg.xml中开启:

<!-- 开启二级缓存 -->

<property name="cache.use_second_level_cache">true</property>

    <!-- 指定缓存提供商  EHCache -->

<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

 

<!-- 指定哪个类的对象会被方到二级缓存中 ,可以映射文件中指定-->

<class-cache usage="read-only" class="com.zrgk.domain.User"/>

 

<class name="User">

    <!-- 指定这个类的对象会被方到二级缓存中 -->

    <cache usage="read-only" region="" />

 

8.2 ehcache文件

     用来指定缓存规则

<ehcache>

    <diskStore path="java.io.tmpdir"/><!-- 缓存对象存在磁盘上路径 -->

    <!-- 缓存规则

       maxElementsInMemory  内存中最多缓存多少个对象

       timeToIdleSeconds    最大空闲时间()

       timeToLiveSeconds    最大存活时间

       overflowToDisk       内存中数量超过规定时,是否把对象存到磁盘上      

       eternal              是否是永久的

 

    -->

    <defaultCache

        maxElementsInMemory="10000"

        eternal="false"

        timeToIdleSeconds="120"

        timeToLiveSeconds="120"

        overflowToDisk="true"

        />

    <cache name="sampleCache1"

        maxElementsInMemory="10000"

        eternal="false"

        timeToIdleSeconds="300"

        timeToLiveSeconds="600"

        overflowToDisk="true"

        />

    <cache name="sampleCache2"

        maxElementsInMemory="1000"

        eternal="true"

        timeToIdleSeconds="0"

        timeToLiveSeconds="0"

        overflowToDisk="false"

        /> -->

</ehcache>

 

8.3 使用二级缓存

public static void main(String[] args) {

//System.out.println(System.getProperty("java.io.tmpdir"));

Session session = HibernateSessionFactory.getSession();

User user = (User)session.get(User.class, 1);

session.close();

System.out.println(user.getId()+"\t"+user.getName());

//HibernateSessionFactory.getSessionFactory().evict(User.class); //清除二级缓存

        Session session2 = HibernateSessionFactory.getSession();

User user2 = (User)session2.get(User.class, 1);

session2.close();

System.out.println(user2.getId()+"\t"+user2.getName());

}

 

9 getCurrentSession()的使用

要使用getCurrentSession() 方法,要在hibernate.cfg.xml中开启

  <!-- 配置可以使用getCurrentSession -->

          <property name="current_session_context_class">thread</property>

  使用getCurrentSession() 获得的session 即使是查询,也要有事务!!!

  这个session不需要手动close()

10 抓取策略  (fetch)

关联对象的查询,是跟抓取策略有关的。

<many-to-one  fetch="" >

select (默认)  -------- 关联对象延时加载,查关联对象时另外再发sql进行查询

join          --------- 使用左外连接方式查询, lazy失效

 

<set fetch=""></set>

  select(默认)  ----- 关联对象延时加载,查关联对象时,另发sql

  join          ----- 使用左外连接方式查询, lazy失效

  subselect     ----- 关联对象延时加载,查关联对象时,另发sql

              ----- 查关联对象,会使用子查询的方式

selectsubselect的区别:

Session session = HibernateSessionFactory.getSession();

Query query = session.createQuery("from Department where id in(1,2)");

List<Department> list = query.list();

for(Department d:list){

System.out.println(d.getName());

for(Employee e:d.getEmployeeSet()){

System.out.println("    "+e.getName());

}

}

session.close();

11 悲观锁和乐观锁

      避免丢失更新问题

             1 悲观锁    get(LockMode.UPGRADE)

             2 乐观锁  依靠版本控制

11.1 悲观

public void test1(){

Session session = HibernateSessionFactory.getSession();

User user = (User)session.get(User.class,1,LockMode.UPGRADE);

session.close();

}

 

//select * from user where id=1 for update

@Test

public void test2(){

Session session = HibernateSessionFactory.getSession();

User user = (User)session.get(User.class,1,LockMode.UPGRADE);

session.close();

 

}

 

11.2 乐观

public class User {

private int id;

private String name;

private int age;

private Date birthday;

private String email;

private int version;

public int getVersion() {

return version;

}

public void setVersion(int version) {

this.version = version;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public Date getBirthday() {

return birthday;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

}

 

<hibernate-mapping package="com.zrgk.domain">

<class name="User">

    <id name="id">

       <generator class="native"></generator>

    </id>

    <version name="version"></version>

        <property name="name"></property>

        <property name="age"></property>

        <property name="birthday"></property>

        <property name="email"></property>

</class>

</hibernate-mapping>

 

@Test

public void test1(){

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

User user = (User)session.get(User.class,1);

user.setName("xxx");

tx.commit();

session.close();

}

@Test

public void test2(){

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

User user = (User)session.get(User.class,1);

user.setName("yyy");

tx.commit();

session.close();

}

12查询缓存

一级缓存和二级缓存只能缓存对象,查询缓存可以缓存普通属性。

12.1 开启查询缓存

<!-- 开启查询缓存-->

<property name="hibernate.cache.use_query_cache">true</property>

12.2 使用查询缓存

Session session = HibernateSessionFactory.getSession();

        String hql = "select name from User where id=1";   // 指查name属性

        Query q = session.createQuery(hql);

        q.setCacheable(true); // 开启查询缓存

        String name1 = (String)q.uniqueResult();

        q.setCacheable(true);  // 每次查询都要调用这个方法开启查询缓存

        String name2 = (String)q.uniqueResult();

        System.out.println(name1+"\t"+name2);

   session.close();

   Session session3 = HibernateSessionFactory.getSession();

       String hql3 = "select name from User where id=1";

       Query q3 = session3.createQuery(hql3);

       q3.setCacheable(true); // 开启查询缓存

       String name3 = (String)q3.uniqueResult();

       System.out.println(name3);

      session3.close();

 

13 spring整合hibernate

13.1 添加spring整合hibernatejar包

org.springframework.orm-3.0.7.RELEASE.jar

13.2hibernate的配置信息转移spring配置文件中

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

       <property name="locations">

           <list>

               <value>classpath:dbconfig.properties</value>

           </list>

       </property>

   </bean>

 

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="${driver_class}">

</property>

<property name="url" value="${url}"></property>

<property name="username" value="${username}"></property>

<property name="password" value="${password}"></property>

</bean>

 

<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="dataSource">

<ref bean="dataSource"></ref>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">

org.hibernate.dialect.MySQLDialect

</prop>

 

<prop key="hibernate.show_sql">true</prop>

</props>

</property>

<!--

<property name="mappingResources">

<list>

<value>com/zrgk/domain/Department.hbm.xml</value>

<value>com/zrgk/domain/User.hbm.xml</value>

<value>com/zrgk/domain/Employee.hbm.xml</value>

</list>

</property>

-->

 

<property name="mappingDirectoryLocations">

     <list>

        <value>com/zrgk/domain</value>

     </list>

</property>

    </bean>

13.3使用模板HibernateTemplate

<!-- 配置模板类 HibernateTemplate  要把sessionFactory注入给ht-->

    <bean id="ht" class="org.springframework.orm.hibernate3.HibernateTemplate">

        <property name="sessionFactory" ref="sessionFactory"></property>   

    </bean>

    

    

    <!-- 配置BaseDao -->

    <bean id="baseDao" class="com.zrgk.dao.BaseDaoImpl" abstract="true">

       <property name="ht" ref="ht"></property>

</bean>

<bean id="userDao" class="com.zrgk.dao.UserDaoImpl" parent="baseDao"></bean>

     

<bean id="userService" class="com.zrgk.service.UserServiceImpl">

       <property name="userDao" ref="userDao"></property>

</bean>

 

public class BaseDaoImpl<T,PK extends Serializable> implements BaseDao<T, PK> {

Class entityClass;

private HibernateTemplate ht;  // spring 的类

public HibernateTemplate getHt() {

return ht;

}

public void setHt(HibernateTemplate ht) {

this.ht = ht;

}

public Class getEntityClass() {

return entityClass;

}

public void setEntityClass(Class entityClass) {

this.entityClass = entityClass;

}

@Override

public void insert(T t) {

 ht.save(t);

 

}

@Override

public void update(T t) {

    ht.update(t);

}

@Override

public void delete(T t) {

 ht.delete(t);

}

@Override

public T findById(PK id) {

T t = (T)ht.get(entityClass, id);

return t;

}

}

 

 

13.4事务管理

<!-- 配置事务管理器 切面 -->

    

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory"></property>

</bean>

    

    <!-- 事务的传播规则 -->

      <tx:advice id="txAdvice" transaction-manager="transactionManager">

           <tx:attributes>

                 <tx:method name="add*" propagation="REQUIRED"  />

                 <tx:method name="modify*" propagation="REQUIRED" />

                 <tx:method name="remove*" propagation="REQUIRED"/>

                 <tx:method name="zhuanzhang" propagation="REQUIRED" rollback-for="java.lang.NullPointerException"/>

                 <tx:method name="*" propagation="REQUIRED" read-only="true" />

           </tx:attributes>

      </tx:advice>

      

      <!-- 哪些类的哪些方法参与事务 -->

      <aop:config>

           <aop:pointcut id="allManagerMethod" expression="execution(* com.zrgk.service.*.*(..))"/>

           <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice" />

      </aop:config>

 

13.4继承方式整合

public class BaseDaoImpl<T,PK extends Serializable> extends HibernateDaoSupport implements BaseDao<T, PK> {

Class entityClass;

public Class getEntityClass() {

return entityClass;

}

public void setEntityClass(Class entityClass) {

this.entityClass = entityClass;

}

@Override

public void insert(T t) {

 this.getHibernateTemplate().save(t);

}

@Override

public void update(T t) {

this.getHibernateTemplate().update(t);

}

@Override

public void delete(T t) {

this.getHibernateTemplate().delete(t);

}

@Override

public T findById(PK id) {

 

T t = (T)this.getHibernateTemplate().get(entityClass, id);

return t;

}

}

 

<!-- 配置BaseDao -->

    <bean id="baseDao" class="com.zrgk.dao.BaseDaoImpl" abstract="true">

        <property name="sessionFactory" ref="sessionFactory"></property>

    </bean>

13.4保留hibernate配置文件的方式

<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="configLocation"

value="classpath:hibernate.cfg.xml">

</property>

</bean>

 

posted on 2018-09-09 18:01  云作  阅读(772)  评论(0)    收藏  举报

导航