MyBatis(随笔: 动态SQL映射文件)

发布时间:2026/11/6 4:49:21

MyBatis(随笔: 动态SQL映射文件) 动态SQL我们可以用mybatis执行sql的形式来对数据的表进行增删改查操作不过遇到比较复杂的业务需要写复杂的sql时比如说sql的条件不确定可能有一个条件或者多个我们就需要动态sql来提高sql的灵活性。基于OGNL表达式完成多条件查询等逻辑实现用于实现动态SQL的元素主要有if , trim , where , set , choosewhen、otherwise, foreach 示例代码 Demo.查询用户表 跟名称 密码 地址做多条件查询Java接口UserMapper.java//动态Sql// 1. if where trim// 查询用户表 跟名称 密码 地址做多条件查询//如果参数过多可以使用 Map;publicListUsercha(Param(name)Stringname,Param(pwd)Stringpwd,Param(address)Stringaddress);映射文件UserMapper.XMLif 完成多条件查询!-- 方式一if --selectidcharesultTypeUserSELECT * FROM smbms_user WHERE 11!-- 为了保证拼接 where 11 如果if成立 and拼接,不成立也不会因为 where后面啥也没有而报错 --iftestname!null and name!AND userName LIKE CONCAT(%,#{name},%)/ififtestpwd!null and pwd!AND userPassword LIKE CONCAT(%,#{pwd},%)/ififtestaddress!null and address!AND address LIKE CONCAT(%,#{address},%)/if/select!-- 使用 if 进行动态sql处理 test: 使用OGNL表达式,进行验证参数而拼接对应的 sql 语句; 对于参数,不建议使用 parameterType 传单个参数,可以是 Map|复杂数据类型,而单个参数因为没有参数名所以 OGNL表达式无法表示进行判断...可以使用注解.. --where 完成多条件查询!-- 方式二 where --selectidcharesultTypeUserSELECT * FROM smbms_userwhereiftestname!null and name!AND userName LIKE CONCAT(%,#{name},%)/ififtestpwd!null and pwd!AND userPassword LIKE CONCAT(%,#{pwd},%)/ififtestaddress!null and address!AND address LIKE CONCAT(%,#{address},%)/if/where/select!-- 使用 whereif 进行动态sql处理 if就不介绍了 where: 这里sql语句上面就不需要加 where 11防止拼接错误了. 因为: where 会自动在第一个 if成立的sql前面加 where 并移除它的and而之后的不会有影响; --trim 完成多条件查询!-- 方式三: trim --selectidcharesultTypeUserSELECT * FROM smbms_usertrimprefixwhereprefixOverridesand|or!-- 第一个成立if 新增where 剪切 and 或 or --iftestname!null and name!AND userName LIKE CONCAT(%,#{name},%)/ififtestpwd!null and pwd!AND userPassword LIKE CONCAT(%,#{pwd},%)/ififtestaddress!null and address!AND address LIKE CONCAT(%,#{address},%)/if/trim/select!-- 使用 trimif 进行动态sql处理 if就不介绍了 trim : 类似于一个可以自定义的标签,这里就相当于将 trim 设置为一个类似 where标签; 更灵活地去除多余关键字,替代where和set prefix 代表的是语句的前缀会在第一个成立if sql前面加 prefix的值; suffix 代表的是语句的后缀会在最后一个成立if sql后面加 suffix的值; prefixOverrides 代表的是需要去掉的字符串,会在第一个成立if 剪切sql中 prefixOverrides的值; suffixOverrides 代表的是语句的后缀会在最后一个成立if 剪切sql中 suffixOverrides的值; --修改用户表 使用if set trimJava接口UserMapper.java//2.修改用户表 使用if set frimpublicintupd(Useru);映射文件UserMapper.XMLset 完成修改updateidupdparameterTypeUserUPDATE smbms_usersetiftestuserName!null and userName!userName #{userName},/ififtestuserPassword!null and userPassword!userPassword#{userPassword},/if/setwhere id #{id}/update--!-- set: 会默认在第一个成立if 前面加SET,并去掉最后一个列的 , 逗号 注意要确保至少有一个set 成立哦~不然 UPDATE 表 WHERE ID? 并不符合Sql语句!,没有一个if成立导致没有 SET要修改的列; --trim 完成修改updateidupdparameterTypeUserUPDATE smbms_usertrimprefixsetsuffixwhere id #{id}suffixOverrides,iftestuserName!null and userName!userName #{userName},/ififtestuserPassword!null and userPassword!userPassword#{userPassword},/if/trim/updatein查询用户表 使用foreach 完成部门查询;Java接口UserMapper.java// 3.in查询用户表 使用foreach 完成部门查询;publicListUserchain(ListIntegeruserRoles);映射文件UserMapper.XML!-- 3.in查询用户表 使用fearche 完成部门查询; --selectidchainparameterTypejava.util.ListresultTypeUserSELECT * FROM smbms_user WHERE userRole INforeachcollectionlistitemWopen(close)separator,#{W}/foreach/select!-- foreach: 迭代一个集合通常用于in条件 item 表示集合中每一个元素进行迭代时候的别名; index 指定一个名称,用于表示在迭代过程中每次迭代到的位置。 collection:必须指定: list集合 当传入参数是单参数且是一个list时候 collection属性值应该为 list; array数组: 当传入参数是单参数且是一个数组时候collection属性值应该为array map-key集合: 当传入参数为多参数,就需要包它们封装为一个Map进行处理; open 表示该语句开始时候的符合,既然是in 那一定是 open( separator 表示在每次进行迭代之间什么符号,作为分隔符 既然是in 那一定是 separator, close 表示该语句结束时候的符合,既然是in 那一定是 close) --对于某些查询需求,虽然有多个查询条件,但我们不想应用所有的条件,只选择其中一种查询结果时候可以使用Choose;Java接口UserMapper.java//5.对于某些查询需求,虽然有多个查询条件,但我们不想应用所有的条件,只选择其中一种查询结果时候可以使用Choose;//用户名模糊查询 | 密码模糊查询 都不符合则查全部;publicListUserchoose(Param(name)Stringname,Param(pwd)Stringpwd);映射文件UserMapper.XML!-- 用户名模糊查询 | 密码模糊查询 都不符合则查全部; --!-- Choose --selectidchooseresultTypeUserSELECT * FROM smbms_userwherechoosewhentestname!null and name!AND userName LIKE CONCAT(%,#{name},%)/whenwhentestpwd!null and pwd!AND userPassword LIKE CONCAT(%,#{pwd},%)/whenotherwiseand 11/otherwise/choose/where/select!-- choose(when、otherwise): 相当于Java中switch语句,当when有条件满足的时候就跳出choose,如果没有一个成立则执行: otherwise; choose when test 条件1 …/when when test 条件2 …/when ..... otherwise…/otherwise /choose --运行类DTSqlRun .Javapackagecom.wsm.run;importjava.util.ArrayList;importjava.util.List;importjava.util.Scanner;importorg.apache.ibatis.session.SqlSession;importcom.wsm.mapper.UserMapper;importcom.wsm.pojo.User;importcom.wsm.utis.MyBatisUtil;publicclassDTSqlRun{staticScannerinputnewScanner(System.in);publicstaticvoidmain(String[]args){DTSqlRunrnewDTSqlRun();//r.cha();//r.upd();//r.chain();r.choose();}publicvoidcha(){SqlSessionsessionMyBatisUtil.create();UserMapperumsession.getMapper(UserMapper.class);ListUserusersum.cha(w,null,);if(users.size()0){System.out.println(没有数据);}for(Useruser:users){System.out.println(user.getId()\tuser.getUserCode()\tuser.getUserName()\tuser.getPhone()\tuser.getAddress());}MyBatisUtil.close(session);}publicvoidupd(){UserunewUser();//u.setUserName(asdsasad);u.setUserPassword(xxasssssda);u.setId(1);SqlSessionsessionMyBatisUtil.create();UserMapperumsession.getMapper(UserMapper.class);if(um.upd(u)1){session.commit();//手动提交;System.out.println(修改成功);}else{System.out.println(修改失败);}MyBatisUtil.close(session);}publicvoidchain(){ListIntegerinnewArrayListInteger();in.add(1);in.add(2);//in.add(3);SqlSessionsessionMyBatisUtil.create();UserMapperumsession.getMapper(UserMapper.class);ListUserusersum.chain(in);if(users.size()0){System.out.println(没有数据);}for(Useruser:users){System.out.println(user.getId()\tuser.getUserCode()\tuser.getUserName()\tuser.getPhone()\tuser.getAddress()\tuser.getUserRole());}MyBatisUtil.close(session);}publicvoidchoose(){SqlSessionsessionMyBatisUtil.create();UserMapperumsession.getMapper(UserMapper.class);ListUserusersum.choose(s,ss);//两个参数都传了,但pwd的属性无效,因为name 成立了 choose 就结束了;if(users.size()0){System.out.println(没有数据);}for(Useruser:users){System.out.println(user.getId()\tuser.getUserCode()\tuser.getUserName()\tuser.getPhone()\tuser.getAddress());}MyBatisUtil.close(session);}}MyBatis缓存正如大多数框架一样MyBatis提供了一级缓存和二级缓存一级缓存一级缓存是基于,PerpetyalCache(MyBatis 自带的), HashMap本地缓存作用范围在 SqlSession域内. 当SqlSession关闭时,则其所有的缓存就会被清空…二级缓存二级缓存就是 global caching 它超出 sqlsession 范围之外, 结果可以被所有的sqlSession 共享;开启它只需要在MyBatis 的核心配置文件( MyBatis-config.xml ) setting 中设置…二级缓存的配置1.需要在MyBatis-config.xml中配置settings!--配置mybatis的log实现为LOG4J --settingnamelogImplvalueLOG4J/!--设置resultMap的自动映射级别NONE(禁止自动匹配),PARTIAL(默认)自动匹配所有属性,有内部嵌套(association、collection)的除外 且 数据库列与实体类名相同,FULL(自动匹配所有属性)比PARTIAL更强 --settingnameautoMappingBehaviorvalueFULL/!-- 设置二级缓存 --settingnamecacheEnabledvaluetrue//settings2.在对应的Mapper.xml 文件中设置缓存默认是没有开启缓存的;需要注意的是global caching 作用域针对的是 mapper 的 namespace 而言的,即只有在此 namepace 内的查询才可以共享这个 cache…cacheevictionFIFOflushInterval60000size512readOnlytrue/!-- 二级缓存 --!-- eviction 文件的保存形式; flushInterval 缓存对象的毫秒数; size 缓存对象的个数; 先进先出原则,如果已经满了,则最先进的移除,添加新的 readOnly : 只读 --3.在 mapper 文件配置支持 cache 后, 如果需要对个别查询进行调整可以单独设置 cache 代码这样就不需要在配置 Cache了…方法2 和 方法3可以选一种...!-- userCache: true开启 false关闭; --selectidcharesultMapRoleMapuseCachetrue.../select示例demo//根据编号查部门及 部门员工;publicvoidcha(){SqlSessionsessionMyBatisUtil.create();RoleMapperrmsession.getMapper(RoleMapper.class);//一级缓存缓存数据存储在 sqlSession中;Rolerrm.cha(2);System.out.println(r.getRoleName()\tr.getId());ListUserur.getUsers();for(Useruser:u){System.out.println(user.getUserName());}//因此不关闭 sqlSession 在此查相同的数据不会在需要sql语句; 访问数据库;System.out.println(------------------------------------------);Roler1rm.cha(2);System.out.println(r1.getRoleName()\tr1.getId());//而查询没有查过的数据还是需要sql 访问数据库System.out.println(------------------------------------------);Roler2rm.cha(3);System.out.println(r2.getRoleName()\tr2.getId());MyBatisUtil.close(session);//关闭SqlSessionSystem.out.println(二级缓存);//二级缓存: 数据存储在 sqlSessionFactory工厂中;//需要在配置信息中设置//MyBatis: setting namecacheEnabled valuetrue///xxxMapper.xml中 cache evictionFIFO flushInterval60000 size512 readOnlytrue///而查询时: select idcha resultMapRoleMap useCachetrue 即可;!! useCachetrue/false 开启/关闭;//即使是SqlSession 关闭对于查过的数据也会保存起来SqlSessionsessionrMyBatisUtil.create();RoleMapperrmrsessionr.getMapper(RoleMapper.class);Rolerrrmr.cha(1);System.out.println(rr.getRoleName()\trr.getId());MyBatisUtil.close(sessionr);//关闭SqlSession//上面关闭了,才用二级缓存;所以不在需要Sql 数据库操作;SqlSessionsessionr1MyBatisUtil.create();RoleMapperrmr1sessionr1.getMapper(RoleMapper.class);Rolerr1rmr1.cha(1);System.out.println(rr1.getRoleName()\trr1.getId());MyBatisUtil.close(sessionr1);//关闭SqlSession}Run
延伸阅读

更多相关文章

2026/11/6 4:49:21

Spring配置补充 (随笔详情扩展:)

Spring配置补充&#xff1a; 实现Spring 和 MyBatis 集成过程中学习了,Spring 的配置数据源的方法; 实际开发过程中还有很多灵活的配置文件; 灵活配置DataSource: <!-- 远古方法&#xff08;最初方法&#xff09;,数据库连接池,不过我最喜欢用的; --><bean id"…

2026/11/6 4:49:21

初始MyBatis(随笔1)

初始MyBatis(随笔1) 框架技术 为什么要学习框架技术&#xff1a; PTT模板举例&#xff1a;做ppt前, 总是会需要找一些模板, 优点; 1. 不用考虑布局, 排版等问题, 提高了效率; 2. 可以专心于PTT的内容, 使演讲 “质量” 更有保障; 3. 新手也可以实现出很好的 PPT; 框架&#x…

2026/11/6 5:54:24

逆向工程实战:黑盒映射还原与查表逆向技巧

逆向工程里有一类题目特别有意思&#xff0c;它不靠复杂的加密算法吓唬人&#xff0c;也不靠庞大的代码量拖垮你&#xff0c;而是用一个看似简单的“盒子”把你的思路锁死。reverse_box 就是这样一个典型代表——名字直白得近乎挑衅&#xff0c;仿佛在说“来吧&#xff0c;拆开…

2026/11/6 5:54:24

分类模型评估指标详解:准确率、精确率、召回率与F1值

做分类模型的朋友大概都有过这种经历&#xff1a;模型训练完&#xff0c;准确率刷到了 0.95&#xff0c;兴冲冲拿去汇报&#xff0c;结果被一句“那漏检的那批样本怎么办”问得哑口无言。我早年做第一个二分类项目时就栽在这上面——数据里正负样本比例接近 1:99&#xff0c;模…

2026/11/6 5:54:24

MySQL SQL进阶实战:复杂查询优化与性能提升

1. MySQL SQL进阶实战&#xff1a;第二天核心知识点解析作为数据库管理员&#xff0c;我经常遇到刚接触MySQL的开发者在第二天学习SQL时遇到的典型困惑。今天我们就来深入剖析那些容易被忽略却至关重要的SQL知识点&#xff0c;这些内容往往决定了你能否从"会写SQL"进…

2026/11/6 5:54:24

MySQL SQL进阶实战:性能优化与高级特性详解

1. MySQL SQL进阶实战指南作为关系型数据库的核心操作语言&#xff0c;SQL的熟练程度直接决定开发者的数据处理效率。今天我们将深入探讨MySQL中那些容易被忽略却极其实用的SQL技巧&#xff0c;这些内容来自我多年数据库运维中积累的实战经验。2. 核心语法精讲2.1 多表连接优化…

2026/11/6 5:54:24

VMware分布式虚拟交换机配置与性能优化指南

1. 项目背景与核心需求在虚拟化环境中&#xff0c;VMware ESXi作为企业级虚拟化平台被广泛使用。很多管理员会遇到这样的场景&#xff1a;当一台ESXi主机上的虚拟机需要访问另一台ESXi主机上的虚拟机时&#xff0c;传统的网络配置方式往往需要复杂的路由设置或额外的网络设备。…

2026/11/6 5:49:24

OceanBase与DataGrip连接配置与优化实战

1. OceanBase与DataGrip技术栈解析作为国产分布式数据库的代表作&#xff0c;OceanBase凭借其高可用性和水平扩展能力&#xff0c;在金融、电信等领域逐步替代传统Oracle架构。而JetBrains旗下的DataGrip作为多数据库管理工具&#xff0c;其智能补全、可视化查询等功能深受开发…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代&#xff0c;基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而&#xff0c;与配合度高的人类不同&#xff0c;宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态&#xff0c;更无法控制光照环境。实际应用中&#xff0c;我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/6 1:03:39

MCU晶振电路设计全解析:从负载电容计算到PCB布局调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代&#xff0c;基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而&#xff0c;与配合度高的人类不同&#xff0c;宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态&#xff0c;更无法控制光照环境。实际应用中&#xff0c;我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑