Spring整合ORM技术 -- 集成Hibernate

发布时间:2020-07-04 22:27:23 作者:kuchensheng
来源:网络 阅读:1023

1、Spring整合ORM方案的好处:

2、Spring整合Hibernate步骤

    2.1 配置SessionFactory(可自动完成)

        使用Hibernate框架的第一个工作是编写Hibernate的配置文件,接着使用这些配置文件实例化SessionFactory,创建好Hibernate的基础设施。Spring为创建SessionFactory提供了FactoryBean工厂类:org.springframework.orm.hibernate3.LocalSessionFactoryBean,通过一些必要的配置,即可或缺一个SessionFactoryBean。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop" 
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
    
    <context:component-scan base-package="org.worm.biz.springmvc"/>
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
     destroy-method="close"
     p:driverClassName="${jdbc.driverClassName}"
     p:url="${jdbc.url}"
     p:username = "${jdbc.username}"
     p:password = "${jdbc.password}"/>
    <!-- 也可以使用p:mappingDirectoryLocations来指定多个放置Hibernate映入文件的目录 --> 
    <bean id="sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean"
     p:dataSource-ref = "dataSource"
     p:mappingLocations="classpath:org/worm/biz/springmvc/dao/*.hbm.xml">
     <!-- 指定Hibernate配置文件 -->
     <property name="hibernateProperties">
      <props>
       <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
       <prop key="hibernate.show_sql">true</prop>
       <prop key="hibernate.formate_sql">true</prop>
      </props>
     </property> 
    </bean>
    
    <!-- 配置HibernateTemplate Bean -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"
     p:sessionFactory-ref="sessionFactory"/>
    <!-- 配置Hibernate事务管理 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
     p:sessionFactory-ref="sessionFactory"/>
    <tx:annotation-driven transaction-manager="transactionManager"/>
    </beans>

    2.2、使用HibernateTemplate

        基于模板类使用Hibernate是最简单的方式,它可以在不牺牲Hibernate强大功能的情况下,以一种更简洁的方式使用Hibernate,极大地降低了Hibernate的使用难度。

package org.worm.biz.springmvc.dao.hibernate;
import java.util.List;
public interface IBaseDao<T> {
 /**
  * 保存实体对象
  * @param t 实体对象
  * */
 public void addEntity(T t);
 
 /**
  * 更新实体对象
  * @param t 实体对象
  * */
 public  void updateEntity(T t);
 
 /**
  * 获取实体对象
  * @param serialNo 主键
  * */
 public  T getEntity(String serialNo,T t);
 
 /**
  * 获取实体对象集
  * @param hql 查询语句
  * @param params 查询条件
  * */
 public  List<T> getEntities(String hql,Object[] params);
 
 /**
  * 获取实体对象集
  * */
 public  List<T> getEntitiesByExample(T t);
}

package org.worm.biz.springmvc.dao.hibernate;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
public class BaseDao<T> implements IBaseDao<T> {
 private Class entityClass;//Dao的泛型类型,即子类所指定的T所对应的类型
 
 public BaseDao() {
  Type genType = getClass().getGenericSuperclass();
  Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
  entityClass = (Class) params[0];
 }
 @Autowired
 private HibernateTemplate hibernateTemplate;
 public HibernateTemplate getHibernateTemplate() {
  return hibernateTemplate;
 }
 public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
  this.hibernateTemplate = hibernateTemplate;
 }
 
 @Override
 public void addEntity(T t) {
  // TODO Auto-generated method stub
  getHibernateTemplate().save(t);
 }
 @Override
 public  void updateEntity(T t) {
  // TODO Auto-generated method stub
  getHibernateTemplate().update(t);
 }
 @Override
 public  T getEntity(String serialNo) {
  // TODO Auto-generated method stub
  return (T) getHibernateTemplate().get(entityClass, Integer.valueOf(serialNo));
 }
 @Override
 public  List<T> getEntities(String hql, Object[] params) {
  // TODO Auto-generated method stub
  return (List<T>) getHibernateTemplate().find(hql, params);
 }
 @Override
 public  List<T> getEntitiesByExample(T t) {
  // TODO Auto-generated method stub
  return getHibernateTemplate().findByExample(t);
 }
}

package org.worm.biz.springmvc.dao.hibernate;
import org.springframework.stereotype.Repository;
import org.worm.biz.springmvc.dao.User;
@Repository
public class UserDao extends BaseDao<User>{
 //添加自身独有的业务
}

    2.3、使用Hibernate原生Hibernate API

        使用Hibernate原生API与在Spring中使用HibernateTemplate中使用和事务绑定的Session相同

package org.worm.biz.springmvc.dao.hibernate;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.worm.biz.springmvc.dao.User;
public class BaseDao implements IBaseDao<User> {
// @Autowired
// private HibernateTemplate hibernateTemplate;
//
// public HibernateTemplate getHibernateTemplate() {
//  return hibernateTemplate;
// }
//
// public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
//  this.hibernateTemplate = hibernateTemplate;
// }
 @Autowired
 private SessionFactory sessionFactory;
 
 @Override
 public void addEntity(User t) {
  // TODO Auto-generated method stub
//  getHibernateTemplate().save(t);
  sessionFactory.getCurrentSession().save(t);
 }
 @Override
 public  void updateEntity(User t) {
  // TODO Auto-generated method stub
//  getHibernateTemplate().update(t);
  sessionFactory.getCurrentSession().update(t);
 }
 @Override
 public  User getEntity(String serialNo, User t) {
  // TODO Auto-generated method stub
//  return (User) getHibernateTemplate().get(t.getClass(), Integer.valueOf(serialNo));
  return (User) sessionFactory.getCurrentSession().get(t.getClass(), Integer.valueOf(serialNo));
 }
 @Override
 public  List<User> getEntities(String hql, Object[] params) {
  // TODO Auto-generated method stub
//  return (List<User>) getHibernateTemplate().find(hql, params);
  return null;
 }
 @Override
 public  List<User> getEntitiesByExample(User t) {
  // TODO Auto-generated method stub
//  return getHibernateTemplate().findByExample(t);
  return null;
 }
}

    2.4、使用注解配置Entity

package org.worm.biz.springmvc.dao;
import javax.persistence.*;

@Entity
//@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "t_user")
public class User{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_no")
    protected int userId;
    @Column(name = "user_nick_name")
    protected String userName;
    protected String password;
    
    @Column(name = "user_age")
    protected String userAge;
    
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
 public String getUserAge() {
  return userAge;
 }
 public void setUserAge(String userAge) {
  this.userAge = userAge;
 }
    
}

    Hibernate通过AnnotationConfiguration的addAnnotatedClass()方法加载使用JPA注解的实体类,获取映射的元数据信息, 并在此基础上创建SessionFactory实例。AnnotationSessionFactoryBean扩展了LocalSessionFactoryBean类,增强的功能是:可以根据实体类的注解获取ORM的配置信息。也允许混合使用XML配置和注解配置对象关系映射,Hibernate内部自动整合这些元数据信息,不会产生冲突。Spring为了可以通过扫描方式加载带注解的实体类,提供了一个好用的packagesToScan属性,可以指定一系列的包名,Spring将扫描并加载这些包(包含子包)路径的所有带注解实体类。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop" 
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
    
    <context:component-scan base-package="org.worm.biz.springmvc"/>
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
     destroy-method="close"
     p:driverClassName="${jdbc.driverClassName}"
     p:url="${jdbc.url}"
     p:username = "${jdbc.username}"
     p:password = "${jdbc.password}"/>
    <!-- 也可以使用p:mappingDirectoryLocations来指定多个放置Hibernate映入文件的目录 --> 
<!--     <bean id="sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" -->
<!--      p:dataSource-ref = "dataSource" -->
<!--      p:mappingLocations="classpath:org/worm/biz/springmvc/dao/*.hbm.xml"> -->
<!--      <property name="hibernateProperties"> -->
<!--       <props> -->
<!--        <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> -->
<!--        <prop key="hibernate.show_sql">true</prop> -->
<!--        <prop key="hibernate.formate_sql">true</prop> -->
<!--       </props> -->
<!--      </property>  -->
<!--     </bean> -->
    <!-- 带注解实体类 -->
    <bean id="sessionFactory_1" class = "org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
     p:dataSource-ref = "dataSource">
     <!-- 通过扫描方式加载带注解的实体类 -->
     <property name="packagesToScan" value="org.worm.biz.springmvc.dao"/>
     <!-- 指定Hibernate配置文件 -->
     <property name="hibernateProperties">
      <props>
       <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
       <prop key="hibernate.show_sql">true</prop>
       <prop key="hibernate.formate_sql">true</prop>
      </props>
     </property> 
    </bean>
    <!-- 配置HibernateTemplate Bean -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"
     p:sessionFactory-ref="sessionFactory"/>
    <!-- 配置Hibernate事务管理 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
     p:sessionFactory-ref="sessionFactory"/>
    <tx:annotation-driven transaction-manager="transactionManager"/>
    </beans>

    2.5 统一使用事务管理,详情配置请见2.2

3、延迟加载问题

    Hibernate允许对关联对象、属性进行延迟加载,但是必须保证延迟加载的操作限于同一个Hibernate Session范围之内进行。如果Service层返回一个启用了延迟加载功能领域对象给Web层,当Web层访问到那些需要延迟加载的数据时,由于加载领域对象的Hibernate Session已经关闭,将会导致延迟加载数据异常。因此Spring专门提供了一个OpenSessionInViewFilter过滤器,它的主要功能是使每个请求过程中绑定一个Hibernate Session,即使最初的事务已经完成了,可以在Web层进行延迟加载的操作。注意:对小型系统来说,使用OpenSessionInViewFilter确实可以降低延迟加载所引发的各种问题,使Service层代码更易开发和维护,但是对大型且高并发的应用来说,强烈建议不要使用OpenSessionInViewFilter。因为OpenSessionInViewFilter会让每个Web请求线程都绑定一个Hibernate的Session。知道Web请求处理时才会释放。这极大的影响了系统新能。

4、DAO层设计

    为了增加代码复用率,强烈建议使用接口、基类和泛型来定义。详情见2.2.基类BaseDao<T>通过泛型方式允许子类Dao指定操作的实体类,以便简化常用的数据操作方法。同时,在BaseDao注入了一个HibernateTemplate,这样子类只要打上@Repository的注解就自然拥有HibernateTemplate成员变量了,无须各自声明。BaseDao的构造方法通过Java反射机制自动解析出子类T锁对应的类型,以便HibernateTemplate直接利用这个信息进行数据访问操作。

5、查询接口方法的设计

    DAO层除了CRUD的数据操作之外,另外一个重要的操作就是根据查询条件执行数据查询,所有ORM框架都允许用户动态绑定参数确定查询条件。查询条件的数目往往是不固定的。因此实体DAO定义带参数的查询方法一般有:

6、总结

    Spring为其所支持的ORM框架提供了方面易用的FactoryBean,用以创建ORM框架的基础设施。Spring通过模板类在不损失框架功能的情况下大大降低了使用这些ORM技术的难度。此外Spring允许用户使用原生的API来构造DAO。使用原生API时,Spring能够保证用户获取到事务绑定的资源,Spring的事务管理机制同样有效。

    Spring对Hibernate所提供的支持应该是最丰富的。

推荐阅读:
  1. spring整合PC蛋蛋系统研发springmvc和hibernate
  2. ORM 规范

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring hibernate mvc

上一篇:Real-Rime Rendering (4) - 基于图像的绘制(Image-Based Effects)

下一篇:使用缓存问题

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》