MyBatis 令人热爱的一大特性就是动态 SQL 。在使用 JDBC 的过程中 。根据条件进行 SQL 的拼接是很麻烦且非常的容易出错的 。MyBatis 动态 SQL 的出现 。解决了这种麻烦 。
MyBatis通过 OGNL 来进动作态 SQL 的使用的 。目前 。动态 SQL 接受以下几种标签:
文章插图
1 资料准备
为了后面的演示 。创建了一个 Maven 项目 mybatis-dynamic, 创建了对应的资料库和表
DROP TABLE IF EXISTS `student`;CREATE TABLE `student` ( `student_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号', `name` varchar(20) DEFAULT NULL COMMENT '姓名', `phone` varchar(20) DEFAULT NULL COMMENT '电话', `email` varchar(50) DEFAULT NULL COMMENT '邮箱', `sex` tinyint(4) DEFAULT NULL COMMENT '性别', `locked` tinyint(4) DEFAULT NULL COMMENT '情况(0:正常,1:锁定)', `gmt_created` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '存入资料库的时光', `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '改写的时光', `delete` int(11) DEFAULT NULL, PRIMARY KEY (`student_id`)) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生表';对应的项目结构
文章插图
2 if 标签
if 标签是我们最常使用的 。在查询、删除、更新的时候很可能会使用到 。一定混合 test 属性联动使用 。
2.1 在 WHERE 条件中使用 if 标签
这是常见的一种现象 。我们在进行按条件查询的时候 。可能会有多种状态 。
2.1.1 查询条件
根据输入的学生消息进行条件检索
当只输入玩家名时 。使用玩家名进行模糊检索;当只输入性别时 。使用性别进行完整匹配当玩家名和性别都存在时 。用这两个条件进行查询匹配查询2.1.2 动态 SQL
接口函数
/** * 根据输入的学生消息进行条件检索 * 1. 当只输入玩家名时 。使用玩家名进行模糊检索; * 2. 当只输入邮箱时 。使用性别进行完整匹配 * 3. 当玩家名和性别都存在时 。用这两个条件进行查询匹配的用 * @param student * @return */ ListStudent selectByStudentSelective(Student student);对应的动态 SQL
select id="selectByStudentSelective" resultMap="BaseResultMap" parameterType="com.homejim.mybatis.entity.Student" select include refid="Base_Column_List" / from student where 1=1 if test="name != null and name !=''" and name like concat('%', #{name}, '%') /if if test="sex != null" and sex=#{sex} /if /select在此 SQL 语句中 。where 1=1 是多条件拼接时的小技术 。后面的条件查询就可以都用 and 了 。
同一时间 。我们添加了 if 标签来处理动态 SQL
if test="name != null and name !=''" and name like concat('%', #{name}, '%') /if if test="sex != null" and sex=#{sex} /if此 if 标签的 test 属性值是一个符合 OGNL 的表示式 。表示式可以是 true 或 false 。如果表示式返回的是数值 。则0为 false, 非 0 为 true;
2.1.3 测试
@Test public void selectByStudent() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student search = new Student(); search.setName("明"); System.out.println("只有名字时的查询"); ListStudent studentsByName = studentMapper.selectByStudentSelective(search); for (int i = 0; i studentsByName.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsByName.get(i), ToStringStyle.MULTI_LINE_STYLE)); } search.setName(null); search.setSex((byte) 1); System.out.println("只有性别时的查询"); ListStudent studentsBySex = studentMapper.selectByStudentSelective(search); for (int i = 0; i studentsBySex.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsBySex.get(i), ToStringStyle.MULTI_LINE_STYLE)); } System.out.println("姓名和性别同一时间存在的查询"); search.setName("明"); ListStudent studentsByNameAndSex = studentMapper.selectByStudentSelective(search); for (int i = 0; i studentsByNameAndSex.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsByNameAndSex.get(i), ToStringStyle.MULTI_LINE_STYLE)); } sqlSession.commit(); sqlSession.close(); }只有名字时的查询 。发送的语句和结果
文章插图
查询的条件只发送了
where 1=1 and name like concat('%', ?, '%') 只有性别时的查询 。发送的语句和结果
推荐阅读
- \"不在其位,不谋其政\",你对这句成语的理解是怎样的?
- 山东最知名的白酒有哪些?
- 为什么有人说关羽喜欢看《春秋》?
- 河南有哪些名酒?最好喝的是哪个牌子的?
- 清蒸多宝鱼的做法 不加一滴水做法简单
- 《世说新语》中学生应该怎样读,怎样做笔记才能积累解词,提高课外文言文的阅读能力?
- 河南的四大名酒是怎么没落的?
- 宝宝起痱子用什么方法最有效 婴儿去痱子止痒最有效的方法
- 《左传》与《战国策》是史书还是兵法?