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文件

<?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> 
<span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>springboot-jpa<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>springboot-jpa<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>0.0.1-SNAPSHOT<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">packaging</span>&gt;</span>jar<span class="hljs-tag">&lt;/<span class="hljs-name">packaging</span>&gt;</span> 
 
<span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>springboot-jpa<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">description</span>&gt;</span>Demo project for Spring Boot<span class="hljs-tag">&lt;/<span class="hljs-name">description</span>&gt;</span> 
 
<span class="hljs-tag">&lt;<span class="hljs-name">parent</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.0.0.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">relativePath</span>/&gt;</span> <span class="hljs-comment">&lt;!-- lookup parent from repository --&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">parent</span>&gt;</span> 
 
<span class="hljs-tag">&lt;<span class="hljs-name">properties</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">project.build.sourceEncoding</span>&gt;</span>UTF-8<span class="hljs-tag">&lt;/<span class="hljs-name">project.build.sourceEncoding</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">project.reporting.outputEncoding</span>&gt;</span>UTF-8<span class="hljs-tag">&lt;/<span class="hljs-name">project.reporting.outputEncoding</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">java.version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">java.version</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">properties</span>&gt;</span> 
 
<span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-test<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>mysql<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mysql-connector-java<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-data-jpa<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.projectlombok<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>lombok<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.16.18<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-test<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.4.5.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>test<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
    <span class="hljs-comment">&lt;!--querydsl依赖--&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.querydsl<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>querydsl-jpa<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.querydsl<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>querydsl-apt<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>provided<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
    <span class="hljs-comment">&lt;!--阿里巴巴数据库连接池,专为监控而生 --&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.alibaba<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>druid<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.0.26<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
    <span class="hljs-comment">&lt;!-- 阿里巴巴fastjson,解析json视图 --&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.alibaba<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>fastjson<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.2.15<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.alibaba<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>druid<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.1.3<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span> 
 
<span class="hljs-tag">&lt;<span class="hljs-name">build</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">plugins</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span> 
            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-maven-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
        <span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span> 
        <span class="hljs-comment">&lt;!--添加QueryDSL插件支持--&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span> 
            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.mysema.maven<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> 
            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>apt-maven-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> 
            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.1.3<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> 
            <span class="hljs-tag">&lt;<span class="hljs-name">executions</span>&gt;</span> 
                <span class="hljs-tag">&lt;<span class="hljs-name">execution</span>&gt;</span> 
                    <span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span> 
                        <span class="hljs-tag">&lt;<span class="hljs-name">outputDirectory</span>&gt;</span>target/generated-sources/java<span class="hljs-tag">&lt;/<span class="hljs-name">outputDirectory</span>&gt;</span> 
                        <span class="hljs-tag">&lt;<span class="hljs-name">processor</span>&gt;</span>com.querydsl.apt.jpa.JPAAnnotationProcessor<span class="hljs-tag">&lt;/<span class="hljs-name">processor</span>&gt;</span> 
                    <span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span> 
                <span class="hljs-tag">&lt;/<span class="hljs-name">execution</span>&gt;</span> 
            <span class="hljs-tag">&lt;/<span class="hljs-name">executions</span>&gt;</span> 
        <span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">plugins</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">build</span>&gt;</span> 

</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;

<span class="hljs-meta">@Column</span>(nullable = <span class="hljs-keyword">false</span>) 
<span class="hljs-keyword">private</span> String username; 
<span class="hljs-meta">@Column</span>(nullable = <span class="hljs-keyword">false</span>) 
<span class="hljs-keyword">private</span> Date birthday; 
<span class="hljs-meta">@Column</span>(nullable = <span class="hljs-keyword">false</span>) 
<span class="hljs-keyword">private</span> String sex; 
<span class="hljs-meta">@Column</span>(nullable = <span class="hljs-keyword">false</span>) 
<span class="hljs-keyword">private</span> 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环境 IT虾米网
  • 使用QueryDSL与SpringDataJPA实现单表普通条件查询 IT虾米网
  • 使用QueryDSL与SpringDataJPA完成Update&Delete IT虾米网
  • 使用QueryDSL与SpringDataJPA实现多表关联查询 IT虾米网

注意一点,目前springboot2.0 版本对JPA支持有误,如果你用springboot2 来配置querydsl,application启动类会运行不起来,正确的依赖包或者是配置类我还没有找到,希望有点子的朋友可以和我联系。 本人QQ:844072586

      </div> 

原文地址:IT虾米网


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: SELECT command denied to user 'xxxx'@''知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。