网站首页 > 技术文章 正文
在之前的文章提到过关于sql动态传参在springData中的应用,下面补充一下关于原生sql和springData的同一需求下的两种不同的写法:
需求:contoller层传递一个map给service层,需要从map中取到三个参数(pid、enVisible、type)给数据库进行查询返回结果集。
需求明细:
1.不确定前端是否会传递这三个参数,换言之,这三个参数不一定能够取到;
2.如果传递传递参数pid、enVisible,如果能取到值的话,则按照相应的条件进行筛选;
3.type参数传递,如果传递参数为空则,则筛选出符合其他条件的全部数据;如果传递为0,则筛选出type为1和2的数据;如果传递参数不为0(为1或2或3),则筛选出与之对应的数据。
处理逻辑放在service层实现方法1——springData通过Specification进行实现:
dao层写法:
public interface PermissionDao extends JpaRepository<Permission, String>, JpaSpecificationExecutor<Permission> {
}service写法:
public List<Permission> findAll(Map<String,Object> map){
//1.需要查询条件
Specification<Permission> specification = new Specification<Permission>() {
@Override
public Predicate toPredicate(Root<Permission> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//查询条件list接受
List<Predicate> list = new ArrayList<Predicate>();
//pid:父id应用
if (!StringUtils.isEmpty(map.get("pid"))){
list.add(criteriaBuilder.equal(root.get("pid").as(String.class),(String)map.get("pid")));
}
//enVisible:0:查询平台所有权限(最高权限);1:查询组织的权限
if(!StringUtils.isEmpty(map.get("enVisible"))){
list.add(criteriaBuilder.equal(root.get("enVisible").as(String.class),(String)map.get("enVisible")));
}
// type:查询全部权限列表type:0: 菜单+按钮(权限点) 1:菜单 2;按钮(权限点) 3:api接口
if (StringUtils.isEmpty(map.get("type"))){
String type = (String)map.get("type");
CriteriaBuilder.In<Object> in = criteriaBuilder.in(root.get("type"));
if("0".equals(type)){
in.value(1).value(2);
}else {
in.value(Integer.parseInt(type));
}
}
return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
}
};
return permissionDao.findAll(specification);
}处理逻辑放在dao层实现方法2——springData通过原生sql进行实现:
dao层写法:
public interface PermissionDao extends JpaRepository<Permission, String>, JpaSpecificationExecutor<Permission> {
@Query(value = "select * from pe_permission where (pid = ?1 or ?1 is null) and (en_visible = ?2 or ?2 is null) and IF(?3 is null,(1 = 1),IF(?3 = 0,type in (1,2), type = ?3))",nativeQuery = true)
List<Permission> selectList(Object pid, Object enVisible, Object type);
}service写法:
public List<Permission> findAll(Map<String,Object> map){
return permissionDao.selectList(map.get("pid"),map.get("enVisible"),map.get("type"));
}两种方式经测试都可以实现需求,但从代码量上来说,第二种实现方式肯定是优于第一种方式的;但从程序的可读性来说,如果sql比较好的同学,那么第二种方式可能跟适合一些,但是如果是springData学的比较好的同学可能更喜欢第一种吧。
第一种方式基本就是借用springData封装好的接口去实现逻辑的,再此我不赘述了,关于第二种方式,我多啰嗦几句:(pid = ?1 or ?1 is null)和(en_visible = ?2 or ?2 is null)在上一篇文章也说过,基本的意思就是判断传递过来的参数是否为空,如果不为空就按照传递过来的参数进行检索,如果为空的话就相当与没条件一个意思。
至于IF函数是mysql数据库种自带的函数,IF(表达式1,表达式2,表达式3):表达式1返回布尔值,如果返回为true,那么去执行表达式2;如果返回为false,那么执行表达式3。但个人不推荐这种写法,原因是必须是mysql数据或者该数据库中必须含有这个函数;所以换个数据库的话,就必须要换个函数,其他数据库不是很了解,如果是Oracle数据库的话,得将这个函数换成Nvl2()这个函数,用法是一样的,也可以实现同样的效果,不过这样也暴露出这种方式的一个问题,如果写原生sql中含有某种数据库特定的数据库函数,那么它的移植性就会差一点。
关于springData中动态传参的见解就这些了,希望大家喜欢,不说了,我去写bug了哈。
猜你喜欢
- 2024-10-01 全面解析45种设计模式(Design pattern)和六大原则
- 2024-10-01 5分钟了解(什么是设计模式)(设计模式的意思)
- 2024-10-01 mongoHelper 0.3.9 发布,简化 CRUD操作
- 2024-10-01 JPA 的 Metamodel(jpa格式图片)
- 2024-10-01 设计模式简介(设计模式是干嘛的)
- 2024-10-01 SlideLive网站:如何实现个性化搜索
- 2024-10-01 JPA核心接口EntityManager之API功能详解(三)
- 2024-10-01 使用ElasticSearch快速搭建数据搜索服务
- 2024-10-01 SpringORM最佳实践:SpringData架构与应用
- 2024-10-01 Spring Data JPA 自定义存储库(spring data jpa调用存储过程)
- 最近发表
-
- 聊一下 gRPC 的 C++ 异步编程_grpc 异步流模式
- [原创首发]安全日志管理中心实战(3)——开源NIDS之suricata部署
- 超详细手把手搭建在ubuntu系统的FFmpeg环境
- Nginx运维之路(Docker多段构建新版本并增加第三方模
- 92.1K小星星,一款开源免费的远程桌面,让你告别付费远程控制!
- Go 人脸识别教程_piwigo人脸识别
- 安卓手机安装Termux——搭建移动服务器
- ubuntu 安装开发环境(c/c++ 15)_ubuntu安装c++编译器
- Rust开发环境搭建指南:从安装到镜像配置的零坑实践
- Windows系统安装VirtualBox构造本地Linux开发环境
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (77)
- vector线程安全吗 (73)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)
