准备数据表:
CREATE TABLE `user_info` (
`ID` int NOT NULL AUTO_INCREMENT COMMENT 'id',
`NAME` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
`AGE` int NOT NULL COMMENT '年龄',
`BIRTHDAY` date NOT NULL COMMENT '生日',
`ADDRESS` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '住址',
`CREATETIME` date DEFAULT NULL COMMENT '创建时间',
`UPDATETIME` date DEFAULT NULL COMMENT '更新时间',
`GENDER` varchar(2) NOT NULL COMMENT '性别',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb3;
if 标签是我们最常使用的。在查询、删除、更新的时候很可能会使用到。必须结合 test 属性联合使用,test属性值是一个OGNL表达式,表达式可以使true或false
mapper接口:
/**
* 根据条件查询用户信息
* @date 2021/11/7 10:24
* @param userInfo
* @return java.util.List
*/
List<UserInfo> queryByUserInfo(UserInfo userInfo);
映射文件中对应的动态sql:
<select id="queryByUserInfo" parameterType="UserInfo" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user_info where 1=1
<if test="name != null and name != ''">
and name=#{name}
if>
<if test="gender != null and gender != ''">
and gender=#{gender}
if>
select>
测试:
@Test
public void TestQueryByUserInfo(){
UserInfo userInfo = new UserInfo();
userInfo.setName("小明");
// 根据名称查询
List<UserInfo> userInfos1 = userInfoMapper.queryByUserInfo(userInfo);
for (UserInfo user : userInfos1){
System.out.println(user);
}
// 根据性别查询
userInfo.setName(null);
userInfo.setGender("男");
List<UserInfo> userInfos2 = userInfoMapper.queryByUserInfo(userInfo);
for (UserInfo user : userInfos2){
System.out.println(user);
}
// 根据姓名和性别同时查询
userInfo.setName("小天");
List<UserInfo> userInfos3 = userInfoMapper.queryByUserInfo(userInfo);
for (UserInfo user : userInfos3){
System.out.println(user);
}
}
mapper接口:
/**
* 更新用户非空字段
* @date 2021/11/7 10:54
* @param userInfo
* @return int
*/
int updateByPrimaryKey(UserInfo userInfo);
映射文件中对应的动态sql:
<update id="updateByPrimaryKey" parameterType="UserInfo">
update user_info
<set>
<if test="name != null">
name = #{name},
if>
<if test="age != null">
age = #{age},
if>
<if test="gender != null">
gender = #{gender},
if>
<if test="birthday != null">
birthday = #{birthday},
if>
<if test="address != null">
address = #{address},
if>
<if test="createTime != null">
createTime = #{createTime},
if>
<if test="updateTime != null">
updateTime = #{updateTime}
if>
set>
where id = #{id}
update>
测试:
@Test
public void TestUpdateByPrimaryKey(){
UserInfo userInfo = new UserInfo();
userInfo.setId(1);
userInfo.setGender("女");
userInfo.setAddress("北京市朝阳区新华街道139号");
int i = userInfoMapper.updateByPrimaryKey(userInfo);
System.out.println(i);
}
mapper接口:
/**
* 插入用户信息
* @date 2021/11/7 11:14
* @param userInfo
* @return int
*/
int insertUserInfo(UserInfo userInfo);
映射文件中对应的动态sql:
<insert id="insertUserInfo" parameterType="UserInfo">
insert into user_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">
name,
if>
<if test="age != null">
age,
if>
<if test="gender != null">
gender,
if>
<if test="birthday != null">
birthday,
if>
<if test="address != null">
address,
if>
<if test="createTime != null">
createTime,
if>
<if test="updateTime != null">
updateTime
if>
trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="name != null">
#{name},
if>
<if test="age != null">
#{age},
if>
<if test="gender != null">
#{gender},
if>
<if test="birthday != null">
#{birthday},
if>
<if test="address != null">
#{address},
if>
<if test="createTime != null">
#{createTime},
if>
<if test="updateTime != null">
#{updateTime}
if>
trim>
insert>
测试:
@Test
public void TestInsertUserInfo(){
UserInfo userInfo = new UserInfo();
userInfo.setName("小狄");
userInfo.setAge(25);
userInfo.setGender("男");
int i = userInfoMapper.insertUserInfo(userInfo);
System.out.println(i);
}
把上面的代码where1=1修改为下面的代码,当存在用户名时根据用户名查询,存在性别根据性别查询,两个都存在是根据两个条件插叙,两个都不存在时查询全部。
<select id="queryByUserInfo" parameterType="UserInfo" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user_info
<where>
<if test="name != null and name != ''">
and name=#{name}
if>
<if test="gender != null and gender != ''">
and gender=#{gender}
if>
where>
select>
测试:
@Test
public void TestQueryByUserInfo(){
UserInfo userInfo = new UserInfo();
userInfo.setName("小明");
// 根据名称查询
List<UserInfo> userInfos1 = userInfoMapper.queryByUserInfo(userInfo);
for (UserInfo user : userInfos1){
System.out.println(user);
}
// 根据性别查询
userInfo.setName(null);
userInfo.setGender("男");
List<UserInfo> userInfos2 = userInfoMapper.queryByUserInfo(userInfo);
for (UserInfo user : userInfos2){
System.out.println(user);
}
// 根据姓名和性别同时查询
userInfo.setName("小天");
List<UserInfo> userInfos3 = userInfoMapper.queryByUserInfo(userInfo);
for (UserInfo user : userInfos3){
System.out.println(user);
}
// 姓名和性别同时不存在时查询全部
userInfo = null;
List<UserInfo> userInfos4 = userInfoMapper.queryByUserInfo(userInfo);
for (UserInfo user : userInfos4){
System.out.println(user);
}
}
choose when otherwise 标签可以帮我们实现 if else 的逻辑。一个 choose 标签至少有一个 when, 最多一个otherwise
mapper接口:
/**
* 根据id或者名称查询
* @date 2021/11/7 11:51
* @param userInfo
* @return com.dynamic.entity.UserInfo
*/
UserInfo queryByIdOrName(UserInfo userInfo);
映射文件中对应的动态sql:
<select id="queryByIdOrName" parameterType="UserInfo" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user_info
<where>
<choose>
<when test="id != null">
and id = #{id}
when>
<otherwise>
and name = #{name}
otherwise>
choose>
where>
select>
id和name都传时会根据wher标签匹配的进行查询
该标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分 close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名 sperator:代表分隔符
mapper接口:
/**
* 根据id查询用户信息
* @date 2021/11/7 17:08
* @param ids
* @return com.dynamic.entity.UserInfo
*/
List<UserInfo> queryById(@Param("ids") List<Integer> ids);
映射配置:
<select id="queryById" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user_info
<where>
<if test="ids != null and ids.size()>0">
<foreach collection="ids" open="id in (" close=")" item="id" separator=",">
#{id}
foreach>
if>
where>
select>
测试:
@Test
public void TestQueryById() {
ArrayList<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
List<UserInfo> userInfoList = userInfoMapper.queryById(ids);
for (UserInfo userInfo : userInfoList)
System.out.println(userInfo);
}
bind标签中,value对应传入实体类的某个字段,name属性既给对应字段取的变量名。在value属性中可以使用字符串拼接等特殊处理,模糊查询的时候可以处理入参属性
<select id="selectUserInfo" resultType="com.zhang.entity.UserInfo">
<bind name="name" value="'%' + name + '%'"/>
select * from USER_INFO
<where>
<if test="name != null and name != '' ">
and name like #{name}
if>
where>
select>
sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。
定义片段:
<sql id="defult">
select * from user
sql>
引用sql片段:
<select id="findByUser" resultMap="userMap" parameterType="user">
<include refid="defult">include>
<where>
<if test="userName != null and userName != ''">
and username=#{userName}
if>
<if test="userSex != null and userSex != ''">
and sex=#{userSex}
if>
where>
select>