Mybatis动态标签基本使用
1.介绍
动态SQL:动态SQL是指根据不同的查询条件,生成不同的SQL语句
我们之前写的 SQL 语句都比较简单,如果有比较复杂的业务,我们需要写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ,稍微不注意,由于引号,空格等缺失可能都会导致错误。那么怎么去解决这个问题呢?这就要使用 mybatis 动态SQL,通过 if, choose, when, otherwise,trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。
2.搭建坏境
数据库信息:
#创建表
CREATE TABLE `user` (
`id` INT(5) NOT NULL AUTO_INCREMENT COMMENT '编号',
`username` VARCHAR(50) DEFAULT NULL COMMENT '姓名',
`address` VARCHAR(50) DEFAULT NULL COMMENT '住址',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
# 添加数据
INSERT INTO `user` VALUES
(1,'齐元松','河南'),
(2,'苏炳添','中国'),
(3,'齐菁菁','河南'),
(4,'牛辉','中国'),
(5,'刘祥','中国'),
(6,'齐元松','河南'),
(7,'齐元松','中国'),
(100,'詹三','中国');
编写实体类:
@Data
public class User {
private int id;
private String username;
private String address;
}
编写Mapper接口及xml文件
public interface UserMapper {
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mapper.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lili.dao.UserMapper">
</mapper>
3.编写代码
1. if,where的使用
需求:根据所传参数进行动态查询:
编写接口类:
List<User> findUserByIf(Map<String, Object> map);
编写xml文件:
<select id="findUserByIf" parameterType="map" resultType="com.lili.entity.User">
select * from user
<where>
<if test="id != null">
id = #{id}
</if>
<if test="username != null">
and username = #{username}
</if>
<if test="address !=null">
and address = #{address}
</if>
</where>
</select>
这里注意,where标签的作用:如果没有满足条件的,自动去除where,有的话,会加上where 并且去掉第一个and
编写测试:
@Test
public void test2() {
try (SqlSession sqlSession = MybatisUtil.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("id",1);
map.put("username","齐元松");
map.put("address","中国");
List<User> users = mapper.findUserByIf(map);
users.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
2. set
当我们想更新一条数据时,我们只需要传入须要更新的字段值即可
接口方法:
int update(User user);
编写Mapper:
<update id="update" parameterType="com.lili.entity.User">
update user
<set>
<if test="username !=null">
username = #{username},
</if>
<if test="address !=null">
address = #{address}
</if>
where id = #{id}
</set>
</update>
编写测试:
@Test
public void test4() {
try (SqlSession sqlSession = MybatisUtil.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(100);
user.setAddress("中国");
user.setUsername("詹三");
int i = mapper.update(user);
System.out.println(i);
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
3. choose语句
有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose标签可以解决此类问题,类似于 Java 的 switch 语句
接口方法:
List<User> findUserByChoose(Map<String, Object> map);
编写Mapper:
<select id="findUserByChoose" parameterType="map" resultType="com.lili.entity.User">
select * from user
<where>
<choose>
<when test="id !=null">id = #{id}</when>
<when test="username !=null">username = #{username}</when>
<when test="address !=null">address = #{address}</when>
<otherwise>id = 1</otherwise>
</choose>
</where>
</select>
编写测试:
@Test
public void test3() {
try (SqlSession sqlSession = MybatisUtil.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("username", "齐元松");
List<User> users = mapper.findUserByChoose(map);
users.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
4. SQL片段
有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。
提取sql片段:
<sql id="username_address">
<if test="username !=null">
username = #{username},
</if>
<if test="address !=null">
address = #{address}
</if>
</sql>
引用sql片段:
<update id="update" parameterType="com.lili.entity.User">
update user
<set>
<include refid="username_address"/>
where id = #{id}
</set>
</update>
5. foreach语句
需求:查询id为1或2或3或4的信息
接口方法:
List<User> findByForeach(@Param("idList") List<Integer> idList);
编写Mapper:
<select id="findByForeach" resultType="com.lili.entity.User" parameterType="list">
select * from user
where id in
<foreach collection="idList" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
编写测试:
@Test
public void test5() {
try (SqlSession sqlSession = MybatisUtil.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<User> users = mapper.findByForeach(integers);
users.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
小结:其实动态 sql 语句的编写往往就是一个拼接的问题,为了保证拼接准确,我们最好首先要写原生的 sql 语句出来,然后在通过 mybatis 动态sql 对照着改,防止出错。多在实践中使用才是熟练掌握它的技巧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!