spring boot2 整合(二)JPA(特别完整!)
JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
JPA 的目标之一是制定一个可以由很多供应商实现的API,并且开发人员可以编码来实现该API,而不是使用私有供应商特有的API。
JPA是需要Provider来实现其功能的,Hibernate就是JPA Provider中很强的一个,应该说无人能出其右。从功能上来说,JPA就是Hibernate功能的一个子集。
本教程大概流程:
- 借助idea实现springboot 和 spring data jpa 整合
- 实现JpaRepository接口快捷开发
- 自定义Mapper查询接口方法
- MVC架构+分页功能实战
- QueryDSL工具与之的整合
首先我的开发环境:
jdk1.8+maven3+IDEA
1. 完善pom文件
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>springboot-jpa</groupId>
<artifactId>springboot-jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-jpa</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>1.4.5.RELEASE</version>
<scope>test</scope>
</dependency>
<!--querydsl依赖-->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
<!--阿里巴巴数据库连接池,专为监控而生 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.26</version>
</dependency>
<!-- 阿里巴巴fastjson,解析json视图 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.15</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--添加QueryDSL插件支持-->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2. 完善application.properties 文件
spring.datasource.url=jdbc:mysql://localhost:3306/user
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type: com.alibaba.druid.pool.DruidDataSource
spring.datasource.filters:stat
spring.datasource.maxActive: 20
spring.datasource.initialSize: 1
spring.datasource.maxWait: 60000
spring.datasource.minIdle: 1
spring.datasource.timeBetweenEvictionRunsMillis: 60000
spring.datasource.minEvictableIdleTimeMillis: 300000
spring.datasource.validationQuery: select 'x'
spring.datasource.testWhileIdle: true
spring.datasource.testOnBorrow: false
spring.datasource.testOnReturn: false
spring.datasource.poolPreparedStatements: true
spring.datasource.maxOpenPreparedStatements: 20
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.show-sql=true
3. 编写实体类 User.java
package com.fantj.model;
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
@Data
@Entity
@Table(name = "user")
public class User {
public User(){
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(nullable = false)
private String username;
@Column(nullable = false)
private Date birthday;
@Column(nullable = false)
private String sex;
@Column(nullable = false)
private String address;
}
@Data注解是 lombok 依赖包下的注解,它可以自动帮我们生成set/getter方法,简化代码量。有兴趣的可以详细了解,这里不做多解释。
4. 实现DAO层
package com.fantj.repostory;
/**
* Created by Fant.J.
*/
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
//自定义repository。手写sql
@Query(value = "update user set name=?1 where id=?4",nativeQuery = true) //占位符传值形式
@Modifying
int updateById(String name,int id);
@Query("from User u where u.username=:username") //SPEL表达式
User findUser(@Param("username") String username);// 参数username 映射到数据库字段username
}
注意:只有@Query 的注解下不能使用insert,我们需要在上面再添加个@Modify注解,我习惯都加,nativeQuery 是询问是否使用原生sql语句。多表查询也是在这里手写sql,不做演示。因为后面我们用更好的支持多表查询的工具框架 QueryDSL来帮助我们更简洁的实现它。
5.实现Service层
UserService .java
package com.fantj.service;
/**
* Created by Fant.J.
*/
public interface UserService {
/** 删除 */
public void delete(int id);
/** 增加*/
public void insert(User user);
/** 更新*/
public int update(User user);
/** 查询单个*/
public User selectById(int id);
/** 查询全部列表*/
public Iterator<User> selectAll(int pageNum, int pageSize);
}
UserServiceImpl.java
package com.fantj.service.impl;
/**
* Created by Fant.J.
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
/**
* 删除
*
* @param id
*/
@Override
public void delete(int id) {
userRepository.deleteById(id);
}
/**
* 增加
*
* @param user
*/
@Override
public void insert(User user) {
userRepository.save(user);
}
/**
* 更新
*
* @param user
*/
@Override
public int update(User user) {
userRepository.save(user);
return 1;
}
/**
* 查询单个
*
* @param id
*/
@Override
public User selectById(int id) {
Optional<User> optional = userRepository.findById(id);
User user = optional.get();
return user;
}
/**
* 查询全部列表,并做分页
* @param pageNum 开始页数
* @param pageSize 每页显示的数据条数
*/
@Override
public Iterator<User> selectAll(int pageNum, int pageSize) {
//将参数传给这个方法就可以实现物理分页了,非常简单。
Sort sort = new Sort(Sort.Direction.DESC, "id");
Pageable pageable = new PageRequest(pageNum, pageSize, sort);
Page<User> users = userRepository.findAll(pageable);
Iterator<User> userIterator = users.iterator();
return userIterator;
}
}
分页不止可以这样做,也可以在Controller层进行实例化和初始化然后将Pageable对象传给Service。
当然也可以对分页进行封装,封装后的展示。
Page<User> datas = userRepository.findAll(PageableTools.basicPage(1, 5, new SortDto("id")));
是不是很简洁。大家可以自己尝试一下。
6. 实现Controller
package com.fantj.controller;
/**
* Created by Fant.J.
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.GET,value = "/delete/{id}")
public void delete(@PathVariable("id")int id){
userService.delete(id);
}
@RequestMapping(method = RequestMethod.POST,value = "/insert")
public void insert(User user){
userService.insert(user);
}
@RequestMapping(method = RequestMethod.POST,value = "/update/{id}")
public void update(@RequestParam User user){
userService.update(user);
}
@RequestMapping(method = RequestMethod.GET,value = "/{id}/select")
public User select(@PathVariable("id")int id){
return userService.selectById(id);
}
@RequestMapping(method = RequestMethod.GET,value = "/selectAll/{pageNum}/{pageSize}")
public List<User> selectAll(@PathVariable("pageNum") int pageNum, @PathVariable("pageSize") int pageSize){
Iterator<User> userIterator = userService.selectAll(pageNum, pageSize);
List<User> list = new ArrayList<>();
while(userIterator.hasNext()){
list.add(userIterator.next());
}
return list;
}
}

QueryDSL工具与上文的整合
可以参考恒宇少年的四篇文章:
- Maven环境下如何配置QueryDSL环境 https://www.jianshu.com/p/a22447c0897c
- 使用QueryDSL与SpringDataJPA实现单表普通条件查询 https://www.jianshu.com/p/4e9d8adaeeb2
- 使用QueryDSL与SpringDataJPA完成Update&Delete https://www.jianshu.com/p/ac388c3c36c2
- 使用QueryDSL与SpringDataJPA实现多表关联查询 https://www.jianshu.com/p/6199e76a5485
注意一点,目前springboot2.0 版本对JPA支持有误,如果你用springboot2 来配置querydsl,application启动类会运行不起来,正确的依赖包或者是配置类我还没有找到,希望有点子的朋友可以和我联系。 本人QQ:844072586
作者:FantJ
链接:https://www.jianshu.com/p/3b31270a44b1
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
spring boot2 整合(二)JPA(特别完整!)的更多相关文章
- [Java] Spring boot2 整合 Thymeleaf 后 去除模板缓存
Spring boot2 整合 Thymeleaf 后 去除模板缓存 网上好多文章只是简单粗暴的说,在 application.properties 做如下配置即可: #Thymeleaf cach ...
- 【串线篇】spring boot整合SpringData JPA
一.SpringData简介 其中SpringData JPA底层基于hibernate 二.整合SpringData JPA JPA: Java Persistence API的简称,中文名Java ...
- spring boot2整合dubbox全注解
前题 dubbox是dubbo的一个升级版,简单说就是本来dubbo是阿里开发的,现在阿里不维护了,当当网拿过去继续开发.本来阿里的dubbo维护到2.6版本,而再高版本的都是当当网维护的就叫成dub ...
- spring boot2 整合(一)Mybatis (特别完整!)
大概介绍下流程: 借助idea实现mybatis逆向工程 用xml配置实现整合 用cmd命令行实现mybatis逆向工程 用mapping.xml配置实现数据交互 用注解的方式实现数据交互 首先我的开 ...
- Spring+Quartz 整合二:调度管理与定时任务分离
新的应用场景:很多时候,我们常常会遇到需要动态的添加或修改任务,而spring中所提供的定时任务组件却只能够通过修改xml中trigger的配置才能控制定时任务的时间以及任务的启用或停止,这在带给我们 ...
- Spring Boot2(十二):手摸手教你搭建Shiro安全框架
一.前言 SpringBoot+Shiro+Mybatis完成的. 之前看了一位小伙伴的Shiro教程,跟着做了,遇到蛮多坑的(´இ皿இ`) 修改整理了一下,成功跑起来了.可以通过postman进行测 ...
- spring boot2.0(二 ) lettcute访问redis
前言 此处已经省略redis的安装,请自行百度查找redis的服务端安装过程. 1.pom文件配置: <project xmlns="http://maven.apache.org/P ...
- Spring Boot2(十五):Shiro记住我rememberMe、验证码Kaptcha
接着上次学习的<Spring Boot2(十二):手摸手教你搭建Shiro安全框架>,实现了Shiro的认证和授权.今天继续在这个基础上学习Shiro实现功能记住我rememberMe,以 ...
- Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
本文是 Spring Boot 整合数据持久化方案的最后一篇,主要和大伙来聊聊 Spring Boot 整合 Jpa 多数据源问题.在 Spring Boot 整合JbdcTemplate 多数据源. ...
随机推荐
- c# 大批量用户访问数据库报错
报错信息:There is already an open DataReader associated with this Connection which must be closed first ...
- 升级ssh到OpenSSH_7.5p1
Redhat 6.5 x64升级SSH到OpenSSH_7.5p1 为了防止openssh安装失败导致不能远程登录,先部署telnet服务以防万一. rpm -qa telnet telnet-ser ...
- C#一个窗体调用另一个窗体的方法
一个窗体调用另一个窗体的方法:例如:窗体B要调用窗体A中的方法1.首先在窗体A中将窗体A设为静态窗体public static FormA m_formA; //设此窗体为静态,其他窗体可调用此 ...
- 【Java基础】16、小数的浮点型和定点型
一.简介 1.对于不需要任何准确计算精度的数字可以直接使用浮点型,但是如果需要精确计算的结果,则必须使用定点型(BigDecimal类) 浮点型:float,double 定点型:BigDecimal ...
- Advanced redirection features
here are three types of I/O, which each have their own identifier, called a file descriptor: standar ...
- es6 语法 (字符串扩展)
{ console.log('a',`\u0061`); //a,a console.log('s',`\u20BB7`); //s ₻7 console.log('s',`\u{20BB7}`) / ...
- Ambari架构源码解析
1. Ambari介绍 Apache Ambari是一种基于Web的工具,支持Apache Hadoop集群的供应.管理和监控.Ambari已支持大多数Hadoop组件,包括HDFS.MapReduc ...
- SuperMap iClient for JavaScript image出图
SuperMap iClient for JavaScript 客户端基于openlayers 开发. 目前最高版本为811,9D产品后推荐客户使用leaflet.openlayers客户端开发. 问 ...
- JMeter 中实现发送Java请求
JMeter 中实现发送Java请求 1. 步骤1 新建JAVA项目 File -> New -> Java Project 如上图,填写Project Name,然后Next,打开以J ...
- Statement和PreparedStatement的异同
1.首先两个都是java向数据库执行sql语句的对象! java代码连接数据库,并且执行sql语句的步骤如下: //1.注册数据库的驱动程序 Class.forName(driverClass); / ...