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工具与之的整合

首先我的开发环境:
jdk1.8+maven3+IDEA

1. 完善pom文件



    4.0.0

    springboot-jpa
    springboot-jpa
    0.0.1-SNAPSHOT
    jar

    springboot-jpa
    Demo project for Spring Boot

    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.0.RELEASE
         
    

    
        UTF-8
        UTF-8
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter
        

        
            org.springframework.boot
            spring-boot-starter-test
        

        
            org.springframework.boot
            spring-boot-starter-web
        
        
            mysql
            mysql-connector-java
        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        

        
            org.projectlombok
            lombok
            1.16.18
        
        
            org.springframework.boot
            spring-boot-test
            1.4.5.RELEASE
            test
        
        
        
            com.querydsl
            querydsl-jpa
        
        
            com.querydsl
            querydsl-apt
            provided
        
        
        
            com.alibaba
            druid
            1.0.26
        
        
        
            com.alibaba
            fastjson
            1.2.15
        
        
            com.alibaba
            druid
            1.1.3
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
            
            
                com.mysema.maven
                apt-maven-plugin
                1.1.3
                
                    
                        
                            target/generated-sources/java
                            com.querydsl.apt.jpa.JPAAnnotationProcessor
                        
                    
                
            
        
    




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 {

    //自定义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 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 optional = userRepository.findById(id);
        User user = optional.get();
        return user;
    }

    /**
     * 查询全部列表,并做分页
     *  @param pageNum 开始页数
     * @param pageSize 每页显示的数据条数
     */
    @Override
    public Iterator selectAll(int pageNum, int pageSize) {
        //将参数传给这个方法就可以实现物理分页了,非常简单。
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = new PageRequest(pageNum, pageSize, sort);
        Page users = userRepository.findAll(pageable);
        Iterator userIterator =  users.iterator();
        return  userIterator;
    }
}

分页不止可以这样做,也可以在Controller层进行实例化和初始化然后将Pageable对象传给Service。
当然也可以对分页进行封装,封装后的展示。

    Page 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 selectAll(@PathVariable("pageNum") int pageNum, @PathVariable("pageSize") int pageSize){
        Iterator userIterator = userService.selectAll(pageNum, pageSize);
        List 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

你可能感兴趣的:(spring boot2 整合(二)JPA(特别完整!))