spring boot2 整合(二)JPA(特別完整?。?/h2>

JPA全稱Java Persistence API.JPA通過JDK 5.0注解或XML描述對象-關(guān)系表的映射關(guān)系,并將運行期的實體對象持久化到數(shù)據(jù)庫中。

JPA 的目標之一是制定一個可以由很多供應(yīng)商實現(xiàn)的API,并且開發(fā)人員可以編碼來實現(xiàn)該API,而不是使用私有供應(yīng)商特有的API。

JPA是需要Provider來實現(xiàn)其功能的,Hibernate就是JPA Provider中很強的一個,應(yīng)該說無人能出其右。從功能上來說,JPA就是Hibernate功能的一個子集。

本教程大概流程:

  1. 借助idea實現(xiàn)springboot 和 spring data jpa 整合
  2. 實現(xiàn)JpaRepository接口快捷開發(fā)
  3. 自定義Mapper查詢接口方法
  4. MVC架構(gòu)+分頁功能實戰(zhàn)
  5. QueryDSL工具與之的整合

首先我的開發(fā)環(huán)境:
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>
        <!--阿里巴巴數(shù)據(jù)庫連接池,專為監(jiān)控而生 -->
        <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. 實現(xiàn)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);// 參數(shù)username 映射到數(shù)據(jù)庫字段username
}

注意:只有@Query 的注解下不能使用insert,我們需要在上面再添加個@Modify注解,我習(xí)慣都加,nativeQuery 是詢問是否使用原生sql語句。多表查詢也是在這里手寫sql,不做演示。因為后面我們用更好的支持多表查詢的工具框架 QueryDSL來幫助我們更簡潔的實現(xiàn)它。

5.實現(xiàn)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);
    /** 查詢?nèi)苛斜?/
    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;
    }

    /**
     * 查詢?nèi)苛斜?并做分頁
     *  @param pageNum 開始頁數(shù)
     * @param pageSize 每頁顯示的數(shù)據(jù)條數(shù)
     */
    @Override
    public Iterator<User> selectAll(int pageNum, int pageSize) {
        //將參數(shù)傳給這個方法就可以實現(xiàn)物理分頁了,非常簡單。
        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。
當(dāng)然也可以對分頁進行封裝,封裝后的展示。

    Page<User> datas = userRepository.findAll(PageableTools.basicPage(1, 5, new SortDto("id")));

是不是很簡潔。大家可以自己嘗試一下。

6. 實現(xiàn)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啟動類會運行不起來,正確的依賴包或者是配置類我還沒有找到,希望有點子的朋友可以和我聯(lián)系。 本人QQ:844072586

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容