SpringData JPA的常用语法汇总

2023-01-21 0 4,745

目录

前言

SpringData JPA常用有两种写法一个是用Jpa自带方法进行CRUD适合简单查询场景、例如查询全部数据、根据某个字段查询,根据某字段排序等等。另一种是使用注解方式@Query@Modifying

1.方法方式

方法说明

接口方法如下,方法作用见注释:

public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    // 无条件,查询全部记录
    List<T> findAll();
    // 排序查询
    List<T> findAll(Sort var1);
    // 根据主键ID查询
    List<T> findAllById(Iterable<ID> var1);
    // 批量保存集合数据
    <S extends T> List<S> saveAll(Iterable<S> var1);

    void flush();
 
    <S extends T> S saveAndFlush(S var1);
    // 批量删除
    void deleteInBatch(Iterable<T> var1);
    // all in 全部删除
    void deleteAllInBatch();
    // 查询一条记录
    T getOne(ID var1);
    // 条件查询
    <S extends T> List<S> findAll(Example<S> var1);
    // 条件查询,带排序
    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

例子

一般dao实现JpaRepository接口,直接调用JpaRepository中的方法就可以实现了简单查询,例如查询User实例列表:

// 构建user的Example对象
Example<User> example =Example.of(User);
List<User> users = userRepository.findAll(example);

2.注解方式

jpa实现CRUD的主要注解是@Query

注解说明

@Query注解主要有以下参数,参数作用如下:

  • value:SQL语句
  • countQuery: 分页查询时统计总数
  • nativeQuery: 使用执行这个方法的时候执行原生sql语句,直接写数据库中的实际表名和表的实际字段名

@Query的代码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@QueryAnnotation
@Documented
public @interface Query {
    String value() default \"\";
    String countQuery() default \"\";
    String countProjection() default \"\";
    boolean nativeQuery() default false;
    String name() default \"\";
    String countName() default \"\";
}

例子

  • 使用注解方式分组查询

跟正常写sql语句相同,将sql写到value中,并且nativeQuery = true。下面例子是根据task_id进行分组查询task集合

@Query(value = \"select task_id from task group by task_id\", nativeQuery = true)
List<Task> queryByGroup();
  • 使用注解方式排序

根据task_id进行排序查询task集合

@Query(value = \"select task_id,task_date from task order by task_id\", nativeQuery = true)
List<Task> queryOrder();
  • 使用注解方式条件查询

条件查询时可以使用字段名 操作符 ?;例如:task_date >= ?,使用位置匹配?。也可以使用字段名 操作符 :属性名;例如:task_date >= :startDate,使用属性名匹配,推荐使用后者,如果字段顺序修改,不影响匹配结果。下面是根据任务时间(task_date)段内和未被删除(deleted)的任务

@Query(value = \"select task_id,task_date from task where task_date >=? and task_date <=? and deleted=0 \", nativeQuery = true)
List<ApptTask> queryDate(@Param(\"startDate\") String startDate, @Param(\"endDate\") String endDate);
  • 使用注解方式修改

修改一条数据需要加上@Modifying用于标识是修改操作,默认事务等级是只读,所以还需要加上@Transactional,这样覆盖了默认的@Transactional才可以执行修改操作。下面是根据task_id更新task表的备注信息

@Transactional(rollbackOn = Exception.class)
@Modifying
@Query(value = \"update task set remark = ? where task_id=?\", nativeQuery = true)
void updateRemark(@Param(\"remark\") String remark, @Param(\"taskId\") String taskId);

多表联查,且多条件、分页查询怎么写?

复杂的查询需要注意,以下使用一个Mysql的多表联查的例子来说明复杂的查询要怎么写。下面是usertask表关联查询出任务名称、任务ID、用户名称这些信息,并且根据task_nametask_date进行过滤;根据task_date倒序。

共有几点需要注意:

  • 多表联查使用正常的JOIN就可以
  • 多条件是常见的情况,需要区别传入的条件是否要去执行,这种情况需要使用where 1=1 and 这种方式来保证条件不传时仍然正常查询。
  • 分页查询需要传入分页参数Pageable,并且写countQuery来统计总数。
  • 多条件查询关键:if(:参数!='',k.字段名 =:参数,1=1),这里是使用了if进行判断,这个写法类似Mybatis xml中的<if>标签。if的含义是代表传入的参数如果不为""(Spring类型空是""而不是null)将参数传入,如果为空时显示1=1 代表参数为真,对查询结果不产生作用。

代码:

@Query(value =
      \" select a.task_name, a.task_id,u.user_name\" +
      \" from task a \" +
      \" LEFT JOIN usert u\" +
      \" ON a.user_id = u.user_id\" +
      \" where  a.deleted=0  \" +
      \" AND if(:taskName!=\'\',a.task_name =:taskName,1=1)\" +
      \" AND if(:startDate!=\'\',a.task_date >=:startDate,1=1)\" +
      \" AND if(:endDate!=\'\',a.task_date <=:endDate,1=1)\" +
      \" order by a.task_date desc\"
      , 
      nativeQuery = true
      , 
      countQuery =
      \" select count(*)\" +
      \" from task a \" +
      \" LEFT JOIN usert u\" +
      \" ON a.user_id = u.user_id\" +
      \" where  a.deleted=0  \" +
      \" AND if(:taskName!=\'\',a.task_name =:taskName,1=1)\" +
      \" AND if(:startDate!=\'\',a.task_date >=:startDate,1=1)\" +
      \" AND if(:endDate!=\'\',a.task_date <=:endDate,1=1)\" +
      \" order by a.task_date desc\")
Page<Map<String,Object>> queryUserTaskPage(@Param(\"taskName\") String taskName, @Param(\"startDate\") LocalDate startDate, @Param(\"endDate\") LocalDate endDate, @Param(\"pageable\") Pageable pageable);

小结

以上列举了两种JPA的crud方式,jpa方法与注解方式,平时写代码时更倾向于使用注解方式去写原生sql来实现业务。对于简单查询可以用JpaRepository里面这些方法就够用了,对于更复杂的场景推荐使用@Query写sql的方式来实现。

jpa方法可以屏蔽底层的sql,如果有不同数据库实现的服务,用jpa方法可以免于修改sql。但是jpa方法对于分组查询、limit支持、多条件、多表联查这些不太友好。

总结

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 SpringData JPA的常用语法汇总 http://www.20zxx.cn/462948/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务