spring结合hibernate示例详解

单纯Hibernate程序

1、首先是导入hibernate的jar包。

2、 建立用户和用户操作记录实体,Log.Java和User.java。代码如下所示。

Log.java

import java.util.Date;
public class Log {
  private int id;
  //日志的类别.日志一般起到一个不可否认性.
  //操作日志 安全日志 事件日志.
  private String type;
  private String detail;
  private Date time;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getType() {
    return type;
  }
  public void setType(String type) {
    this.type = type;
  }
  public String getDetail() {
    return detail;
  }
  public void setDetail(String detail) {
    this.detail = detail;
  }
  public Date getTime() {
    return time;
  }
  public void setTime(Date time) {
    this.time = time;
  }
} 

User.java

public class User {
  private int id;
  private String name;
  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;
  }
} 

3、 并建立与之对应的实体配置文件,Log.hbm.xml和Use.hbm.xml。代码如下所示。

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="com.bjpowernode.usermgr.domain.User" table="t_user">
    <id name="id" >
      <generator class="native"/>
    </id>
    <property name="name" />
  </class>
</hibernate-mapping> 

Log.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="com.bjpowernode.usermgr.domain.Log" table="t_log">
    <id name="id" >
      <generator class="native"/>
    </id>
    <property name="type" />
    <property name="detail" />
    <property name="time" />
  </class>
</hibernate-mapping> 

4、Manager层代码如下所示。

LogManager.java接口

public interface LogManager {
  //添加日志.方法
  public void addLog(Log log);
} 

LogManagerImpl实现

public class LogManagerImpl implements LogManager {
  @Override
  public void addLog(Log log) {
    HibernateUtils.getSessionFactory().getCurrentSession().save(log); 

  }
}

UserManager接口

public interface UserManager { 

  public void addUser(User user);
} 

UserManagerImpl.java实现

public class UserManagerImpl implements UserManager {
  @Override
  public void addUser(User user) {
    Session session = null;
    try {
      //这个session中是放到threadlocal.
      session = HibernateUtils.getSessionFactory().getCurrentSession();
      session.beginTransaction();
      // 网用户表中添加一条同时网日志中添加一条.
      session.save(user);
      Log log = new Log();
      log.setType("操作日志");
      log.setTime(new Date());
      log.setDetail("xxx");
      LogManager logManager = new LogManagerImpl();
      //添加日志.
      logManager.addLog(log);
      session.getTransaction().commit();
    } catch (Exception e) {
      e.printStackTrace();
      session.getTransaction().rollback();
    }finally{
      HibernateUtils.closeSession(session);
    }
  }
} 

5、是通过sessionFactory来创建session,通过session来开启提交和关闭回滚事务,我们把session的开启关闭封装到一个工具类中。HibernateUtils.java代码如下所示。

public class HibernateUtils {
  private static SessionFactory factory;
  static {
    try {
      //读取hibernate.cfg.xml文件
      Configuration cfg = new Configuration().configure();
      //建立SessionFactory
      factory = cfg.buildSessionFactory();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
  public static Session getSession() {
    return factory.openSession();
  }
  public static void closeSession(Session session) {
    if (session != null) {
      if (session.isOpen()) {
        session.close();
      }
    }
  }
  public static SessionFactory getSessionFactory() {
    return factory;
  }
} 

6、配置hibernate.cfg.xml文件,包括数据库名称,数据库关联的表,以及用户名密码等。代码如下所示。

<hibernate-configuration>
  <session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/spring_hibernate_1</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <!--
    <property name="hibernate.current_session_context_class">jta</property>
    -->
    <mapping resource="com/bjpowernode/usermgr/domain/User.hbm.xml"/>
    <mapping resource="com/bjpowernode/usermgr/domain/Log.hbm.xml"/>
  </session-factory>
</hibernate-configuration> 

7、 使用junit进行单元测试,代码如下所示。

import junit.framework.TestCase;
public class UserManagerImplTest extends TestCase {
  public void testAddUser() {
    UserManager userManager = new UserManagerImpl();
    User user = new User();
    user.setName("张三");
    userManager.addUser(user);
  }
} 

在上述操作用,对事物的控制边界在业务逻辑层,因为在UserManagerImpl中我们调用addUser()这一方法的同时要把这一操作写入到日志中,也就是调用了addLog()方法,而对于类的方法,一方法一session,一session一事务,那么如果控制事务的呢?我们要执行开启addUser()事务同时再开启addLog()事务吗?在这里我们没有再用以前的openSession方法,选择用的HibernateUtils.getSessionFactory().getCurrentSession();同时在hibernate.cfg.xml中对getCurrentSession()进行配置如下,       <propertyname="hibernate.current_session_context_class">thread</property>表示在当前线程中,与当前线程绑定这样执行addUser()方法和addLog()方法使用的是同一个事务。

那OpenSession和getCurrentSession的区别呢?

1、          openSession必须关闭,currentSession在事务结束后自动关闭。

2、          openSession没有和当前线程绑定,currentSession和当前线程绑定。并且使用currentSession需要在我们的hibernate.cfg.xml文件中进行事务的配置,是使用Jdbc事务还是JTA事务。

hibernate和spring结合使用

我们从上述例子中发现,hibernate的事务是独立于hibernate对数据库的增删改查的,并且事务控制在我们的业务逻辑层,对于独立的东西,像是横切性问题,自然想到了AOP,实际上SpringAOP封装了对事务的管理,使用SpringAOP我们不再负责去开启和关闭事务。

下面用SpringAOP来和hibernate结合。

当然也要导入Spring相关jar。

对于事务管理就是一个横切性问题,把事务管理模块化就是我们的aspect,然后再配置文件中进行配置,我们可以把事务单独放到一个配置文件中。

1、代码如下,applicationContext-common.xml文件。

<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     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-2.0.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  <!-- 配置SessionFactoyr -->
  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation">
      <value>classpath:hibernate.cfg.xml</value>
    </property>
  </bean>
  <!-- 配置事务管理器 -->
  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
      <ref bean="sessionFactory"/>
    </property>
  </bean>
<!-- 哪些类哪些方法使用事务. -->
<aop:config>
  <aop:pointcut id="allManagerMethod" expression="execution(* com.bjpowernode.usermgr.manager.*.*(..))"/>
  <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
    <tx:method name="add*" propagation="REQUIRED"/>
    <tx:method name="del*" propagation="REQUIRED"/>
    <tx:method name="modify*" propagation="REQUIRED"/>
    <tx:method name="*" propagation="REQUIRED" read-only="true"/>
  </tx:attributes>
</tx:advice>
</beans> 

首先是配置的是sessionFactory,让spring拿到hibernate的sessionFactory,以便对hibernate事务控制,通过sessionFactory产生session再访问。这样就把把hibernate的sessionFactory注入到Spring中了。通过<property>标签,告诉SpringHibernate的配置文件在哪里,以便spring可以读取hibernate的配置文件。
其次是配置事务管理器,把我们的sessionFactory注入给事务管理器,让事务管理器管理事务。

其次,到底是哪些类哪些方法,开始执行的时候执行事务,<aop:pointcutid="allManagerMethod"  

其次,配置AOP,expression="execution(*com.bjpowernode.usermgr.manager.*.*(..))",到底是哪些类交给spring完成事务管理?我们应用在所有的manager包中的所有方法上,manager所有类所有方法全部参与事务的运行。那在什么地方触发开启事务?

再次,定义一个Advice,配置事务的传播特性,例如addUser()中调用addLog()方法,是在同一个事务还是不在同一个事务。以add开头,del开头,modify开头以及其他,我们配置的事务传播特性为propagation="REQUIRED",这样在一个方法中调用另一个方法他们公共一个线程。

2、让UserManagerImpl继承spring提供的对hibernateDao支持类。

HibernateDaoSupport,这样继承之后我们就能拿到session,其实也就是hibernate中的session,只不过spring为我们封装了。我们可以这样拿到sesion:This.getSession().save(user);或者使用spring封装好的对象:

This.getHibernateTemplate().save(user);这样都封装到里面了,我们不管理事务的开启和关闭。

之前在我们的UserManagerImpl中使用了LogManagerImpl实例,这次我们可以使用Spring的IOC容器,把他们之间的依赖关系注入到Spring中,这样就看不到实例,面对接口编程,进行了解耦。

接口不变,UserManagerImpl.java代码如下所示。

public class UserManagerImpl extends HibernateDaoSupport implements UserManager {
  private LogManager logManager;
  public void setLogManager(LogManager logManager)
  {
    this.logManager = logManager;
  }
  @Override
  public void addUser(User user)throws Exception {
    //this.getSession().save(user);
        //或者用.
        this.getHibernateTemplate().save(user);
        Log log = new Log();
        log.setType("操作日志");
        log.setTime(new Date());
        log.setDetail("xxx");
        //LogManager logManager = new LogManagerImpl();
        //添加日志.
        logManager.addLog(log);
        //运行期的异常,会回滚. 并且是他的子类也会回滚.
        //throw new RuntimeException();
        //throw new Exception();
  }
} 

LogManagerImpl.java 代码如下所示。

public class LogManagerImpl extends HibernateDaoSupport implements LogManager {
  @Override
  public void addLog(Log log) {
    //getSession().save(log);
    this.getHibernateTemplate().save(log); 

  }
} 

删除我们自己建立的HibernateUtils.java类,删除hibernate.cfg.xml文件中对getCurrentSession()的事务配置。

3、在配置文件中配置依赖关系。

applicationContext-beans.xml代码如下所示。

<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     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-2.0.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  <bean id="userManager" class="com.bjpowernode.usermgr.manager.UserManagerImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="logManager" ref="logManager"/>
  </bean>
  <bean id="logManager" class="com.bjpowernode.usermgr.manager.LogManagerImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>
</beans> 

在Junit中测试程序代码如下所示。

public class UserManagerImplTest extends TestCase {
  public void testAddUser() {
    BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext-*.xml");
    UserManager userManager = (UserManager) factory.getBean("userManager");
    User user = new User();
    user.setName("张三");
    try {
      userManager.addUser(user);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
} 

显示结果如下图所示。

这样就完成了spring和hibernate的结合,主要是利用SpringAOP对hibernate的事务进行控制和在Manager层之间的调用用Spring IOC进行控制。

总结

以上所述是小编给大家介绍的spring结合hibernate示例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Spring Boot + Jpa(Hibernate) 架构基本配置详解

    1.基于springboot-1.4.0.RELEASE版本测试 2.springBoot + hibernate + Druid + MySQL + servlet(jsp) 不废话,直接上代码 一.maven的pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&qu

  • Java框架篇:Spring+SpringMVC+hibernate整合开发

    前言: 最近没什么事做,搭个框架写成博客记录下来,拉通一下之前所学知识. 话不多说,我们直接步入正题. 准备工作: 1/安装并配置java运行环境 2/数据库的安装配置(Mysql) 3/安装并配置服务器(Tomcat) 4/Maven 5/ IntelliJIDEA的安装配置(本人使用的主要软件是IntelliJIDEA,没用eclipse什么的) 6/ 使用IntelliJIDEA创建一个web app项目. 貌似就这些了吧 导包 不同于以往的导包,由于我们创建的是maven的webapp项

  • Spring4整合Hibernate5详细步骤

    Spring与Hiberante整合 通过hibernate的学习,我们知道,hibernate主要在hibernate.cfg.xml配置文件中 接下来我们看一下hibernate的一个配置文件 hibernate配置文件 hibernate.cfg.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibern

  • springmvc4+hibernate4分页查询功能实现

    Springmvc+hibernate成为现在很多人用的框架整合,最近自己也在学习摸索,由于我们在开发项目中很多项目都用到列表分页功能,在此参考网上一些资料,以springmvc4+hibnerate4边学边总结,得出分页功能代码,虽然不一定通用,对于初学者来说有参考价值. 分页实现的基本过程: 一.分页工具类 思路: 1.编写Page类,定义属性,应该包括:查询结果集合.查询记录总数.每页显示记录数.当前第几页等属性. 2.编写Page类,定义方法,应该包括:总页数.当前页开始记录.首页.下一

  • Spring 整合 Hibernate 时启用二级缓存实例详解

    Spring 整合 Hibernate 时启用二级缓存实例详解 写在前面: 1. 本例使用 Hibernate3 + Spring3: 2. 本例的查询使用了 HibernateTemplate: 1. 导入 ehcache-x.x.x.jar 包: 2. 在 applicationContext.xml 文件中找到 sessionFactory 相应的配置信息并在设置 hibernateProperties 中添加如下代码: <!-- 配置使用查询缓存 --> <prop key=&q

  • Spring与Hibernate整合事务管理的理解

    在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据操作,然后提交事务,关闭事务,我们这样做的原因是因为Hibernate默认的事务自动提交是false,他是需要我们人为的手动提交事务,假如你不想每次都手动提交事务的话,你可以在hibernate.cfg.xml我文件中把它设置为事务自动提交: xml代码 <property name="def

  • spring结合hibernate示例详解

    单纯Hibernate程序 1.首先是导入hibernate的jar包. 2. 建立用户和用户操作记录实体,Log.Java和User.java.代码如下所示. Log.java import java.util.Date; public class Log { private int id; //日志的类别.日志一般起到一个不可否认性. //操作日志 安全日志 事件日志. private String type; private String detail; private Date time

  • Spring 缓存抽象示例详解

    Spring缓存抽象概述 Spring框架自身并没有实现缓存解决方案,但是从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,提供对缓存功能的声明,能够与多种流行的缓存实现集成. Cache接口为缓存的组件规范定义,包含缓存的各种操作集合: Cache接口下Spring提供了各种xxxCache的实现:如RedisCache,EhCacheCache , ConcurrentMapCa

  • Spring @value用法示例详解

    目录 一.两种使用方法 二.配置 2.1 @Value(“#{configProperties[‘key’]}”)使用 2.1.1配置文件: 2.2 @Value(“${key}”)使用 2.2.1 配置文件 为了简化读取properties文件中的配置值,spring支持@value注解的方式来获取,这种方式大大简化了项目配置,提高业务中的灵活性. 一.两种使用方法 1.@Value(“#{configProperties[‘key’]}”) 2.@Value(“${key}”) 二.配置 2

  • Shiro集成Spring之注解示例详解

    前言 Shiro的组件都是JavaBean/POJO式的组件,所以非常容易使用Spring进行组件管理,可以非常方便的从ini配置迁移到Spring进行管理,且支持JavaSE应用及Web应用的集成. 集成 Spring 后我们通过过滤器链来配置每个 URL 需要的权限,但当配置多了以后就会不方便,而且只支持 URL 级别的配置. 好在 Shiro 提供了相应的注解用于权限控制,此处使用了 Spring MVC 来测试Shiro注解,当然 Shiro 注解不仅仅可以在 web 环境使用,在独立的

  • Spring JPA find分页示例详解

    目录 前言 源码 一.单纯分页查询 查询结果 结论 二.排序分页查询 查询结果 三.方法整理 总结: 前言 在现实项目中,数据量一般都不小,如果一次性全部请求出来,肯定是影响性能,而且大量数据展示到页面上观感也不好.这时我们就需要用到分页,给定一个 pageSize,每次请求的数量就是 pageSize 的大小,这样既可以节约时间,又可以美化页面.Spring JPA 就为我们提供这样一个方法,准确来说是提供了一个对象用来约束数据按照分页的形式进行请求. 源码 findAll(Pageable

  • 基于spring boot 1.5.4 集成 jpa+hibernate+jdbcTemplate(详解)

    1.pom添加依赖 <!-- spring data jpa,会注入tomcat jdbc pool/hibernate等 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <

  • Spring依赖注入(DI)两种方式的示例详解

    目录 一.依赖注入方式 二.setter注入 引用类型 简单类型 三.构造器注入 引用类型 简单类型 参数适配(了解) 四.依赖注入方式选择 一.依赖注入方式 思考:向一个类中传递数据的方式有几种? 普通方法(set方法) 构造方法 思考:依赖注入描述了在容器中建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串呢? 引用类型 简单类型(基本数据类型与String) 依赖注入方式: setter注入 简单类型 引用类型 构造器注入 简单类型 引用类型 二.setter注

  • Spring AOP事务管理的示例详解

    目录 转账案例-环境搭建 步骤1:准备数据库表 步骤2:创建项目导入jar包 步骤3:根据表创建模型类 步骤4:创建Dao接口 步骤5:创建Service接口和实现类 步骤6:添加jdbc.properties文件 步骤7:创建JdbcConfig配置类 步骤8:创建MybatisConfig配置类 步骤9:创建SpringConfig配置类 步骤10:编写测试类 事务管理 转账案例-环境搭建 步骤1:准备数据库表 之前我们在整合Mybatis的时候已经创建了这个表,可以直接使用 create

  • Spring Cloud动态配置刷新RefreshScope使用示例详解

    目录 引言 一.了解@RefreshScope,先要了解@Scope 二.RefreshScope 的实现原理 三.使用——@RefreshScope 使用流程 引言 用过Spring Cloud的同学都知道在使用动态配置刷新的我们要配置一个 @RefreshScope,在类上才可以实现对象属性的的动态更新. @RefreshScope 能实现动态刷新全仰仗着 @Scope这个注解. 一.了解@RefreshScope,先要了解@Scope 1.RefreshScope继承于GenericSco

  • Spring实现泛型注入的示例详解

    目录 1.Spring泛型注入 2. 关于java泛型有四种Type GenericArrayType泛型数组类型 ParameterizedType参数化类型 TypeVariable 类型变量 WildcardType 通配符类型 1.Spring泛型注入 创建一个抽象泛型类BaseDao,有参数化类型T public abstract class BaseDao<T> { public abstract void eat(); } 每种动物有不同的行为,猫.狗 public class

随机推荐