欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JPA学习 —— 第三课、spring整合JPA (完全版)

程序员文章站 2024-03-14 10:14:04
...

1.配置依赖

    <!--版本控制 -->
    <properties>
        <mysql.version>5.1.34</mysql.version>
        <spring.version>4.3.0.RELEASE</spring.version>
        <hibernate.version>4.1.0.Final</hibernate.version>
        <querydsl.version>4.1.4</querydsl.version>
        <jackson.version>2.5.4</jackson.version>
    </properties>
    <dependencies>
        <!-- javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- Spring Framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- Spring Framework end -->

        <!-- c3p0 start -->
        <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        <!-- c3[0 end -->

        <!--hibernate start -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <!--hibernate end -->

        <!-- cglib start -->
        <!-- https://mvnrepository.com/artifact/cglib/cglib -->
        <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/cglib/cglib -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>
        <!-- cglib end -->

        <!--mysql start -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <!--mysql end -->
        <!--test start -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--test end -->
        <!--common start -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <!--common end -->
    </dependencies>

这里比之前不完全版就是多了事务配置相关依赖

2.配置 applicationContext.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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="com.ssj"></context:component-scan>

    <!-- 配置数据源 -->
    <context:property-placeholder location="classpath:jdbc.properties" />

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <!-- 配置其他属性(省略) -->
    </bean>

    <!-- 配置 JPA 的 EntityManagerFactory -->
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
        </property>
        <property name="packagesToScan" value="com.ssj.domain"></property>
        <property name="jpaProperties">
            <props>
                <!-- 实体类命名规则 hibernate5以下有效-->
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
                <!-- 指定自动生成数据表的策略 -->
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <!-- 执行操作时是否在控制台打印SQL -->
                <prop key="hibernate.show_sql">true</prop>
                <!-- 是否对SQL进行格式化 -->
                <prop key="hibernate.format_sql">true</prop>
                <!-- 方言 -->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>

                 <!-- 其他配置 -->
            </props>
        </property>
    </bean>
    <!-- 配置事务 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"></property>
    </bean>

    <!-- 使用annotation定义事务 -->
    <tx:annotation-driven transaction-manager="transactionManager"
        proxy-target-class="true" />

    <!-- #2通知:增强事务 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="select*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="load*" propagation="SUPPORTS" read-only="true" />
            <!-- 其他采用默认事务方式 -->
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>
    <!-- #3 切面:将切入点与通知点关联 -->
    <aop:config proxy-target-class="true">
        <aop:pointcut expression=" execution(* com.ssj.service..*(..))"
            id="serviceMethod" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />
    </aop:config>

</beans>

这里配置了事务控制,主要是监控service中的方法,通过方法前缀进行匹配。这样开发者就不用再管事务相关的内容了,全交给spring容器进行管理了。

3.实体类

package com.ssj.domain;

import java.util.Date;

import javax.persistence.*;

@Entity
@Table(name="employee")
public class Employee {

    @Column(name="ID")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Id
    private Integer Id;

    @Column(name="EMP_NAME")
    private String empName;

    @Column(name="EMP_BIRTH")
    @Temporal(TemporalType.DATE)
    private Date empBirth;


    public Integer getId() {
        return Id;
    }
    public void setId(Integer id) {
        Id = id;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Date getEmpBirth() {
        return empBirth;
    }
    public void setEmpBirth(Date empBirth) {
        this.empBirth = empBirth;
    }
    @Override
    public String toString() {
        return "Employee [Id=" + Id + ", empName=" + empName + ", empBirth="
                + empBirth + "]";
    }
}

4.dao层

package com.ssj.dao;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;

import com.ssj.domain.Employee;

@Repository
public class EmployeeDao {

    @PersistenceContext
    private EntityManager em;

    public void save(Employee emp){
        em.persist(emp);
    }
}

5.service层

package com.ssj.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ssj.dao.EmployeeDao;
import com.ssj.domain.Employee;

@Service
public class EmployeeService {

    @Autowired
    private EmployeeDao employeeDao;

    public void save(Employee emp){
        employeeDao.save(emp);
    }
}

6.测试类

package com.ssj.test;

import java.util.Date;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.ssj.domain.Employee;
import com.ssj.service.EmployeeService;

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations= "classpath:applicationContext.xml") 
public class Test01 {

    @Autowired
    private EmployeeService employeeService;

    @Test
    public void test1(){
        Employee emp = new Employee();
        emp.setEmpName("李四");
        emp.setEmpBirth(new Date());
        employeeService.save(emp);
    }

}

7.测试结果
JPA学习 —— 第三课、spring整合JPA (完全版)
数据库
JPA学习 —— 第三课、spring整合JPA (完全版)

总结:这里比之前不完全版就多了个事务的配置,将事务控制交给spring容器管理,开发者就不用关注事务相关内容。
开发时直接注入使用EntityManage,而不用再通过工厂方法获取。
@PersistenceContext
private EntityManager em;

注:之前用的hibernate5,但是有个配置是只在5以下才有效,所以改成了hibernate4

<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>

命名规范的设置在hibernate5中改了,这里就不详细说了,有兴趣的朋友可以自己去研究下。
注:之前配置hibernate方言使用的是org.hibernate.dialect.MySQLMyISAMDialect就是告诉MySQL数据库使用MyISAM引擎。但是使用这个引擎创建的数据表总是生成不了外键,查了一些资料才知道:
MyISAM类型不支持事务处理和外键等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外键等高级数据库功能。
所以后来就改为了使用InnoDB

<!-- 方言 -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>

但是使用这个又出现个问题,新建表失败。
原来是我的MySql数据库美誉开启InnoDB的缘故。
开启方法:
修改MySQL安装目录下的my.ini,在skip-innodb前增加#,重启MySQL即可。
重启:
Windows
  1.点击“开始”->“运行”(快捷键Win+R),cmd。
  2.停止:输入 net stop mysql
3.启动:输入 net start mysql

相关标签: jpa