最近整合Spring3 和Hibernate 4的总结

本文介绍了如何将Spring框架与Hibernate整合,实现数据持久化的配置与应用。包括Hibernate配置文件详解、Spring配置说明、实体类映射及事务管理等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近写毕设的实验,就顺便把hibernate和spring配了一下,记录下来以后可能有用的到


Hibernate 配置

      Hibernate.cfg.xml文件在intellij中配置数据源之后生成

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/weibo_test</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">62050218</property>

        <!-- Hibernate setting -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.autocommit">true</property>
        <property name="javax.persistence.validation.mode">none</property>

        <!-- c3p0 setting -->
        <property name="hibernate.connection.provider_class">
            org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider
        </property>
        <property name="hibernate.c3p0.min_size">5</property>
        <property name="hibernate.c3p0.max_size">20</property>
        <property name="hibernate.c3p0.timeout">300</property>
        <property name="hibernate.c3p0.max_statements">50</property>
        <property name="hibernate.c3p0.idle_test_period">3000</property>
        <mapping class="org.mt.persistence.entity.CourseEntity"/>
        <mapping class="org.mt.persistence.entity.StudentEntity"/>
        <mapping class="org.mt.persistence.entity.StudentHasCourseEntity"/>


        <!-- DB schema will be updated if needed -->
        <!-- <property name="hbm2ddl.auto">update</property> -->
    </session-factory>
</hibernate-configuration>
其中第一部分是数据源配置,第二部分是hibernate方言和自动提交等的配置,第三部分是c3P0数据源连接池的配置,之前本来是没有配这部分的,但是后来发现如果不在spring中直接配置数据源,而是继续使用hibernate配置文件的话,必须使用连接池才可以。c3p0配置下面的一部分是数据库实体配置,先通过mysql workbench 画ER图生成sql,再通过数据库逆向生成实体类还是比较方便的。


Spring 配置

      spring-config.xml文件通过intellij自动生成

<?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:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="org.mt.persistence.dao"/>

    <bean id="sessionFactory"
          class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
    </bean>

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

配置文件中sessionFactory通过配置文件引用hibernate的配置,componet-scan 配置了@Repository注解会扫描的包,使用了这个注解的bean不用在xml中配置就会自动被扫描为bean,bean id就是类名首字母小写。最后两段配置了spring中的transactionManager用于管理Hibernate事务,不然@Transactional注解无法用

@Repository
public class StudentDaoImp implements StudentDao{

    private SessionFactory sessionFactory;

    @Autowired
    public StudentDaoImp(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    private Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Transactional
    @Override
    public void addStudent(StudentEntity student) {
        getCurrentSession().save(student);
    }

    @Transactional
    @Override
    public StudentEntity loadStudent(Integer studentID) {
        return (StudentEntity) getCurrentSession().get(StudentEntity.class, studentID);
    }

    @Transactional
    @Override
    public void updateStudent(StudentEntity student) {
        getCurrentSession().update(student);
    }
}

一个简单的利用@Repository 和@Transactional注解例子,通过这种方法定义bean必须定义接口,然后通过接口来调用spring 中的bean,这个倒是和spring一直崇尚的面向接口编程比较接近。@Autowired 是spring中的自动装配,@Transactional 在方法调用的时候都伴随着一个事务的开始与结束,结合hibernate3之后提供的线程绑定的currentSession,可以取代以前所用的HibernateTemplate。关于这几种注解的详细用法后面应该还是会花时间专门研究一下。


在整个实验的过程中,通过数据库反向生成实体的时候。多对多的关系生成的实体在实验过程中总是会报重复列的错误。

@javax.persistence.IdClass(org.mt.persistence.entity.StudentHasCourseEntityPK.class)
@javax.persistence.Table(name = "student_has_course", schema = "", catalog = "weibo_test")
@Entity
public class StudentHasCourseEntity {
    private int studentId;
    private int courseId;
    private StudentEntity studentByStudentId;
    private CourseEntity courseByCourseId;

    @javax.persistence.Column(name = "student_id", nullable = false, insertable = true, updatable = true, length = 10, precision = 0)
    @Id
    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }

    @javax.persistence.Column(name = "course_id", nullable = false, insertable = true, updatable = true, length = 10, precision = 0)
    @Id
    public int getCourseId() {
        return courseId;
    }

    public void setCourseId(int courseId) {
        this.courseId = courseId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        StudentHasCourseEntity that = (StudentHasCourseEntity) o;

        if (courseId != that.courseId) return false;
        if (studentId != that.studentId) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = studentId;
        result = 31 * result + courseId;
        return result;
    }

    @ManyToOne
    @javax.persistence.JoinColumn(name = "student_id", referencedColumnName = "id", nullable = false,insertable = false,updatable = false)
    public StudentEntity getStudentByStudentId() {
        return studentByStudentId;
    }

    public void setStudentByStudentId(StudentEntity studentByStudentId) {
        this.studentByStudentId = studentByStudentId;
    }

    @ManyToOne
    @javax.persistence.JoinColumn(name = "course_id", referencedColumnName = "id", nullable = false,insertable = false,updatable = false)
    public CourseEntity getCourseByCourseId() {
        return courseByCourseId;
    }

    public void setCourseByCourseId(CourseEntity courseByCourseId) {
        this.courseByCourseId = courseByCourseId;
    }
}

看代码可以发现,多对多关系在数据库中被解析为两个一对多关系,并有一张额外的关系表,表中的两个元素为多对多关系表的ID,两个外键一起作为主键。通过自动生成的话,外键和主键定义重复确实会发生冲突。因此在外键定义中加上 

insertable = false,updatable = false
可以保证插入的时候忽略外键,这里还是有点不清楚,后面还是应该再专门研究一下hibernate的实体配置


最后把项目maven的pom也贴上,免得以后配spring+hibernate的时候又忘了

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.mt</groupId>
    <artifactId>testUser</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <org.springframework.version>3.2.4.RELEASE</org.springframework.version>
        <version.hibernate>4.1.8.Final</version.hibernate>
        <version.hibernate-validator>4.3.1.Final</version.hibernate-validator>
    </properties>

    <dependencies>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>

        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.24</version>
        </dependency>


        <!-- spring 配置 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Expression Language (depends on spring-core) Define this if you use
            Spring Expression APIs (org.springframework.expression.*) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Bean Factory and JavaBeans utilities (depends on spring-core) Define
            this if you use Spring Bean APIs (org.springframework.beans.*) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Aspect Oriented Programming (AOP) Framework (depends on spring-core,
            spring-beans) Define this if you use Spring AOP APIs (org.springframework.aop.*) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Application Context (depends on spring-core, spring-expression, spring-aop,
            spring-beans) This is the central artifact for Spring's Dependency Injection
            Container and is generally always defined -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Various Application Context utilities, including EhCache, JavaMail,
            Quartz, and Freemarker integration Define this if you need any of these integrations -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Transaction Management Abstraction (depends on spring-core, spring-beans,
            spring-aop, spring-context) Define this if you use Spring Transactions or
            DAO Exception Hierarchy (org.springframework.transaction.*/org.springframework.dao.*) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- JDBC Data Access Library (depends on spring-core, spring-beans, spring-context,
            spring-tx) Define this if you use Spring's JdbcTemplate API (org.springframework.jdbc.*) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Object-to-Relation-Mapping (ORM) integration with Hibernate, JPA,
            and iBatis. (depends on spring-core, spring-beans, spring-context, spring-tx)
            Define this if you need ORM (org.springframework.orm.*) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Object-to-XML Mapping (OXM) abstraction and integration with JAXB,
            JiBX, Castor, XStream, and XML Beans. (depends on spring-core, spring-beans,
            spring-context) Define this if you need OXM (org.springframework.oxm.*) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Support for testing Spring applications with tools such as JUnit and
            TestNG This artifact is generally always defined with a 'test' scope for
            the integration testing framework and unit testing stubs -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${org.springframework.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Hibernate 配置 -->

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${version.hibernate}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>${version.hibernate-validator}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator-annotation-processor</artifactId>
            <version>${version.hibernate-validator}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>${version.hibernate}</version>
        </dependency>


    </dependencies>


</project>

另外,spring和hibernate的配置文件在使用maven来构建项目时应该放在maven的resource文件夹下
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值