• JPA学习总结



    一. 背景相关
    JDK:1.8
    IDE:IntelliJ IDEA
    db:MYSQL
    Spring Boot 结合 JPA
    Spring Boot版本:v2.0.2.RELEASE
    使用maven管理jar包


    二:POM

     1   <dependencies>
     2         <dependency>
     3             <groupId>org.springframework.boot</groupId>
     4             <artifactId>spring-boot-starter-test</artifactId>
     5             <scope>test</scope>
     6         </dependency>
     7         <!--JPA-->
     8         <dependency>
     9             <groupId>org.springframework.boot</groupId>
    10             <artifactId>spring-boot-starter-data-jpa</artifactId>
    11         </dependency>
    12         <!--热部署-->
    13         <dependency>
    14             <groupId>org.springframework.boot</groupId>
    15             <artifactId>spring-boot-devtools</artifactId>
    16             <scope>runtime</scope>
    17             <optional>true</optional>
    18         </dependency>
    19         <!--MySql数据库-->
    20         <dependency>
    21             <groupId>mysql</groupId>
    22             <artifactId>mysql-connector-java</artifactId>
    23             <scope>runtime</scope>
    24         </dependency>
    25         <!--Pageable使用QPageRequest需要这个-->
    26         <dependency>
    27             <groupId>com.querydsl</groupId>
    28             <artifactId>querydsl-jpa</artifactId>
    29         </dependency>
    30     </dependencies>
    31 
    32     <build>
    33         <plugins>
    34             <plugin>
    35                 <groupId>org.springframework.boot</groupId>
    36                 <artifactId>spring-boot-maven-plugin</artifactId>
    37                 <configuration>
    38                     <fork>true</fork>
    39                 </configuration>
    40             </plugin>
    41         </plugins>
    42     </build>



    三:材料准备
    两张实体表 teacher、studnett

     1 @Entity
     2 @Table(name = "student")
     3 public class Student {
     4 
     5 @Id
     6 @GeneratedValue
     7 private Long id;
     8 @Column(name = "stu_name")
     9 private String stuName;
    10 
    11 ....


    注意: get、set方法自行完善

    四. 主要总结内容
    (1)Repository
    (2)CrudRepository
    (3)PagingAndSortingRepository
    (4)JpaRepository
    (5)JpaSpecificationExecutor

    1. repository继承图示

    继承关系是:
    JpaRepository 继承PagingAndSortingRepository,PagingAndSortingRepository继承CrudRepository,CrudRepository继承Repository

    可以看出:
    (1)都是接口
    (2)上面的的继承关系中并没有JpaSpecificationExecutor,这个是独立的

    2. Repository接口
      先点进去,看看,是一个空接口,也就是一个标记接口

      继承这个接口能干什么?查询
      满足其一定的命名规范去书写方法名,可以不用自己写sql语句,直接执行查询


      示例:

      测试:

     

      结果:

     

      解释:我们可以在Repository里自定义方法,但是命名规范是定死的,不是大风刮来的,比如说,方法名的开头一般以 find | get | read 为开头

      看图:

      具体的命名规范,建议看官方文档https://docs.spring.io/spring-data/jpa/docs/2.0.7.RELEASE/reference/html/

      总结:
        自定义一个接口,继承Repository接口,满足一定命名规范书写方法名,就可以不用手写sql语句,执行查询操作

    3.@Query注解
      上面已经说了,继承Repository接口,即可实现查询,那么增删改查呢中的增删改呢?
      好的,使用@Query注解,可以实现增、删、改。

      准备:

         A. 此时,需要书写JPQL语句,并且需要用到三个注解@Query、@Modifying、@Transactional
         B. 方法分为有参和无参

      (1)以更新操作为例子
         1)这里先以无参方法为例,实现一个修改的操作

      一般在service层开启注解

      开始测试:

      结果:


      2)带参方法,实现一个修改的操作
        传参方式有两种:命名参数、占位符
        先来第一种:
          英文的冒号   ‘ :’ ,后面加上自定义的名字,冒号和名字之间无空格
          这里还漏了一点,使用命名参数传参,需要在参数中使用@Param注解,里面的值要和JPQL里定义参数名的一样

      A. 使用命名参数示例:

     

     

      service层记住开启注解

      测试:

      结果:

      注意:

        其实还有一点,这一点可以和接下来的占位符进行比较,
        当有参方法有两个及以上参数时,比如下面这个,参数的传递顺序随意,因为有@Param限定好了


      B. 使用占位符示例:

      英文的  '?' ,后面跟着的1啊、2啊或者3456等等,组合起来就表示第一个占位符,第二个占位符...
      注意:因为使用占位符,参数传递顺序严格按照JPQL语句中的顺序,不能乱,这与使用命名参数传参的不同


      所以,我建议使用命名参数传参,免得错乱!

      (3)如果不熟JPQL语句怎么办?用原生sql语句查询
        将上面那个改造一下

      nativeQuery = true 即为使用原生sql
      注意:因为是原生sql语句,所有记得表名和字段都要和数据库字段属性一一对应起来

      (4)为什么会有JPQL语句?为什么还支持原生sql语句?
        就用官方事先实现好的,以及满足JPA命名规范的自定义方法去查询或者更新不行吗?
        还真不行!
        比如说,我这有个子查询,怎么查?查不了吧。。。
        这里用JPQL或者原生sql就很简单


      (5)like模糊查询
        这里讲讲使用@Query的模糊查询,主要是 '%'的用法,有两种


        1)传递参数时,在参数两边用%

        2)直接写在@Query里


        推荐使用第二种,传参就老老实实传参,别瞎折腾

        总结:
          1> 记住  @Query、@Modifying、@Transactional、@Param 这四个注解的用处
          2> 使用JPQL语句可以执行查询、修改、删除的操作,不能进行增加数据的操作
          3> 使用原生sql语句可以实现增的操作,就是nativeQuery = true(上面忘记说了)
          4> 默认情况下,spring Data 的每个方法上都有事务,但都是只读事务(read-only),是无法完成修改数据的操作行为的,所以,若是涉及到对数据进行改动的操作,请开启事务@Transactional
          5> 带参方法传参有两种方式,命名参数、占位符,我个人推荐命名参数
          6> like 模糊查询传参也有两种方式,个人建议直接写在JPQL语句内更好

    4. CrudRepository接口
      先点进去,看看,可以看出官方已经定义好了一些常用CRUD的方法

      方法都是见名知义啊,就不多做解释了
      举个例子吧:
      之前我们已经写好一个findAll的方法,现在我把他给注释了

      然后就报错了

      因为我的返回类型和官方的不一样

      

      改改呗:

      这种时候,这些简单CRUD方法,就不用自己写了,也就是说,自己既可以不用写sql,也不用写自定义方法,用官方提供的现成的就行

      总结:自定义一个接口,继承CrudRepository接口,直接就可以调用官方提供的一套现成的CRUD方法,美滋滋


    5. PagingAndSortingRepository接口
      这个也是见名知义的 --分页、排序用的
      点进去,看看

      好的,来实现一个分页排序功能
      在这之前,我先把之前的表删了,重新生成,再造点数据,都是官方提供的deleteAll、save方法


      现在数据库中的数据长这样

      (1)分页
      我想把写好的方法给大家看看,之后再解释

      然后结果:

      每页显示5条记录,第三页,id从16开始,这不扯犊子吗?id不应该从11开始吗?
      这是第一个问题:page的索引是从0开始的,所以,改一下


      结果:

      第二个问题:这个id是从11开始了,但是这应该是第三页啊。
      再改

      (2)分页好了,还有排序


      总结:PagingAndSortingRepository接口主要就是用来实现分页排序的

    6. JpaRepository接口
      老规矩,点进去看看

      总结:这个嘛,没什么好说的,看方法名就可以了

    7. JpaSpecificationExecutor接口,最后一个


      问题:他是用来干嘛的?
      解释:还是用来分页,但是是用他来组合条件分页

      回想一下上面实现的分页功能,除了传进去一个起始页和一个每页显示记录数以及排序条件,还传了什么?
      没了,就这三个。够用吗,不够啊。
      我想带个参数模糊查询不给啊?
      我想带个id比较比较不给啊?

      OK!
      在上面实现分页的基础上,我增加两个条件,一个是模糊查询,一个是id比较
      先看,之后我再解释

      结果:


      解释一下:
        root: 代表查询的实体类。(这里即为Student)
        criteriaQuery: 可以从中可到Root对象,即告知JPA Criteria查询要查询哪一个实体类, 还可以来添加查询条件,还可以结合EntityManager对象得到最终查询的TypedQuery对象。
        CriteriaBuilder : 用于创建Criteria 相关对象的工厂。当然可以从中获取到Predicate对象
        Predicate 类型,代表一个查询条件

      或者再将上面改改,毕竟参数都是传递过来的,不是大风刮来的


      其实这样还是有问题,思考一下,由于业务的变更,需求变更,即要判断的条件可能更多了
      这种时候,一开始就用一个数组存放条件不够优雅,毕竟数组的大小是写死的
      来来来,换成集合走一波


      总结:当你想用组合条件分页查,继承JpaRepository<T, ID>, JpaSpecificationExecutor<T>呗

      综上,
        日常使用,自定义一个接口,继承JpaRepository接口,
        又想组合条件分页查,继承JpaSpecificationExecutor接口


     

  • 相关阅读:
    查看linux文件目录的大小和文件夹包含的文件数
    linux下oracle 基本操作
    中宇 设备证书 导入配置
    as5 samba 图形配置
    QQ用户免费申领新型电子密码卡
    GRUB引导下进Linux单用户模式的三种方式
    Iptables 规则 一些简单实例和详细介绍
    Linux上JDK的 安装和卸载 详细 (转)
    Linux/Unix命令之Ethtool (设置千兆网卡速度及模式)
    oracle 下 创建数据库和用户界面操作 和sql 语句 下的创建方法
  • 原文地址:https://www.cnblogs.com/shadowdoor/p/9101644.html
Copyright © 2020-2023  润新知