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

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.测试结果
这里写图片描述
数据库
这里写图片描述

总结:这里比之前不完全版就多了个事务的配置,将事务控制交给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

猜你喜欢

转载自blog.csdn.net/abc997995674/article/details/80213531