spring boot2 整合(二)JPA(特別完整!)
JPA全稱Java Persistence API.JPA通過JDK 5.0註解或XML描述物件-關係表的對映關係,並將執行期的實體物件持久化到資料庫中。
JPA 的目標之一是制定一個可以由很多供應商實現的API,並且開發人員可以編碼來實現該API,而不是使用私有供應商特有的API。
JPA是需要Provider來實現其功能的,Hibernate就是JPA Provider中很強的一個,應該說無人能出其右。從功能上來說,JPA就是Hibernate功能的一個子集。
本教程大概流程:
1. 藉助idea實現springboot 和 spring data jpa 整合
2. 實現JpaRepository介面快捷開發
3. 自定義Mapper查詢介面方法
4. MVC架構+分頁功能實戰
5. QueryDSL工具與之的整合
6. EntityManager的使用
首先我的開發環境:
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工具與上文的整合
注意一點,目前springboot2.0 版本對JPA支援有誤,如果你用springboot2 來配置querydsl,application啟動類會執行不起來,正確的依賴包或者是配置類我還沒有找到,希望有點子的朋友可以和我聯絡。 本人QQ:844072586