Spring JPA

文章目录
  1. 1. JPA例子(h2database版)
    1. 1.1. 新建工程
    2. 1.2. pom.xml
    3. 1.3. Customer.java
    4. 1.4. CustomerRepository.java
    5. 1.5. Application.java
    6. 1.6. mvn test异常
    7. 1.7. 运行异常
    8. 1.8. Spring官方代码
    9. 1.9. 醉了
    10. 1.10. spring-boot
  2. 2. JPA例子(hsql版)
  3. 3. JPA例子(Mysql版)
  4. 4. 源代码分享
  5. 5. 后记
  6. 6. 参考文档

JPA例子(h2database版)

这个例子高仿照搬Spring官网给出的例子,只是包不同而已。

新建工程

Eclipse,File,New,Maven Project,Create a simple project打上勾,Next。

Group Id输入反向域名加上工程名,Artifact Id输入子工程名,Packaging处选择jar(意思是普通工程;如果是web工程,选择war;如果用来定义父工程,选择pom)。

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<groupId>com.voidking.book</groupId>
<artifactId>book-jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.5.RELEASE</version>
</parent>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>org.jboss.repository.releases</id>
<name>JBoss Maven Release Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>

</project>

Customer.java

src/main/java/com/voidking/book/entity/Customer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.voidking.book.entity;

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

@Entity
public class Customer {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;

protected Customer() {}

public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

@Override
public String toString() {
return String.format(
"Customer[id=%d, firstName='%s', lastName='%s']",
id, firstName, lastName);
}

}

CustomerRepository.java

src/main/java/com/voidking/book/repository/Customer.java

1
2
3
4
5
6
7
8
9
10
11
package com.voidking.book.repository;
import java.util.List;

import org.springframework.data.repository.CrudRepository;

import com.voidking.book.entity.Customer;

public interface CustomerRepository extends CrudRepository<Customer, Long> {

List<Customer> findByLastName(String lastName);
}

Repository(资源库):通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调。这个叫法就类似于我们通常所说的DAO,在这里,我们就按照这一习惯把数据访问层叫Repository Spring Data,基础的Repository提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下:
Repository:仅仅是一个标识,表明任何继承它的均为仓库接口类,方便Spring自动扫描识别
CrudRepository: 继承Repository,实现了一组CRUD相关的方法
PagingAndSortingRepository: 继承CrudRepository,实现了一组分页排序相关的方法
JpaRepository: 继承PagingAndSortingRepository,实现一组JPA规范相关的方法
JpaSpecificationExecutor: 比较特殊,不属于Repository体系,实现一组JPA Criteria查询相关的方法
我们自己定义的XxxxRepository需要继承JpaRepository,这样我们的XxxxRepository接口就具备了通用的数据访问控制层的能力。

Application.java

src/main/java/com/voidking/book/app/Application.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.voidking.book.app;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.voidking.book.entity.Customer;
import com.voidking.book.repository.CustomerRepository;

@SpringBootApplication
public class Application implements CommandLineRunner {

@Autowired
CustomerRepository repository;

public static void main(String[] args) {
SpringApplication.run(Application.class);
}

@Override
public void run(String... strings) throws Exception {
// save a couple of customers
repository.save(new Customer("Jack", "Bauer"));
repository.save(new Customer("Chloe", "O'Brian"));
repository.save(new Customer("Kim", "Bauer"));
repository.save(new Customer("David", "Palmer"));
repository.save(new Customer("Michelle", "Dessler"));

// fetch all customers
System.out.println("Customers found with findAll():");
System.out.println("-------------------------------");
for (Customer customer : repository.findAll()) {
System.out.println(customer);
}
System.out.println();

// fetch an individual customer by ID
Customer customer = repository.findOne(1L);
System.out.println("Customer found with findOne(1L):");
System.out.println("--------------------------------");
System.out.println(customer);
System.out.println();

// fetch customers by last name
System.out.println("Customer found with findByLastName('Bauer'):");
System.out.println("--------------------------------------------");
for (Customer bauer : repository.findByLastName("Bauer")) {
System.out.println(bauer);
}
}

}

mvn test异常

执行命令mvn test,抛出异常:

1
2
Exception in thread "main" java.lang.UnsupportedClassVersionError:
com/voidking/book/app/Application : Unsupported major.minor version 52.0

这个异常,是因为本机没有安装jdk8,我就把Properties->java build path->Libraries中的JVM8换成JVM7。

解决方法:
右击项目,Properties,Java Compiler,Compiler compliance level从1.8改成1.7,之后就可以运行了。

运行异常

mvn spring-boot:run,异常:

1
2
3
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'application': Injection of autowired dependencies failed; 
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.voidking.book.repository.CustomerRepository com.voidking.book.app.Application.repository;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.voidking.book.repository.CustomerRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

可以看到,异常层层连锁,看起来那么长,实际上重点在后面。
原来是缺少CustomerRepository类型的bean,那么,为什么缺少呢?是否是因为需要一个类似spring.xml的配置文件?

Spring官方代码

看看Spring官方给出的例子,确实没有配置文件。mvn spring-boot:run,结果如下:

运行成功,可见,这个例子是没有任何问题的。那么,问题出在哪里?因为分了不同的包?

试一试,把所有.java移动到一个包中,运行。。。成功!

醉了

从中午12点忙到晚上12点,此问题没有解决,我也是醉了。。。

spring-boot

第二天,继续查找资料,终于明白了,这一切都是spring-boot搞的鬼。

spring-boot会自动配置通过jpa进行数据访问需要的bean。

spring-boot会根据classpath包含的内容自动推测用户的需求并自动配置。例如如果在classpath包含了hsqldb,并且用户未配置数据库连接,spring-boot将会配置一个hsqldb内存数据库和数据源。

spring-boot无代码生成,所有的配置可通过代码完成(spring 的javaconfig),不需要使用xml(虽然可以使用)。

JPA例子(hsql版)

h2database和hsql非常类似,适合作为嵌入式数据库使用,其它的数据库大部分都需要安装独立的客户端和服务器端。顺便比较一下各个数据库,如下图:

name属性用于定义持久化单元的名字(name必选,空值也合法);transaction-type指定事务类型(可选)

JPA例子(Mysql版)

源代码分享

Spring官方例子
git clone https://github.com/spring-guides/gs-accessing-data-jpa.git

后记

使用Spring,和单纯的JPA有什么区别?

  • 多了一些标记为Bean的注解,比如@Repository、@Service、@Controller和@Component。

  • JAP有持久化配置文件persistence.xml(src/META-INF),默认加载。在这个文件中,可以配置数据库连接信息,实体类等;
    使用了Spring,除了persistence.xml,还多出了一个或多个Spring的配置文件,配置文件间可以通过<import>标签引用;
    persistence.xml中的内容,可以改写到spring的配置文件中,如果内容全部改写,此时persistence.xml文件可以省略。

参考文档

Accessing Data with JPA
http://spring.io/guides/gs/accessing-data-jpa/

Spring Data JPA - Reference Documentation
http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/

使用 Spring Data JPA 简化 JPA 开发
http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-jpa/

简单的Spring JPA实现例子
http://blog.csdn.net/kongxx/article/details/5653370

spring mvc 的jpa JpaRepository数据层 访问方式汇总
http://jishiweili.iteye.com/blog/2088265

使用spring-boot快速开发spring应用
http://itindex.net/detail/49108-spring-boot-%E5%BC%80%E5%8F%91

JPA 不在 persistence.xml 文件中配置每个Entity实体类的2种解决办法
http://www.cnblogs.com/taven/archive/3351841.html

Jpa规范中persistence.xml 配置文件解析
http://www.cnblogs.com/edwardlauxh/archive/2632292.html