spring data jpa 查询
自定义方法规则
适合单表,操作一个实体
1.支持排序orderby,单独只排序,不能分页
2.分页,直接传入参数Pageable,而且支持排序,
// 这里必须是Pageable,pageRequest不行
Page<Student> findByNameLike(String name, Pageable pageRequest);
// 返回分页的content,可以直接只取list
List<Student> findByNameLike(String name, Pageable pageRequest);
// 支持查询部分字段 定义接口 onlyName,getName(),返回值的也是这个接口QueryStudentDTO
List<QueryStudentDTO> findByNameLike(String name, Pageable pageRequest);
// 支持查询部分字段 定义类dto 注意构造方法,只能全参,不能有无参构造
List<QueryStudentDTO2> findByNameLike(String name, Pageable pageRequest);
jpql语句
// jpql的分页和排序使用
@Query(" from Student where name like ?1 order by address desc ")
List<Student> queryName2(String name, Pageable pageRequest); // 定义List返回当前页,定义Page返回分页信息
// 使用jpql实现部分查询
// 定义成map,map的key和value就是对象的 name=value,必须给出别名
// JPQL下支持分页或者排序,排序或者分页可以直接传入Pageable或者Sort 【注意,nativeSql不支持传入Pageable和Sort】
@Query(" select name as name, address as address from Student where name like ?1 order by address desc ")
List<Map<String,Object>> queryName2(String name, Pageable pageRequest);
// 定义成接口,注意要给别名,不然值为null
@Query(" select name as name, address as address from Student where name like ?1 order by address desc ")
List<QueryStudentDTO> queryName2(String name, Pageable pageRequest);
// 定义成类,需要用该类进行接收(需要定义全参构造方法),给出全路径名称
@Query(" select new com.test.model.QueryStudentDTO2(name,address) from Student where name like ?1 order by address desc ")
List<QueryStudentDTO2> queryName2(String name, Pageable pageRequest);
// 测试返回结果有聚合函数
// 可以用接口接收,注意需要起别名
@Query(" select name as name, count(name) as nameCount from Student group by name order by nameCount desc ")
List<QueryStudentDTO3> queryName2(String name, Pageable pageRequest);
// 定义成类,需要用该类进行接收,给出全路径名称
@Query(" select new com.test.model.QueryStudentDTO3Impl(name,count(name)) from Student group by name order by count(name) desc ")
List<QueryStudentDTO3> queryName2(String name, Pageable pageRequest);
原生sql语句 native sql
// 接口可以接收。 类不可以(全参构造函数也不行),这里是原生sql,不是对象映射,无法像JPQL那样写类的全路径
@Query(value = " select id, name, address from test_student where name like ?1 ", nativeQuery = true)
List<QueryStudentDTO> queryName(String name, Pageable pageRequest);
此外,如果是动态条件,可支持在代码里写原生sql进行动态拼接
Sql语句是字符串拼接而成,拼接完成后,成sql语句,交给数据库执行; 恶意注入: 拼接过程中,sql语义存在被恶意修改的可能,利用注释/or)
使用占位: 在拼接完成之前,已经从字符串转换成sql语句; 先占位,进行预编译,然后再传参数
拼接sql字符串,不使用占位符,对于参数而言,都要加引号,也就是说在sql中体现为字符串; 在sql语句中字符串就是字符串的表现形式(‘ ’/” ”);
使用占位符的时候不需要,如果是字符串,占位符会帮忙加上引号,而不是字符串的话传什么就是什么,
解析结果集
返回的对应的对象,对象的属性必须要一一对应的返回的字段值吗?
不是,可以多,但不能少,也就是查出的列要满足实体的所有字段,查出的列可以多不能少!
如果返回值只查一个字段,可以就返回String/int或其他对应的类型来接收即可
Jpa, 返回的几个列,如果单独用一个类接收,是否也需要建立表和映射关系?
用jpql就需要,类可以不完全接受所有的列(查出的列可以多不能少),但要有表的映射关系,而且要有主键; 可以映射到同一张表去
用本地nativesql就不需要映射到表,但类还是要有,而且要被返回的字段塞满;
占位符的问题
Between and / > / like 都可以
In () 要做考虑。占位后,直接传list
#{} 就是 ? 可以防止恶意注入,如果是字符串,会在sql语句中带入引号