拓展阅读
Spring Data JPA
Spring Data JPA,作为更大的 Spring Data 家族的一部分,使得基于 JPA 的仓库实现变得更加容易。
该模块提供了对基于 JPA 的数据访问层的增强支持。
它使得构建使用数据访问技术的、由 Spring 驱动的应用程序变得更加容易。
ps: spring data 太大了,就从 jpa 一个点入手。学习运用并了解其设计思想。
Hello World
spring-data-jpa(java-persist-api )默认使用 Hibernate 作为实现。
项目结构
├── spring-data-jpa
│ ├── pom.xml
│ ├── src
│ │ ├── main
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ └── ryo
│ │ │ │ └── spring
│ │ │ │ └── data
│ │ │ │ └── jpa
│ │ │ │ ├── dao
│ │ │ │ │ ├── EmployeeDAO.java
│ │ │ │ │ └── EmployeeDAOImpl.java
│ │ │ │ ├── model
│ │ │ │ │ └── Employee.java
│ │ │ └── resources
│ │ │ ├── jdbc.properties
│ │ │ ├── spring
│ │ │ │ └── applicationContext-datasource.xml
│ │ │ └── sql
│ │ │ └── init.sql
│ │ └── test
│ │ └── java
│ │ └── SpringDataJPATest.java
属性及配置文件
- pom.xml
<?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">
<parent>
<artifactId>spring-data</artifactId>
<groupId>com.ryo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-data-jpa</artifactId>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>1.1.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
- init.sql
测试时建立的数据库为 spring_data
。
脚本用于新建表,内容如下:
CREATE TABLE `Employee` (
`id` int(11) unsigned NOT NULL COMMENT '主键',
`name` varchar(20) DEFAULT NULL COMMENT '名称',
`role` varchar(20) DEFAULT NULL COMMENT '角色',
PRIMARY KEY (`id`))
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '雇员表';
- jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_data?useUnicode=true&characterEncoding=UTF-8&useOldAlias
jdbc.username=root
jdbc.password=123456
- applicationContext-datasource.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:p="http://www.springframework.org/schema/p"
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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- Jpa Entity Manager 配置 -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/>
<property name="packagesToScan" value="com.ryo.spring.data.jpa.model"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
<bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false"/>
<property name="database" value="MYSQL"/>
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
<bean id="entityManager" factory-bean="entityManagerFactory" factory-method="createEntityManager"/>
<!-- Jpa 事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<!--<!– 启动对@AspectJ(面向切面)注解的支持 –>-->
<aop:aspectj-autoproxy />
<context:component-scan base-package="com.ryo.spring.data.jpa"/>
</beans>
代码
- EmployeeDAO.java
import com.ryo.spring.data.jpa.model.Employee;
import java.util.List;
public interface EmployeeDAO {
//Create
void save(Employee employee);
//Read
Employee getById(int id);
//Update
void update(Employee employee);
//Delete
void deleteById(int id);
//Get All
List<Employee> getAll();
}
- EmployeeDAOImpl.java
import com.ryo.spring.data.jpa.model.Employee;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.transaction.Transactional;
import java.util.List;
@Transactional
@Repository
public class EmployeeDAOImpl implements EmployeeDAO {
@PersistenceContext
EntityManager em;
@Override
public void save(Employee employee) {
em.persist(employee);
}
@Override
public Employee getById(int id) {
return em.find(Employee.class, id);
}
public void update(Employee employee) {
em.merge(employee);
}
@Override
public void deleteById(int id) {
em.remove(this.getById(id));
}
@Override
public List<Employee> getAll() {
CriteriaBuilder builder = em.getCriteriaBuilder();
final CriteriaQuery<Employee> query = builder.createQuery(Employee.class);
return this.em.createQuery(query).getResultList();
}
}
- Employee.java
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Employee {
@Id
private int id;
private String name;
private String role;
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;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
@Override
public String toString() {
return "{ID=" + id + ",Name=" + name + ",Role=" + role + "}";
}
}
测试代码
- SpringDataJPATest.java
import com.ryo.spring.data.jpa.dao.EmployeeDAO;
import com.ryo.spring.data.jpa.model.Employee;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.util.Random;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/applicationContext-datasource.xml")
public class SpringDataJPATest {
@Resource
private EmployeeDAO employeeDAO;
@Test
public void saveTest(){
Employee emp = new Employee();
int rand = new Random().nextInt(1000);
emp.setId(rand);
emp.setName("Ryo");
emp.setRole("Java Developer");
employeeDAO.save(emp);
}
}
直接运行测试,数据库数据如下:
+-----+------+----------------+
| id | name | role |
+-----+------+----------------+
| 493 | Ryo | Java Developer |
+-----+------+----------------+
jar 包依赖
上述项目的 jar 包依赖如下:
+- org.springframework.boot:spring-boot-starter-data-jpa:jar:1.2.3.RELEASE:compile
| +- org.springframework.boot:spring-boot-starter:jar:1.2.3.RELEASE:compile
| | +- org.springframework.boot:spring-boot:jar:1.2.3.RELEASE:compile
| | +- org.springframework.boot:spring-boot-autoconfigure:jar:1.2.3.RELEASE:compile
| | +- org.springframework.boot:spring-boot-starter-logging:jar:1.2.3.RELEASE:compile
| | | +- org.slf4j:jul-to-slf4j:jar:1.7.11:compile
| | | +- org.slf4j:log4j-over-slf4j:jar:1.7.11:compile
| | | \- ch.qos.logback:logback-classic:jar:1.1.3:compile
| | | \- ch.qos.logback:logback-core:jar:1.1.3:compile
| | \- org.yaml:snakeyaml:jar:1.14:compile
| +- org.springframework.boot:spring-boot-starter-aop:jar:1.2.3.RELEASE:compile
| | +- org.aspectj:aspectjrt:jar:1.8.5:compile
| | \- org.aspectj:aspectjweaver:jar:1.8.5:compile
| +- org.springframework:spring-core:jar:4.1.6.RELEASE:compile
| +- org.springframework.boot:spring-boot-starter-jdbc:jar:1.2.3.RELEASE:compile
| | +- org.springframework:spring-jdbc:jar:4.1.6.RELEASE:compile
| | +- org.apache.tomcat:tomcat-jdbc:jar:7.0.59:compile
| | | \- org.apache.tomcat:tomcat-juli:jar:7.0.59:compile
| | \- org.springframework:spring-tx:jar:4.1.6.RELEASE:compile
| +- org.hibernate:hibernate-entitymanager:jar:4.3.8.Final:compile
| | +- org.jboss.logging:jboss-logging:jar:3.1.3.GA:compile
| | +- org.jboss.logging:jboss-logging-annotations:jar:1.2.0.Beta1:compile
| | +- org.hibernate:hibernate-core:jar:4.3.8.Final:compile
| | | +- antlr:antlr:jar:2.7.7:compile
| | | \- org.jboss:jandex:jar:1.1.0.Final:compile
| | +- dom4j:dom4j:jar:1.6.1:compile
| | | \- xml-apis:xml-apis:jar:1.0.b2:compile
| | +- org.hibernate.common:hibernate-commons-annotations:jar:4.0.5.Final:compile
| | +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
| | \- org.javassist:javassist:jar:3.18.1-GA:compile
| +- javax.transaction:javax.transaction-api:jar:1.2:compile
| +- org.springframework:spring-orm:jar:4.1.6.RELEASE:compile
| +- org.springframework.data:spring-data-jpa:jar:1.7.2.RELEASE:compile
| | +- org.springframework.data:spring-data-commons:jar:1.9.2.RELEASE:compile
| | +- org.springframework:spring-context:jar:4.1.6.RELEASE:compile
| | | \- org.springframework:spring-expression:jar:4.1.6.RELEASE:compile
| | +- org.slf4j:slf4j-api:jar:1.7.11:compile
| | \- org.slf4j:jcl-over-slf4j:jar:1.7.11:compile
| \- org.springframework:spring-aspects:jar:4.1.6.RELEASE:compile
+- com.h2database:h2:jar:1.4.185:compile
+- mysql:mysql-connector-java:jar:5.1.34:compile
+- org.springframework:spring-aop:jar:4.1.6.RELEASE:compile
| +- aopalliance:aopalliance:jar:1.0:compile
| \- org.springframework:spring-beans:jar:4.1.6.RELEASE:compile
+- org.springframework:spring-test:jar:4.1.6.RELEASE:compile
\- junit:junit:jar:4.11:compile
\- org.hamcrest:hamcrest-core:jar:1.3:compile
学习感想
说实在的,觉得 spring-data 设计的很棒。但是 mybatis 的使用门槛实在太低。所有以后可能还是专注于使用 mybatis。