Spring Data Jpa系列教程(四)--------高级查询
2018-03-09 15:33
417 查看
本章介绍一下Spring Data Jpa高级查询,上一章讲的JPQL,JPQL使用起来非常方便,但是如果SQL有一个词不小心写错了,只有在程序运行时才能发现错误在哪,这是一个弊端,如果想要在编译器发现错误该怎么做呢,答案是使用Spring Data Jpa高级查询。
一、Criteria查询@PersistenceContext
private EntityManager entityManager; 首先注入entityManager CriteriaBuilder cb = entityManager.getCriteriaBuilder (); // criteriaQuery工厂
CriteriaQuery cq = cb.createQuery(); //查询语句构造器
Root<User> root = cq.from(User.class); //获取查询根对象
cq.select(root); // select u from User u
Predicate pre = cb.greaterThan(root.get("age").as(Integer.class), 20); // age大于20
cq.where(pre); // select u from User u where u.age > 20
// 上面这一串的目的就是为了构造出 select u from User u where u.age > 20 的JPQL语句
Query query = em.createQuery(cq);
List<User> users = query.getResultList();
这就是一个简单的Criteria查询的例子了,下面说一下怎么使用动态参数,在上方参数20的地方改成: Predicate pre = cb.greaterThan(root.get("age").as(Integer.class), cb.parameter(Integer.class, "age"));
//然后在后面:
query.setparameter("age", 20);只查询部分字段:
把cq.select(root)改成cq.select(root.get("age"))即可;
有多个字段就 cq.multiselect(root.get("age"), root.get("name").......)即可;
此时,结果集映射有两种方法
①List<User> 改成List<Object[]>,手动设置值到实体属性的映射;
②cq.select(cb.construct(User.class, root.get("age"),.......其他字段....)); 使用构造方法自动转换成实体
Fetch查询:
在cq.select 前加上: Fetch rootFetch = root.fetch("interests"); // 关联查询出用户的所有性趣 想要在程序中手动控制fetch,需要先再@ManyToMany等其他注解中将fetch设置成懒加载,然后在程序中控制。
设置JOIN:
在cq.select前加:root.join("interests", JoinType.LEFT); // select u from User u left join u.interests where u.age > 20结果集排序:
在cq.orderBy后面: cq.orderBy(cb.desc(root.get("age")), cb.asc(root.get("name")));多个查询条件: Predicate pre = cb.greaterThan(root.get("age").as(Integer.class), 20); // age大于20
Predicate pre2 = cb.lessThan(root.get("age").as(Integer.class), 40); // age小于20
cq.where(pre)改成cq.where(pre,pre2); 也可以使用cb来设置and,or的关系,如; cq.where(cb.and(pre, pre2));
二、使用JpaSpecificationExcutor查询 public interface UserRepository extends JpaRepository<User, Integer> , JapSpecificationExecutor<User>{
} repository继承了JapSpecificationExecutor之后,在UserServiceImpl中调用userRepository : public List<User> getUsers(){
return userRepository.findAll(new Specification<User>(){
@Override
public Predicate toPredicate(Root<User>, CriteriaQuery<?> cq, CriteriaBuilder cb){
List<Predicate> preList = new ArrayList();
// 跟上面Criteria的条件构造是一样的
// ..........
// ..........
// 条件构造完毕,都在 preList 里面
return cq.where(preList.toArray(new Predicate[preList.size()])).getRestriction();
}
}) ;
} 三、@Query和@NamedQuery查询
这个注解允许我们在借口的方法处使用自定义的查询语句(JPQL或者SQL),public interface UserRepository extends JpaRepository<User, Integer> , JapSpecificationExecutor<User>{
@Query(value="select u from User u where name like ?1") // 这里可以使用位置参数
public List<User> findUserByName(String name);
// @Query(value="select u from User u where name like :name") 这里也可以使用命名参数
// public List<User> findUserByName(@Param("name") String name);
} 如果想使用原生sql的话,@Query注解里有一个属性可以配置:
@Query(value="select u from user u where name like ?1", nativeQuery = true) // 设置为true就表示使用原生sql查询 @NamedQuery:命名查询,是调用实体管理器来执行的命名查询,有一些经常用到的查询,我们把它先写好,之后根据名称直接调用即可。
@NamedQuery的自定义查询写到实体上, @NamedQuery(name = "findUserByName", query="select u from User s where u.name like ?1")
@Entity
@Table("user")
public class User {} 使用实体管理器调用: // 使用命名查询
entityManager.createNamedQuery("findUserByName");
query.setParameter(1, "%王%");
List<User> users = query.getResultList(); 当有多个命名查询时,可用@NamedQueries包裹起来
@NamedQueries({
@NamedQuery(name = "findUserByName", query="select u from User s where u.name like ?1"),
@NamedQuery(name = "findUserByName2", query="select u from User s where u.name like ?1"),
@NamedQuery(name = "findUserByName2", query="select u from User s where u.name like ?1")
})
@Entity
@Table("user")
public class User {}好,本节课程就到这里,下课~~~~~~~~~~!!!!!!!!!!!!!!!!!!!!
一、Criteria查询@PersistenceContext
private EntityManager entityManager; 首先注入entityManager CriteriaBuilder cb = entityManager.getCriteriaBuilder (); // criteriaQuery工厂
CriteriaQuery cq = cb.createQuery(); //查询语句构造器
Root<User> root = cq.from(User.class); //获取查询根对象
cq.select(root); // select u from User u
Predicate pre = cb.greaterThan(root.get("age").as(Integer.class), 20); // age大于20
cq.where(pre); // select u from User u where u.age > 20
// 上面这一串的目的就是为了构造出 select u from User u where u.age > 20 的JPQL语句
Query query = em.createQuery(cq);
List<User> users = query.getResultList();
这就是一个简单的Criteria查询的例子了,下面说一下怎么使用动态参数,在上方参数20的地方改成: Predicate pre = cb.greaterThan(root.get("age").as(Integer.class), cb.parameter(Integer.class, "age"));
//然后在后面:
query.setparameter("age", 20);只查询部分字段:
把cq.select(root)改成cq.select(root.get("age"))即可;
有多个字段就 cq.multiselect(root.get("age"), root.get("name").......)即可;
此时,结果集映射有两种方法
①List<User> 改成List<Object[]>,手动设置值到实体属性的映射;
②cq.select(cb.construct(User.class, root.get("age"),.......其他字段....)); 使用构造方法自动转换成实体
Fetch查询:
在cq.select 前加上: Fetch rootFetch = root.fetch("interests"); // 关联查询出用户的所有性趣 想要在程序中手动控制fetch,需要先再@ManyToMany等其他注解中将fetch设置成懒加载,然后在程序中控制。
设置JOIN:
在cq.select前加:root.join("interests", JoinType.LEFT); // select u from User u left join u.interests where u.age > 20结果集排序:
在cq.orderBy后面: cq.orderBy(cb.desc(root.get("age")), cb.asc(root.get("name")));多个查询条件: Predicate pre = cb.greaterThan(root.get("age").as(Integer.class), 20); // age大于20
Predicate pre2 = cb.lessThan(root.get("age").as(Integer.class), 40); // age小于20
cq.where(pre)改成cq.where(pre,pre2); 也可以使用cb来设置and,or的关系,如; cq.where(cb.and(pre, pre2));
二、使用JpaSpecificationExcutor查询 public interface UserRepository extends JpaRepository<User, Integer> , JapSpecificationExecutor<User>{
} repository继承了JapSpecificationExecutor之后,在UserServiceImpl中调用userRepository : public List<User> getUsers(){
return userRepository.findAll(new Specification<User>(){
@Override
public Predicate toPredicate(Root<User>, CriteriaQuery<?> cq, CriteriaBuilder cb){
List<Predicate> preList = new ArrayList();
// 跟上面Criteria的条件构造是一样的
// ..........
// ..........
// 条件构造完毕,都在 preList 里面
return cq.where(preList.toArray(new Predicate[preList.size()])).getRestriction();
}
}) ;
} 三、@Query和@NamedQuery查询
这个注解允许我们在借口的方法处使用自定义的查询语句(JPQL或者SQL),public interface UserRepository extends JpaRepository<User, Integer> , JapSpecificationExecutor<User>{
@Query(value="select u from User u where name like ?1") // 这里可以使用位置参数
public List<User> findUserByName(String name);
// @Query(value="select u from User u where name like :name") 这里也可以使用命名参数
// public List<User> findUserByName(@Param("name") String name);
} 如果想使用原生sql的话,@Query注解里有一个属性可以配置:
@Query(value="select u from user u where name like ?1", nativeQuery = true) // 设置为true就表示使用原生sql查询 @NamedQuery:命名查询,是调用实体管理器来执行的命名查询,有一些经常用到的查询,我们把它先写好,之后根据名称直接调用即可。
@NamedQuery的自定义查询写到实体上, @NamedQuery(name = "findUserByName", query="select u from User s where u.name like ?1")
@Entity
@Table("user")
public class User {} 使用实体管理器调用: // 使用命名查询
entityManager.createNamedQuery("findUserByName");
query.setParameter(1, "%王%");
List<User> users = query.getResultList(); 当有多个命名查询时,可用@NamedQueries包裹起来
@NamedQueries({
@NamedQuery(name = "findUserByName", query="select u from User s where u.name like ?1"),
@NamedQuery(name = "findUserByName2", query="select u from User s where u.name like ?1"),
@NamedQuery(name = "findUserByName2", query="select u from User s where u.name like ?1")
})
@Entity
@Table("user")
public class User {}好,本节课程就到这里,下课~~~~~~~~~~!!!!!!!!!!!!!!!!!!!!
相关文章推荐
- Spring Data Jpa系列教程(一)--------入门
- Spring Data Jpa系列教程(二)--------实体详解
- Spring Data Jpa系列教程(三)--------JPQL
- Spring Boot系列教程一:Eclipse安装spring-tool-suite插件
- (LINQ 学习系列)(5)Linq教程实例: 单表操作之增 删 改 查询
- Flex4系列教程之六 – 整合Flex,BlazeDS,Spring(< 2.5.6)
- Spring Boot高级教程之使用Redis实现session共享
- Springboot系列:Springboot与Thymeleaf模板引擎整合基础教程(附源码)
- Springboot系列:Springboot与Thymeleaf模板引擎整合基础教程(附源码)
- Spring Boot系列教程三:使用devtools实现热部署
- WebService之Axis2系列教程(九)Axis2与Spring集成传递对象
- Spring Boot系列教程四:配置文件详解properties
- mybatis 高级映射和spring整合之查询缓存(5)
- 《Genesis-3D游戏引擎系列教程-高级篇》2:自定制水
- Spring Boot系列教程五:使用properties配置文件实现多环境配置
- spring data jpa 分页查询
- Spring Boot系列教程一:Eclipse安装spring-tool-suite插件
- Spring data JPA中使用Specifications动态构建查询
- Flask系列教程(5)——视图高级
- mybatis系列教程(二)——spring整合mybatis