SpringBoot Jpa 实现复杂的动态sql查询
SpringBoot Jpa 实现复杂的动态sql查询这里说一下如何利用Jpa 实现复杂的动态sql查询,关于Jpa的介绍我就不多说了,相信小伙伴们都知道,好了,不多说,咱们直奔主题。我这里会贴出关键部分代码以及说明:我的SpringBoot版本是2.3.1,不同版本可能会有那么一点点差异,但是大同小异啦,稍微修改一下就好。一 首先是实体类@Data@Entity@Table(name = "ma
SpringBoot Jpa 实现复杂的动态sql查询
这里说一下如何利用Jpa 实现复杂的动态sql查询,关于Jpa的介绍我就不多说了,相信小伙伴们都知道,好了,不多说,咱们直奔主题。
我这里会贴出关键部分代码以及说明:
我的SpringBoot版本是2.3.1
,不同版本可能会有那么一点点差异,但是大同小异啦,稍微修改一下就好。
一 首先是实体类
@Data
@Entity
@Table(name = "master_user") //设置表名,不设置则默认下划线分隔开
public class User {
/**
* 设置userId主键自增,数据库字段默认下划线分隔开 userId对应数据路字段user_id
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer userId;
/**
* 设置字段不能为空且唯一,后面指定字段对应mysql的数据类型以及说明
*/
@Column(nullable = false, unique = true, columnDefinition = "varchar(32) COMMENT '用户名'")
private String username;
@Column(nullable = false, columnDefinition = "tinyint(4) COMMENT '性别 0男 1女'")
private Integer gender;
@Column(nullable = false)
private Integer age;
}
二 直接看查询
我这里直接贴出service实现层,通过Specification
实现动态查询,Root即root
获取实体类具体属性, CriteriaBuilder即cb
拼接查询条件的,拼接好查询条件之后,通过 CriteriaQuery即query
实现查询,如下所示:
@Override
public Page<User> findAllBySf(Integer gender, Integer age, String username, Integer pageNo, Integer pageSize) {
//动态查询
Specification<User> sf = (Specification<User>) (root, query, cb) -> {
//用于添加所有查询条件
List<Predicate> p = new ArrayList<>();
if (null != gender) {
Predicate p1 = cb.equal(root.get("gender").as(Integer.class), gender);
p.add(p1);
}
if (null != age) {
Predicate p2 = cb.greaterThan(root.get("age").as(Integer.class), age);
p.add(p2);
}
if (!StringUtils.isEmpty(username)) {
Predicate p3 = cb.like(root.get("username").as(String.class), "%" + username + "%");
p.add(p3);
}
Predicate[] pre = new Predicate[p.size()];
Predicate and = cb.and(p.toArray(pre)); //查询条件 and
//Predicate or = cb.or(p.toArray(pre)); //查询条件 or
query.where(and); //添加查询条件
//设置排序
List<Order> orders = new ArrayList<>();
orders.add(cb.desc(root.get("age"))); //倒序
orders.add(cb.asc(root.get("username"))); //正序
return query.orderBy(orders).getRestriction();
};
Pageable pageable = PageRequest.of(pageNo, pageSize);
return userDao.findAll(sf, pageable);
}
具体的说明,我已经在代码注释里说明了,相信一看就明白。
可以发现,JPA查询确实很方便,省去了xml文件,还可以自动生成数据库表,十分的方便。
那么,这个 Specification
是哪儿来的
呢?我们继续看dao层
三 这里是dao层
我在这里添加了一些自定义查询,如果你要执行修改操作,也很简单,添加一个@Modifying
注解即可,我这里就不多加演示啦。
//BaseDao
@NoRepositoryBean//基础dao,作用是不用每次都继承jpa的接口 不作为bean注入spring容器
public interface BaseDao<T, V> extends JpaRepository<T, V>, JpaSpecificationExecutor<T> {
}
@Repository("masterUserDao") //除非有多个同名的UserDao,否则这里不用添加 masterUserDao
public interface UserDao extends BaseDao<User, Integer> {
//这种我就不说了,几乎都懂的
User findOneByUsernameAndAge(String username, Integer age);
//?1 代表第一个参数 以此类推 顺序不能错
@Query("select u from User u where u.gender = ?1 and u.age = ?2 and u.username like %?3%")
List<User> query(Integer gender, Integer age, String username);
//query2()是query()的另外以一种写法 和query()相比 顺序无所谓,因为指定了参数名
@Query("select u from User u where u.gender = :gender and u.age = :age and u.username like %:username%")
List<User> query2(@Param("gender") Integer gender,
@Param("age") Integer age,
@Param("username") String username);
//query3()和query()1 2相比多了 nativeQuery=true 意思是原生sql
@Query(value = "select * from master_user u where u.gender = ?1 and u.age = ?2 and u.username like %?3%", nativeQuery = true)
List<User> query3(Integer gender, Integer age, String username);
}
具体的测试我就不贴出来了,本地测过,都是ok的。顺便提醒一句,dao层的自定义@Query查询都是要传参的,不传会把它当成null进行查询。
好了,我这里只是简单的一个示例,其他更多的用法有待小伙伴们自己挖掘,谢谢阅读~
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)