Spring boot学习之spring-data-jpa的使用(一)

时间:2022-06-23 16:10:09

Spring boot学习之jpa的使用

之前我们是简单的入了门,创建一个helloword,而在实际的开发中仅仅入门是不够的,比如就少不了数据库的操作,本章将简单介绍一下基于hibernate的spring boot中jpa的使用。

1.JPA简介

要使用JPA首先得了解什么是JPA,其实本人在此之前对此也是有一些接触的,但是其究竟是个什么东东,也是不了解的,这次也是在网上各种度娘之后对其有了一个比较明确的理解。

其实JPA本身并不是一种框架,是一种规范,其全称是Java Persistence API,是是Sun官方提出的Java持久化规范,而他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,并且其是在充分吸收了现有Hibernate,TopLink,JDO等ORM框架的基础上发展而来的,具有易于使用,伸缩性强等优点。

而官网对spring data jpa是这么介绍的:Spring Data JPA是Spring Data系列的一部分,可以轻松实现基于JPA的存储库。该模块处理对基于JPA的数据访问层的增强的支持。这使得使用数据访问技术构建Spring供电的应用程序变得更加容易。

Spring Data JPA旨在通过减少实际需要的数量来显着提高数据访问层的实现。作为开发人员,您编写存储库接口(包括自定义查找器方法),Spring将自动提供实现。
特征
基于Spring和JPA构建存储库的复杂支持
支持Querydsl谓词,从而支持类型安全的JPA查询
域类的透明审计
分页支持,动态查询执行,整合自定义数据访问代码的能力
@Query引导时间验证注释查询
支持基于XML的实体映射

[java]  view plain  copy
  1. package com.zxl.examples.controller;  
  2.   
  3. import com.zxl.examples.controller.common.ResultBean;  
  4. import com.zxl.examples.controller.common.SuccessBean;  
  5. import com.zxl.examples.entity.User;  
  6. import com.zxl.examples.service.UserRepository;  
  7. import com.zxl.examples.service.UserSerivceImpl;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9. import org.springframework.data.domain.Page;  
  10. import org.springframework.data.domain.PageRequest;  
  11. import org.springframework.data.domain.Slice;  
  12. import org.springframework.data.domain.Sort;  
  13. import org.springframework.web.bind.annotation.*;  
  14.   
  15. import java.util.ArrayList;  
  16. import java.util.List;  
  17.   
  18. /** 
  19.  * Created by Administrator on 2017/7/24. 
  20.  */  
  21. @RestController  
  22. public class UserController {  
  23.   
  24.     @Autowired  
  25.     UserRepository userRepository;  
  26.   
  27.     @Autowired  
  28.     UserSerivceImpl userSerivce;  
  29.   
  30.     @GetMapping("/users")  
  31.     public List<user> findUserList(){  
  32.         return userRepository.findAll();  
  33.     }  
  34.   
  35.     @PostMapping("/users/add")  
  36.     public User addUser(@RequestParam("username") String username,  
  37.                               @RequestParam("name") String name,  
  38.                               @RequestParam("password") String password){  
  39.         User user = new User();  
  40.         user.setUsername(username);  
  41.         user.setName(name);  
  42.         user.setPassword(password);  
  43.         return userRepository.save(user);  
  44.   
  45.     }  
  46.   
  47.     @GetMapping("/users/{id}")  
  48.     public User getUserById(@PathVariable Long id){  
  49.         return userRepository.findOne(id);  
  50.     }  
  51.   
  52.     @PutMapping("/users/{id}")  
  53.     public User updUserById(@PathVariable Long id,@RequestParam("name") String name){  
  54.         User user = userRepository.findOne(id);//先查出来,否则修改的时候会将其他request中没有的参数也给覆盖掉  
  55.         user.setName(name);  
  56.         return userRepository.save(user);//与保存是同一个方法  
  57.     }  
  58.   
  59.     @DeleteMapping("/users/{id}")  
  60.     public ResultBean delUserById(@PathVariable Long id){  
  61.         userRepository.delete(id);  
  62.         return new SuccessBean();  
  63.     }  
  64.   
  65.     @GetMapping("/users/username/{username}")  
  66.     public List<user> findByUsername(@PathVariable ("username") String username){  
  67.         return userRepository.findByUsername(username);  
  68.     }  
  69.   
  70.     @PostMapping("/users/addMore")  
  71.     public void addMore(){  
  72.         userSerivce.addMoreUsers();  
  73.     }  
  74.   
  75.     @PostMapping("/users/addList")  
  76.     public void addMoreList(){  
  77.         userSerivce.addMoreList();  
  78.     }  
  79.   
  80.       
  81. }  
  82. </user></user>  

通过介绍基于JavaConfig的存储库配置@EnableJpaRepositories

2.1  准备工作

了解了JPA以及Spring data JPA之后那么就可以开始进行实战了,而再此之前需要引入相关的依赖,详见pom文件如下

[plain]  view plain  copy
  1. <!--?xml version="1.0" encoding="UTF-8"?-->  
  2. <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">  
  3.     <modelversion>4.0.0</modelversion>  
  4.   
  5.     <groupid>com.zxl</groupid>  
  6.     <artifactid>sprintboot-examples</artifactid>  
  7.     <version>1.0-SNAPSHOT</version>  
  8.   
  9.     <!-- Inherit defaults from Spring Boot -->  
  10.     <parent>  
  11.         <groupid>org.springframework.boot</groupid>  
  12.         <artifactid>spring-boot-starter-parent</artifactid>  
  13.         <version>1.5.4.RELEASE</version>  
  14.     </parent>  
  15.   
  16.     <!-- Add typical dependencies for a web application -->  
  17.     <dependencies>  
  18.   
  19.         <dependency>  
  20.             <groupid>org.springframework.boot</groupid>  
  21.             <artifactid>spring-boot-starter-data-jpa</artifactid>  
  22.         </dependency>  
  23.   
  24.         <dependency>  
  25.             <groupid>org.springframework.boot</groupid>  
  26.             <artifactid>spring-boot-starter-web</artifactid>  
  27.         </dependency>  
  28.   
  29.         <!-- Runtime -->  
  30.         <!--<dependency>-->  
  31.             <!--<groupId>com.h2database</groupId>-->  
  32.             <!--<artifactId>h2</artifactId>-->  
  33.             <!--<scope>runtime</scope>-->  
  34.         <!--</dependency>-->  
  35.   
  36.         <dependency>  
  37.             <groupid>org.hibernate</groupid>  
  38.             <artifactid>hibernate-core</artifactid>  
  39.         </dependency>  
  40.   
  41.         <dependency>  
  42.             <groupid>org.hsqldb</groupid>  
  43.             <artifactid>hsqldb</artifactid>  
  44.         </dependency>  
  45.   
  46.         <!-- Test -->  
  47.         <dependency>  
  48.             <groupid>org.springframework.boot</groupid>  
  49.             <artifactid>spring-boot-starter-test</artifactid>  
  50.             <scope>test</scope>  
  51.         </dependency>  
  52.   
  53.         <dependency>  
  54.             <groupid>mysql</groupid>  
  55.             <artifactid>mysql-connector-java</artifactid>  
  56.         </dependency>  
  57.     </dependencies>  
  58.   
  59.   
  60.     <!-- Package as an executable jar -->  
  61.     <build>  
  62.         <plugins>  
  63.             <plugin>  
  64.                 <groupid>org.springframework.boot</groupid>  
  65.                 <artifactid>spring-boot-maven-plugin</artifactid>  
  66.             </plugin>  
  67.         </plugins>  
  68.     </build>  
  69.   
  70.   
  71. </project>  
yml属性配置文件需要配置数据库的链接属性,我采用的是mysql数据库,如下(注明:可以先不用理会redis的配置后续会讲到):

[plain]  view plain  copy
  1. # HTTP Server  
  2.   
  3. server:  
  4.   port: 8089   # HTTP (Tomcat) port  
  5.   
  6. spring:  
  7.   profiles:  
  8.     active: local  
  9.   
  10.   
  11. #日志采用debug模式  
  12. debug: true  
  13.   
  14. ---  
  15. #本地环境  
  16. spring:  
  17.   profiles: local  
  18.   
  19.   datasource:  
  20.     driver-class-name: com.mysql.jdbc.Driver  
  21.     url: jdbc:mysql://localhost:3306/bootdb?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true  
  22.     username: root  
  23.     password: root  
  24.   
  25.   jpa:  
  26.     hibernate:  
  27.       ddl-auto: update  
  28.     show-sql: true  
  29.   
  30. # REDIS (RedisProperties)  
  31. # Redis数据库索引(默认为0)  
  32.   redis:  
  33.     database: 0  
  34.     host: localhost  
  35.     port: 6379  
  36.     password: xue$Xin+2@!3  
  37.     pool:  
  38.       # 连接池最大连接数(使用负值表示没有限制)  
  39.       max-active: 8  
  40.       # 连接池最大阻塞等待时间(使用负值表示没有限制)  
  41.       max-wait: -1  
  42.       # 连接池中的最大空闲连接  
  43.       max-idle: 8  
  44.     # 连接超时时间(毫秒)  
  45.     timeout: 0  
  46.   
  47.   
  48.   
  49.   
  50.   
  51. logging:  
  52.   level:  
  53.     org:  
  54.       hibernate:  
  55.         SQL: DEBUG  
  56.         type:  
  57.           descriptor:  
  58.             sql: TRACE  
  59.   
  60. ---  
  61. #开发环境  
  62. spring:  
  63.   profiles: dev  
  64.   
  65. jdbc:  
  66.   driver: com.mysql.jdbc.Driver  
  67.   url: jdbc:mysql://localhost:3306/bootdb?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true  
  68.   username: root  
  69.   password: root1  

其实hibernate有几年没有用过了,大部分年都忘记了,这次也算是温习了一把吧,hql的语法大可以自己简单的去度娘一下,说白了就是把pojo当成table来操作就行了,还有一些参数代入的细节注意下即可,这里简单说下hibernate auto-ddl的配置吧(也是粘贴过来的,懒得自己写了,很有可能自己也没法写的比粘贴的易懂准确):其实这个hibernate.hbm2ddl.auto参数的作用主要用于:自动创建|更新|验证数据库表结构。如果不是此方面的需求建议set value="none"。
create:
每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
create-drop :
每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
update:
最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
validate :
每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。

创建一个简单的entity,代码如下,值得注意的地方是这里必须要有一个无参构造方法,否则JPA启动会报错,另外可以看到其实现了Serializable,这部分主要是为了后续要讲到的spring boot data redis使用时用到的,当然了也可以不实现,只不过使用redis的方式会不一样而已,这个看个人喜好了

[java]  view plain  copy
  1. package com.zxl.examples.entity;  
  2.   
  3. import javax.persistence.Column;  
  4. import javax.persistence.Entity;  
  5. import javax.persistence.GeneratedValue;  
  6. import javax.persistence.Id;  
  7. import java.io.Serializable;  
  8.   
  9. /** 
  10.  * Created by Administrator on 2017/7/21. 
  11.  */  
  12. @Entity  
  13. public class User implements Serializable {  
  14.     private static final long serialVersionUID = 1L;  
  15.   
  16.     @Id  
  17.     @Column(name="id",nullable = false)  
  18.     @GeneratedValue  
  19.     private Long id;  
  20.   
  21.     @Column  
  22.     private String username;  
  23.   
  24.     @Column  
  25.     private String name;  
  26.   
  27.     @Column  
  28.     private String password;  
  29.   
  30.     public Long getId() {  
  31.         return id;  
  32.     }  
  33.   
  34.     public void setId(Long id) {  
  35.         this.id = id;  
  36.     }  
  37.   
  38.     public String getUsername() {  
  39.         return username;  
  40.     }  
  41.   
  42.     public void setUsername(String username) {  
  43.         this.username = username;  
  44.     }  
  45.   
  46.     public String getName() {  
  47.         return name;  
  48.     }  
  49.   
  50.     public void setName(String name) {  
  51.         this.name = name;  
  52.     }  
  53.   
  54.     public String getPassword() {  
  55.         return password;  
  56.     }  
  57.   
  58.     public void setPassword(String password) {  
  59.         this.password = password;  
  60.     }  
  61.   
  62.     public User(String username,String name,String password){  
  63.         super();  
  64.         this.username=username;  
  65.         this.name=name;  
  66.         this.password=password;  
  67.     }  
  68.   
  69.     //必须有一个无参构造方法,否则会报错  
  70.     public User(){  
  71.   
  72.     }  
  73.   
  74.     @Override  
  75.     public String toString() {  
  76.         return getId()+","+getUsername()+","+getName();  
  77.     }  
  78. }  

2.2  创建简单的查询

创建一个自己的Repository,官网上介绍的是其需要集成Repository或者CurdRepository,而此处采用的是继承JpaRepository,至于为什么是JpaRepository,说实话我也不知道,我也是通过看了好多大牛的博客后发现大家都是继承的JpaRepository,所以干脆我也来继承JpaRepository得了,有兴趣的话可以自己去研究研究。

spring data jpa 默认预先生成了一些基本的CURD的方法,直接拿来用就可以,不需要自己来写,可以简单的看一下JpaRepository的源码,一看名称就知道是啥意思了,如下图

Spring boot学习之spring-data-jpa的使用(一)

创建一个UserController类,代码如下:

[java]  view plain  copy
  1. package com.zxl.examples.controller;  
  2.   
  3. import com.zxl.examples.controller.common.ResultBean;  
  4. import com.zxl.examples.controller.common.SuccessBean;  
  5. import com.zxl.examples.entity.User;  
  6. import com.zxl.examples.service.UserRepository;  
  7. import com.zxl.examples.service.UserSerivceImpl;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9. import org.springframework.data.domain.Page;  
  10. import org.springframework.data.domain.PageRequest;  
  11. import org.springframework.data.domain.Slice;  
  12. import org.springframework.data.domain.Sort;  
  13. import org.springframework.web.bind.annotation.*;  
  14.   
  15. import java.util.ArrayList;  
  16. import java.util.List;  
  17.   
  18. /** 
  19.  * Created by Administrator on 2017/7/24. 
  20.  */  
  21. @RestController  
  22. public class UserController {  
  23.   
  24.     @Autowired  
  25.     UserRepository userRepository;  
  26.   
  27.     @Autowired  
  28.     UserSerivceImpl userSerivce;  
  29.   
  30.     @GetMapping("/users")  
  31.     public List<user> findUserList(){  
  32.         return userRepository.findAll();  
  33.     }  
  34.   
  35.     @PostMapping("/users/add")  
  36.     public User addUser(@RequestParam("username") String username,  
  37.                               @RequestParam("name") String name,  
  38.                               @RequestParam("password") String password){  
  39.         User user = new User();  
  40.         user.setUsername(username);  
  41.         user.setName(name);  
  42.         user.setPassword(password);  
  43.         return userRepository.save(user);  
  44.   
  45.     }  
  46.   
  47.     @GetMapping("/users/{id}")  
  48.     public User getUserById(@PathVariable Long id){  
  49.         return userRepository.findOne(id);  
  50.     }  
  51.   
  52.     @PutMapping("/users/{id}")  
  53.     public User updUserById(@PathVariable Long id,@RequestParam("name") String name){  
  54.         User user = userRepository.findOne(id);//先查出来,否则修改的时候会将其他request中没有的参数也给覆盖掉  
  55.         user.setName(name);  
  56.         return userRepository.save(user);//与保存是同一个方法  
  57.     }  
  58.   
  59.     @DeleteMapping("/users/{id}")  
  60.     public ResultBean delUserById(@PathVariable Long id){  
  61.         userRepository.delete(id);  
  62.         return new SuccessBean();  
  63.     }  
  64.   
  65.     @GetMapping("/users/username/{username}")  
  66.     public List<user> findByUsername(@PathVariable ("username") String username){  
  67.         return userRepository.findByUsername(username);  
  68.     }  
  69.   
  70.     @PostMapping("/users/addMore")  
  71.     public void addMore(){  
  72.         userSerivce.addMoreUsers();  
  73.     }  
  74.   
  75.     @PostMapping("/users/addList")  
  76.     public void addMoreList(){  
  77.         userSerivce.addMoreList();  
  78.     }  
  79.   
  80.       
  81. }  
  82. </user></user>  
创建一个UserServiceImpl类,代码如下(实现list批量操作以及事务的控制):
[java]  view plain  copy
  1. package com.zxl.examples.service;  
  2.   
  3. import com.zxl.examples.entity.User;  
  4. import org.springframework.beans.factory.annotation.Autowired;  
  5. import org.springframework.cache.annotation.CacheEvict;  
  6. import org.springframework.cache.annotation.CachePut;  
  7. import org.springframework.cache.annotation.Cacheable;  
  8. import org.springframework.data.redis.core.RedisTemplate;  
  9. import org.springframework.data.redis.core.StringRedisTemplate;  
  10. import org.springframework.stereotype.Service;  
  11. import org.springframework.transaction.annotation.Transactional;  
  12.   
  13. import java.util.ArrayList;  
  14. import java.util.List;  
  15. import java.util.concurrent.TimeUnit;  
  16.   
  17. /** 
  18.  * Created by Administrator on 2017/7/24. 
  19.  */  
  20. @Service("userSerivce")  
  21. public class UserSerivceImpl {  
  22.     @Autowired  
  23.     UserRepository userRepository;  
  24.   
  25.     @Transactional  
  26.     public void addMoreUsers(){  
  27.         User user1 = new User();  
  28.         user1.setUsername("123");  
  29.         user1.setName("123");  
  30.         user1.setPassword("123");  
  31.         userRepository.save(user1);  
  32.         User user2 = new User();  
  33.         user2.setUsername("234");  
  34.         user2.setName("123");  
  35.         user2.setPassword("123");  
  36.         userRepository.save(user2);  
  37.     }  
  38.   
  39.     public void addMoreList(){  
  40.         List<user> userList = new ArrayList<user>();  
  41.         User user1 = new User();  
  42.         user1.setUsername("345");  
  43.         user1.setName("123");  
  44.         user1.setPassword("123");  
  45.         userList.add(user1);  
  46.   
  47.         User user2 = new User();  
  48.         user2.setUsername("456");  
  49.         user2.setName("123");  
  50.         user2.setPassword("123");  
  51.         userList.add(user2);  
  52.         userRepository.save(userList);  
  53.     }  
  54.   
  55.      
  56. }  
  57. </user></user>  
创建一个UserRepository类,代码如下:
[java]  view plain  copy
  1. package com.zxl.examples.service;  
  2.   
  3. import com.zxl.examples.entity.User;  
  4. import org.springframework.data.domain.Page;  
  5. import org.springframework.data.domain.Pageable;  
  6. import org.springframework.data.domain.Slice;  
  7. import org.springframework.data.domain.Sort;  
  8. import org.springframework.data.jpa.repository.JpaRepository;  
  9. import org.springframework.data.jpa.repository.Query;  
  10. import org.springframework.data.repository.query.Param;  
  11.   
  12. import java.util.List;  
  13.   
  14. /** 
  15.  * Created by Administrator on 2017/7/21. 
  16.  */  
  17. public interface UserRepository extends JpaRepository<user,long> {  
  18.   
  19.       
  20.   
  21.   
  22. }  
  23. </user,long>  



下面使用postman来进行测试,结果如下:

Spring boot学习之spring-data-jpa的使用(一)Spring boot学习之spring-data-jpa的使用(一)Spring boot学习之spring-data-jpa的使用(一)Spring boot学习之spring-data-jpa的使用(一)Spring boot学习之spring-data-jpa的使用(一)Spring boot学习之spring-data-jpa的使用(一)


简单查询到此结束了,下篇再继续介绍一些复杂的查询