IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> SpringDataJPA使用jpql 原生sql 方法命名规则 实现多表联查和分页 -> 正文阅读

[大数据]SpringDataJPA使用jpql 原生sql 方法命名规则 实现多表联查和分页

这个也是我本次要写的过程中最想着重说的一个点,应为在写这个SQL 中遇到了很多坑,比如要进行多表联查的过程中就需要返回一个VO对象,在返回对象的时候需要进行相关的考虑和相关的设计,所以在进行相关的查询过程中,还要遵循JPA的语法规范,所以这些就比较难

这个是GItee地址想学的可以参考一下

SpringBootDataJpaDemo: 学习SpringBoot-Data-Jpa的demo工程,包含了jpa基本查询 ,example对象查询,Specification动态查询 以及分页等案例 - Gitee.com

jpql查询

jpql多表联查方式有两种

  • 使用VO(view object)做映射与投影; 即建立一个vo类,该类中包含了要查询的字段,然后在jpql中使用new 类名(属性1,属性2.......) from 的方式查询

    注意:一定要使用new 的方式 且最好使用类名的完全限定名 ,字段的位置必须一致

  • 使用接口方式接收 属性分命名为 getXXX ,****如?getMenuId() 方式 ;

推荐使用VO方式查询

1.VO方式查询

  • 新建一个vo实体
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SysMenuRoleDTO {
    private Long menuId;
    private String menuName;
    private Long roleId;
    private String roleName;
}
  • 写查询接口
 @Query("select new com.lonni.dtos.SysMenuRoleDTO(menu.menuId,menu.menuName,ro.roleId,ro.roleName) from SysMenu  menu join SysRoleMenu ru on menu.menuId=ru.menuId " +
            "join  SysRole ro on ro. roleId=ru.roleId")
    Page<SysMenuRoleDTO> getMenuRoleDto(Pageable pageable);

注意这个地方是用了一个LEFT JOIN进行了一个多表的关联查询,查询的时候可以关联处理多个对象可以通过一种 new 的方式进行使用,但是这样代码看起来很难看

注意这里: new com.lonni.dtos.SysMenuRoleDTO(menu.menuId,menu.menuName,ro.roleId,ro.roleName)

这里一定要是new 的方式 且最好使用完全限定名,否则会找不到

  • 调用接口
 @Test
    public void  testJpqlJoinVo(){
        Page<SysMenuRoleDTO> menuRoleDto = dao.getMenuRoleDto(PageRequest.of(0, 1));
        System.out.println(menuRoleDto);
        System.out.println(menuRoleDto.getTotalElements());
        System.out.println(menuRoleDto.getContent());
        System.out.println(menuRoleDto.getTotalPages());
    }

2.使用接口方式

这个方式就使用JPA的代理类来实现的使用此次方式可以更好的简化代码

  • 新建一个接口

注意格式,一定要是getXXX的方式

/**
 * 使用接口方式接收返回值
 */
public interface SysMenuRole {

     Long getMenuId();
     String getMenuName();
     Long getRoleId();
     String getRoleName();
}
  • 写dao层接口
//使用jpql多表查询 使用接口查询方式
    //案列 :角色拥有的菜单
    @Query("select menu.menuId,menu.menuName,ro.roleId,ro.roleName from SysMenu  menu join SysRoleMenu ru on menu.menuId=ru.menuId " +
            "join  SysRole ro on ro. roleId=ru.roleId")
    Page<SysMenuRole> getMenuRoleDtoByInterface(Pageable pageable);

这里直接就可以使用字段属性方式绑定了

  • 调用
 //测试jpql 多表查询 使用接口方式

    @Test
    public void  testJpqlJoinInterface(){
        Page<SysMenuRole> menuRoleDto = dao.getMenuRoleDtoByInterface(PageRequest.of(0, 1));
        System.out.println(menuRoleDto);
        System.out.println(menuRoleDto.getTotalElements());
        System.out.println(menuRoleDto.getContent());
        System.out.println(menuRoleDto.getTotalPages());
        List<SysMenuRole> content = menuRoleDto.getContent();
        for (SysMenuRole sysMenuRole : content) {
            System.out.println(sysMenuRole.getMenuId());
            System.out.println(sysMenuRole.getMenuName());
        }

    }

原生sql查询

基本语法

原生sql查询和jpql一样,只是需要设置query注解的*nativeQuery=true*

语法:

@Query(value?= "select * from sys_menu menu ",nativeQuery=true)

注意:使用原生sql查询就是查询表了 ,而不是查询实体 所以from后面的一定是数据库表名,且属性一定是数据库字段

分页

  • 分页的返回值不能是javaBean,因为使用原生sql查询了,就不会有字段映射了,最好使用Page<Map>
  • 分页直接加上 Pageable 参数
  • 原生sql****分页时不能使用别名 ,否则报错 (折腾了很久o.o)

接口定义 :

//测试原生sql是否支持分页
    //jpql 分页查询
    @Query(value = " select * from  sys_menu   ",nativeQuery = true)
    Page<Map> getSysPage(Pageable pageable);
//测试原生sql是否支持分页
    @Test
    public  void testSqlPage(){
        Page<Map> sysPage = dao.getSysPage(PageRequest.of(0, 2));
        System.out.println(sysPage.getTotalPages());
        System.out.println(sysPage.getContent());

    }

方法命名规则查询

只需要按照jpa提供的方法名称规则定义方法,不需要自定义jpql
约定:

  • findBy :标识查询操作
    对象中的属性(首字母大写):查询条件,如:findByMenuId 标识根据菜单id查询数据
    • 模糊查询?findByMenuNameLike( "测试%");?传值必须使用sql模糊匹配语法,否则还是全匹配查询
    • 多条件查询?findByMenuIdOrMenuName?;使用and or?等

注意:使用方法命名规则查询参数的顺序必须和findBy后的一致
- 使用方法定义查询 全匹配查询
List<SysMenu> findByMenuIdOrMenuName(long menuId, String menuName);
- 使用方法定义查询 模糊查询
List<SysMenu> findByMenuNameLike(String menuName);

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:31:36  更:2022-04-24 09:31:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:01:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码