[Spring] - Spring + Hibernate

Spring整合Hibernate,花了很长时间研究,其中碰到的比较多问题。

使用的是Spring3.0+Hibernate4.1.6,Spring整合最新版本的Hibernate4.5,会抛些奇奇怪怪的异常。这个官网有说明。

先上代码。

spring的xml配置:springContext.xml

<?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: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-2.5.xsd
                     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://127.0.0.1/test" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                <value>com.my.entity</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
                hibernate.hbm2ddl.auto=update
                hibernate.show_sql=true
                hibernate.format_sql=false
                hibernate.cache.use_second_level_cache=true
                hibernate.cache.use_query_cache=false
                hibernate.cache.provider_class=org.hibernate.cache.internal.NoCacheProvider
                hibernate.current_session_context_class= org.springframework.orm.hibernate4.SpringSessionContext
            </value>
        </property>
    </bean>
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <context:component-scan base-package="com.my" />

    <tx:annotation-driven transaction-manager="txManager" />
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="*" read-only="true"/>
            <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="create*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
      <aop:pointcut id="allServiceMethods" expression="execution(* com.my.service.*.*(..))"/>
      <aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethods"/>
    </aop:config>

</beans>

逐一解释下这个XML,这是最关键的地方:

1、dataSource,这里所使用的是spring自带的org.springframework.jdbc.datasource.DriverManagerDataSource,但这个一般用于个人开发或非并发小项目是可以的,如果用于大型的项目,需要把它替换使用proxool。proxool与spring配置,可以网上搜索下。

2、sessionFactory,里头有个property值为packagesToScan,应该是hibernate所使用的annotation object(即POJO)。使用这个packagesToScan,会自动扫描代码,无需一个个写了。

3、txManager,这是transation管理bean,意思是把声明一个transation bean,以待注入。

4、<context:component-scan base-package="com.my" />,这句是spring使用annotation做注入,基于com.my的命名空间下的所有包和类扫描

5、<tx:annotation-driven transaction-manager="txManager" />,声明一个annotation的transation,让AOP使用。

6、txAdvice,声明一个spring AOP的advice,其意思是内容中定义的attributes对应的方法是否需要开启或禁用transation,以及rollback条件。

7、<aop:config/>是spring的AOP,将txAdvice切入到对应的pointcut中。

补充:

因为测试时使用的是MySql,在测试transation时,发现怎么也不能回滚。原来是MySql数据库要把表引擎修改为InnoDB类型才支持事务。之前使用的是绿色版的MySql,设置了很久也没设置成功,最后去官网下了个安装版的5.7版本,装上默就是InnoDB。-_-#

贴代码:

DAO:

package com.my.dao;

import javax.annotation.Resource;

import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;

import com.my.entity.Account;

@Repository
public abstract class AccountDaoFactory {
    @Resource
    private SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    /*
     * Fin account by id
     */
    public abstract Integer findAccount(Integer accountID);

    /*
     * Add account
     */
    public abstract Account add(String name);

    /*
     * Delete account
     */
    public abstract boolean delete(long id);
}
package com.my.dao.mysql;

import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.stereotype.Repository;

import com.my.entity.Account;

@Repository(value = "accountDao")
public class AccountDao extends com.my.dao.AccountDaoFactory {
    /*
     * Find account by account id
     */
    @Override
    public Integer findAccount(Integer accountID) {
        return accountID;
    }

    @Override
    public Account add(String name) {
        Session session = super.getSessionFactory().getCurrentSession();

        Account account = new Account();
        account.setName(name);
        session.save(account);

        Query query = session.createQuery("FROM Account AS A ORDER BY A.id DESC");
        query.setMaxResults(1);
        account = (Account) query.uniqueResult();
        return account;
    }

    @Override
    public boolean delete(long id) {
        Session session = super.getSessionFactory().getCurrentSession();
        Account account = (Account) session.get(Account.class, id);
        session.delete(account);
        return true;
    }
}

Service:

package com.my.service;

import javax.annotation.Resource;

import com.my.dao.AccountDaoFactory;
import com.my.entity.Account;

public abstract class AccountServiceFactory {
    @Resource(name="accountDao")
    protected AccountDaoFactory accountDao;

    public AccountDaoFactory getAccountDAO() {
        return accountDao;
    }

    public void setAccountDAO(AccountDaoFactory accountDAO) {
        this.accountDao = accountDAO;
    }

    /*
     * Find account by id
     */
    public abstract Integer findAccount(Integer accountID);

    /*
     * Add account
     */
    public abstract Account add(String name);

    /*
     * Delete account
     */
    public abstract boolean delete(long id);

    /*
     * Add and Delete account, transaction test.
     */
    public abstract boolean addAndDelete(String name);
}
package com.my.service.mysql;

import org.springframework.stereotype.Service;

import com.my.entity.Account;
import com.my.service.AccountServiceFactory;

@Service(value="accountService")
public class AccountService extends AccountServiceFactory {

    @Override
    public Integer findAccount(Integer accountID) {
        return accountDao.findAccount(accountID);
    }

    @Override
    public Account add(String name) {
        return accountDao.add(name);
    }

    @Override
    public boolean delete(long id) {
        return accountDao.delete(id);
    }

    @Override
    public boolean addAndDelete(String name) {
        Account account = accountDao.add(name);
        boolean result = accountDao.delete(account.getId());
        return result;
    }

}

Controller:

package com.my.controller;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;

import com.my.entity.Account;
import com.my.service.AccountServiceFactory;

@Controller
public class SpringController {
    @Resource(name="accountService")
    private AccountServiceFactory accountService;

    public AccountServiceFactory getAccount() {
        return accountService;
    }

    public void setAccount(AccountServiceFactory account) {
        this.accountService = account;
    }

    public Integer findAccount(Integer accountID){
        return accountService.findAccount(accountID);
    }

    public Account add(String name){
        return accountService.add(name);
    }

    public boolean delete(long id){
        return accountService.delete(id);
    }

    public boolean addAndDelete(String name){
        return accountService.addAndDelete(name);
    }
}

POJO entity:

package com.my.entity;

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

@Entity
@Table(name = "account")
public class Account {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    @Column(name = "name", length = 200)
    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;
    }
}

JUnit测试:

package com.my.controller;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringControllerTest {
    private SpringController springController;
    private ApplicationContext context;

    @Before
    public void setUp() throws Exception {
        context = new ClassPathXmlApplicationContext("springContext.xml");
        // Use class load
        springController = (SpringController)context.getBean(SpringController.class);
    }

    @Test
    public void testFindAccount() {
        String name = "Robin";
        boolean result = springController.addAndDelete(name);
        assertTrue(result);
    }

}

输出结果:



项目结构:

Spring所需要用到的Jar包:

Hibernate4.1.6所需要用到的Jar包:

时间: 2024-10-09 02:48:50

[Spring] - Spring + Hibernate的相关文章

spring和hibernate整合时报sessionFactory无法获取默认Bean Validation factory

Hibernate 3.6以上版本在用junit测试时会提示错误: Unable to get the default Bean Validation factory spring和hibernate整合时报sessionFactory无法获取默认Bean Validation factory  ,是因为新版hibernate用到新的jar包造成的,默认会自动找验证包,吴国不需要这一步,可以在spring整合hibernate的配置节点中添加如下标红属性: <bean id="sessio

使用Maven 整合Spring和hibernate 适合初级接触的学者

本文,主要介绍Spring 和 hibernate怎么去整合,废话就不多说了,如果不知道spring 和hibernate 是干嘛的,还请去问问度娘哈.下面开始一步一步搭建: 工具: Idea 一.先搭建Spring 1.新建一个maven项目:至于填写项目名称什么的就不一一介绍了 这里我的idea没有自动生成test文件夹,需要大家自己建一下,之后的项目目录如下图所示: 2.下面我贴出项目的Pom文件: <project xmlns="http://maven.apache.org/PO

Spring与Hibernate整合,实现Hibernate事务管理

1.所需的jar包 连接池/数据库驱动包 Hibernate相关jar Spring 核心包(5个) Spring aop 包(4个) spring-orm-3.2.5.RELEASE.jar                 [spring对hibernate的支持] spring-tx-3.2.5.RELEASE.jar                     [事务相关] 2.配置文件 Product.hbm.xml <?xml version="1.0" encoding=

Spring对Hibernate事务管理【转】

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

spring配置hibernate的sessionFactory的几种方法

分类: JAVA Spring Hibernate 2013-01-27 20:47  1851人阅读  评论(0)  收藏  举报 spring配置hibernate的sessionFactory 之前用spring2+hibernate3+struts2开发了一个彩信发布系统,由于第一次使用此架构,造成applicationContext.xml中的配置非常冗长,而且经常因为更改一个小配置项(例:数据库ip.用户名.密码等)将此文件作修改,这及不利于项目维护,万一粗心造成其他地方变动,会对本

Spring+Struts2/Hibernate 学习笔记

=========自动装配========= autowire - 指定自动装配策略 byName 如果是byName的自动装配策略,Spring会负责把setter方法名对应 的Bean注入 如果没有找到,就不执行注入(即不调用这个setter方法) byType Spring会负责把容器类型为setter方法形参类型的Bean注入进来 如果没有找到,就不执行注入(即不调用这个setter方法) 如果找到了多个Bean,那就报错了,出现异常 autowire-candidate-true/fa

菜鸟学习Spring——60s学会Spring与Hibernate的集成

一.概述. Spring与Hibernate的集成在企业应用中是很常用的做法通过Spring和Hibernate的结合能提高我们代码的灵活性和开发效率,下面我就一步一步的给大家讲述Spring如何和Hibernate集成的. 二.代码演示. 导入Hibernate的jar包 Hibernate-3.2/lib/*.jar Hibernate-3.2/hibernate3.jar 还有导入Spring的相关jar包 我用的数据库是MySql所以要导入MySql的驱动jar包: mysql-conn

Spring MVC + Hibernate + Maven: Crud操作示例

Alexey是一个在使用Java,TestNG 和Selenium的自动化WEB应用程序中有丰富经验的测试开发者.他如此的喜欢QA以至于在下班后他为初级QA工程师提供培训课程. 在这篇文章中我想介绍一个Spring MVC + Hibernate + Maven例子.这组技术主要涉及一些基础知识,我想在每一个必要的地方详细解释它.本篇话题范围以外的更多资源,我会提供链接方便你阅读.在文章的最后,我将发布一个GitHub的链接. 目标 示例web应用程序是基于Spring MVC, Hiberna

spring mvc+hibernate的基本配置

<?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&

SpringMVC学习系列(12) 完结篇 之 基于Hibernate+Spring+Spring MVC+Bootstrap的管理系统实现

到这里已经写到第12篇了,前11篇基本上把Spring MVC主要的内容都讲了,现在就直接上一个项目吧,希望能对有需要的朋友有一些帮助. 一.首先看一下项目结构: InfrastructureProjects:是抽取出的基础项目,主要封装了一些通用的操作. SpringMVC3Demo:就是管理系统所在的项目. WeiXinAPI:是之前做微信管理平台测试时封装一些操作,如果不需要把该项目移除即可. 注:项目的前端UI框架用的是国外的一个基于Bootstrap框架的开发的Demo,如不需要替换为