1、pom.xml配置
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.linjb</groupId>
<artifactId>springboot-spring-data-jpa</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-spring-data-jpa Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- Spring Boot 启动父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<!-- Spring Boot web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL 连接驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<finalName>springboot-spring-data-jpa</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、application.properties 配置
在 application.properties 中配置:数据库连接信息(如使用嵌入式数据库则不需要)、自动创建表结构的设置,例如使用 mysql 的情况如下:
## 数据源配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_base_1?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
## Hibernate 的配置属性,其主要作用是:自动创建、更新、验证数据库表结构
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.show-sql=true
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
server.tomcat.uri-encoding=UTF-8
注:spring.jpa.properties.hibernate.hbm2ddl.auto 是 hibernate 的配置属性,其主要作用是:自动创建、更新、验证数据库表结构。该参数的几种配置如下:
1)、create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
2)、create-drop:每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
3)、update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。
4)、validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
3、Model层
package com.linjb.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* 政治面貌表模型
* @Copyright Copyright (C) 2019 linjb
* @author linjb
* @version 1.0
* @CreateDate 2019年2月3日下午6:12:14
*/
@Entity
public class PoliticalStatus {
@Id
@GeneratedValue
private Integer politicalStatusId;
@Column
private String politicalStatusName;
public Integer getPoliticalStatusId() {
return politicalStatusId;
}
public void setPoliticalStatusId(Integer politicalStatusId) {
this.politicalStatusId = politicalStatusId;
}
public String getPoliticalStatusName() {
return politicalStatusName;
}
public void setPoliticalStatusName(String politicalStatusName) {
this.politicalStatusName = politicalStatusName;
}
}
4、创建数据访问接口
针对 PoliticalStatus 实体创建对应的Repository接口实现对该实体的数据访问,如下代码:
package com.linjb.model;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface PoliticalStatusRepository extends JpaRepository<PoliticalStatus, Long>{
public PoliticalStatus findByPoliticalStatusId(Integer politicalStatusId);
public PoliticalStatus findByPoliticalStatusName(String politicalStatusName);
@Query("select politicalStatus from PoliticalStatus politicalStatus where politicalStatus.politicalStatusName like %:nn")
List<PoliticalStatus> fuzzyQueryByPoliticalStatusName(@Param("nn") String politicalStatusName);
}
在 Spring-data-jpa 中,只需要编写类似上面这样的接口就可实现数据访问。不再像我们以往编写了接口时候还需要自己编写接口实现类,直接减少了我们的文件清单。
下面对上面的 PoliticalStatusRepository 做一些解释,该接口继承自JpaRepository,通过查看JpaRepository接口的API文档,可以看到该接口本身已经实现了创建(save)、更新(save)、删除(delete)、查询(findAll、findOne)等基本操作的函数,因此对于这些基础操作的数据访问就不需要开发者再自己定义。
在我们实际开发中,JpaRepository接口定义的接口往往还不够或者性能不够优化,我们需要进一步实现更复杂一些的查询或操作。由于本文重点在spring boot中整合spring-data-jpa,在这里先抛砖引玉简单介绍一下spring-data-jpa中让我们兴奋的功能,后续再单独开篇讲一下spring-data-jpa中的常见使用。
在上例中,我们可以看到下面两个函数:
public PoliticalStatus findByPoliticalStatusId(Integer politicalStatusId);
public PoliticalStatus findByPoliticalStatusName(String politicalStatusName);
它们分别实现了按 politicalStatusId 查询 PoliticalStatus 实体和按politicalStatusName查询User实体,可以看到我们这里没有任何类SQL语句就完成了两个条件查询方法。这就是Spring-data-jpa的一大特性:通过解析方法名创建查询。
除了通过解析方法名来创建查询外,它也提供通过使用@Query 注解来创建查询,您只需要编写JPQL语句,并通过类似“:name”来映射@Param指定的参数,就像例子中的第三个findUser函数一样。
Spring-data-jpa 的能力远不止本文提到的这些,由于本文主要以整合介绍为主,对于Spring-data-jpa的使用只是介绍了常见的使用方式。诸如@Modifying操作、分页排序、原生SQL支持以及与Spring MVC的结合使用等等内容就不在本文中详细展开,这里先挖个坑,后续再补文章填坑,如您对这些感兴趣可以关注我博客或简书,同样欢迎大家留言交流想法。
5、Controller层
在完成了上述配置后,其实已经可以生产文档内容,但是这样的文档主要针对请求本身,而描述主要来源于函数等命名产生,对用户并不友好,我们通常需要自己增加一些说明来丰富文档内容。如下所示,我们通过@ApiOperation注解来给API增加说明、通过@ApiImplicitParams、@ApiImplicitParam注解来给参数增加说明。
package com.linjb.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.linjb.model.PoliticalStatus;
import com.linjb.model.PoliticalStatusRepository;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
@RestController
@RequestMapping(value="/politicalStatus")
public class Controller {
@Autowired
private PoliticalStatusRepository politicalStatusRepository;
@ApiOperation(value="获取政治面貌列表", notes="查询所有")
@RequestMapping(value={"/findAll"},method=RequestMethod.POST)
public List<PoliticalStatus> findAll(){
return politicalStatusRepository.findAll();
}
@ApiOperation(value="创建政治面貌", notes="根据 PoliticalStatus 对象创建政治面貌")
@ApiImplicitParam(name = "politicalStatus", value = "政治面貌对象", required = true, dataType = "PoliticalStatus")
@RequestMapping(value="/save",method=RequestMethod.POST)
public String save(@RequestBody PoliticalStatus politicalStatus){
if(politicalStatus==null){
return "politicalStatus==null";
}
System.out.println(politicalStatus);
politicalStatusRepository.save(politicalStatus);
return "success";
}
@ApiOperation(value="根据名称获取政治面貌列表", notes="全名查询")
@RequestMapping(value="/findByPoliticalStatusName",method=RequestMethod.POST)
public PoliticalStatus findByPoliticalStatusName(@RequestBody String politicalStatusName){
System.out.println("politicalStatusName="+politicalStatusName);
return politicalStatusRepository.findByPoliticalStatusName(politicalStatusName);
}
@ApiOperation(value="根据名称获取政治面貌列表", notes="模糊查询")
@RequestMapping(value="/fuzzyQueryByPoliticalStatusName",method=RequestMethod.POST)
public List<PoliticalStatus> fuzzyQueryByPoliticalStatusName(@RequestBody String politicalStatusName){
System.out.println("politicalStatusName="+politicalStatusName);
return politicalStatusRepository.fuzzyQueryByPoliticalStatusName(politicalStatusName);
}
@ApiOperation(value="根据Id获取政治面貌", notes="Id查询")
@RequestMapping(value="/findByPoliticalStatusId",method=RequestMethod.POST)
public PoliticalStatus findByPoliticalStatusId(@RequestBody Integer politicalStatusId){
System.out.println("politicalStatusId="+politicalStatusId);
return politicalStatusRepository.findByPoliticalStatusId(politicalStatusId);
}
}
6、Application启动类
package com.linjb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
/**
* Spring Boot应用启动类
* @Copyright Copyright (C) 2019 linjb
* @author linjb
* @version 1.0
* @CreateDate 2019年1月31日下午10:25:16
*/
@SpringBootApplication
public class Application /*extends SpringBootServletInitializer*/{
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
// @Override
// protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//
// return builder.sources(Application.class);
// }
}
7、创建Swagger2配置类
package com.linjb;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Swagger2 {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.linjb"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Spring Boot 使用 Spring-data-jpa 简化数据访问层")
.description("政治面貌 API 操作")
.termsOfServiceUrl("https://blog.csdn.net/qq_26629277")
.contact("程序员linjb")
.version("1.0")
.build();
}
}