美文网首页SpringBoot专题
SpringBoot入门建站全系列(六)Spring-data-

SpringBoot入门建站全系列(六)Spring-data-

作者: 逍遥天扬 | 来源:发表于2019-06-11 17:47 被阅读11次

    SpringBoot入门建站全系列(六)Spring-data-jpa进阶使用

    上一篇介绍了Mybatis的配置和基本用法《SpringBoot入门建站全系列(五)使用Spring-data-jpa操作数据库CRUD》

    这一篇在此基础上进阶使用Spring-data-jpa。

    所以,这里就不说怎么怎么配置了,直接写Spring-data-jpa的写法,至于调用,dao层的自己用service调就可以了,需要service配合的会写出来部分逻辑。

    Git地址:
    Gitee

    项目地址:
    品茗IT-同步发布

    品茗IT 提供在线支持:

    一键快速构建Spring项目工具

    一键快速构建SpringBoot项目工具

    一键快速构建SpringCloud项目工具

    一站式Springboot项目生成

    Mysql一键生成Mybatis注解Mapper

    一、普通写法

    Spring-data-jpa支持继承接口中的所有方法直接调用,同时也支持以下几种简便使用方法:

    • find…By,read…By,query…By,count…By,和get…By: 这些写法具体使用需要到官方网站上查询,东西太多了。这里只写出findBy的部分用法。

    findBy的Spring-data-jpa官方示例:

    Keyword Sample JPQL snippet
    And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
    Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
    Is,Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
    Between findByStartDateBetween … where x.startDate between ?1 and ?2
    LessThan findByAgeLessThan … where x.age < ?1
    LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
    GreaterThan findByAgeGreaterThan … where x.age > ?1
    GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
    After findByStartDateAfter … where x.startDate > ?1
    Before findByStartDateBefore … where x.startDate < ?1
    IsNull findByAgeIsNull … where x.age is null
    IsNotNull,NotNull findByAge(Is)NotNull … where x.age not null
    Like findByFirstnameLike … where x.firstname like ?1
    NotLike findByFirstnameNotLike … where x.firstname not like ?1
    StartingWith findByFirstnameStartingWith … where x.firstname like ?1(parameter bound with appended %)
    EndingWith findByFirstnameEndingWith … where x.firstname like ?1(parameter bound with prepended %)
    Containing findByFirstnameContaining … where x.firstname like ?1(parameter bound wrapped in %)
    OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
    Not findByLastnameNot … where x.lastname <> ?1
    In findByAgeIn(Collection<Age> ages) … where x.age in ?1
    NotIn findByAgeNotIn(Collection<Age> ages) … where x.age not in ?1
    TRUE findByActiveTrue() … where x.active = true
    FALSE findByActiveFalse() … where x.active = false
    IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)
    • deleteBy:删除,后面跟字段即可。

    二、JPQL和原生SQL

    JPQL写法:

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query("select u from User u where u.emailAddress = ?1")
      User findByEmailAddress(String emailAddress);
    
      @Query("select u from User u where u.firstname like %?1")
      List<User> findByFirstnameEndsWith(String firstname);
    
      @Modifying
      @Query("update User u set u.firstname = ?1 where u.lastname = ?2")
      int setFixedFirstnameFor(String firstname, String lastname);
    
      @Modifying
      @Query("delete from User u where user.role.id = ?1")
      void deleteInBulkByRoleId(long roleId);
    }
    

    原生SQL写法:

    无它,就是SQL语句。需要注意的是,返回的实体要是表对应实体。

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
      User findByEmailAddress(String emailAddress);
    
    }
    

    三、排序

    可以使用Sort传参。

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query("select u from User u where u.lastname like ?1%")
      List<User> findByAndSort(String lastname, Sort sort);
    
    }
    

    也可以通过方法名称来进行排序。

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query("select u from User u where u.lastname like ?1%")
      List<User> findByAndSort(String lastname, Sort sort);
    
      List<User> findByLastnameOrderByFirstnameAsc(String lastname);
      List<User> findByLastnameOrderByFirstnameDesc(String lastname);
    }
    

    四、分页

    通过传递Pageable参数进行分页,切记,分页页码是从0开始的。

    Pageable也可以进行排序。

    public interface UserRepository extends JpaRepository<User, Long> {
    
      Page<User> findByLastname(String lastname, Pageable pageable);
    
    }
    

    五、动态SQL

    Spring-data-jpa已经很方便了,但是有时候我们有的参数为空,这时我们不想让这些参数作为条件查询,笨办法就是去写n个方法,当然也有好办法了,那就是JpaSpecificationExecutor:

    @Repository
    public interface RdTaskDao extends JpaRepository<RdTask, Integer>, JpaSpecificationExecutor<RdTask> {
    
    }
    

    使用以下sql组装Specification,然后调用findAll进行查询。

    Specification<RdTask> querySpecifi = new Specification<RdTask>() {
                private static final long serialVersionUID = 1L;
    
                @Override
                public Predicate toPredicate(Root<RdTask> root, CriteriaQuery<?> criteriaQuery,
                                             CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicates = new ArrayList<>();
    
                    //未删除标识
                    predicates.add(criteriaBuilder.equal(root.get("deleteFlag"), 0));
    
                    if (!StringUtils.isEmpty(rdTaskListReq.getCreator())) {
                        predicates.add(criteriaBuilder.equal(root.get("creator"), rdTaskListReq.getCreator()));
                    }
                    if (!StringUtils.isEmpty(rdTaskListReq.getDesignater())) {
                        predicates.add(criteriaBuilder.equal(root.get("designater"), rdTaskListReq.getDesignater()));
                    }
                    if (null != rdTaskListReq.getType()) {
                        predicates.add(criteriaBuilder.equal(root.get("type"), rdTaskListReq.getType()));
                    }
                    if (null != rdTaskListReq.getStatus()) {
                        if (rdTaskListReq.getStatus().equals("doing")) {
                            predicates.add(criteriaBuilder.equal(root.get("status"), "doing"));
                        } else if (rdTaskListReq.getStatus().equals("closed")) {
                            predicates.add(criteriaBuilder.equal(root.get("status"), "closed"));
                        }
                    }
    
                    return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                }
            };
    
            Pageable pageable = PageRequest.of(rdTaskListReq.getPage(), rdTaskListReq.getPageSize(), Direction.DESC, "createTime");
            Page<RdTask> page = rdTaskDao.findAll(querySpecifi, pageable);
    

    详细完整代码,可以访问品茗IT-博客《SpringBoot入门建站全系列(六)Spring-data-jpa进阶使用》,也可以在Spring组件化构建中选择查看,并下载。

    六、 事务

    @Transactional注解开启事务。可以注解在类上,也可以注解在方法上。Spring对更新删除操作强制要求加上@Transactional注解。

    @Transactional使用没多少注意的事情,除非是要求特别严格的系统,那就别看乱七八糟的博客,去看官方文档,博客只能带你入门,知道有哪些东西。

    @Transactional一般配置下异常的捕获rollbackFor属性,默认情况下只捕获RuntimeException,可以将注解在方法上的@Transactional改为:

    @Transactional(rollbackFor=Exception.class)
    

    这样就会捕获所有异常。

    mysql的MyISAM引擎不支持事务,切记。

    快速构建项目

    Spring组件化构建

    喜欢这篇文章么,喜欢就加入我们一起讨论SpringBoot技术吧!


    品茗IT交流群

    相关文章

      网友评论

        本文标题:SpringBoot入门建站全系列(六)Spring-data-

        本文链接:https://www.haomeiwen.com/subject/fbnqfctx.html