网站首页 > 技术文章 正文
在之前的文章提到过关于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调用存储过程)
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)