转载

MyBatis之动态sql

  • 首先在 UserMapper.java 中添加抽象方法
    • 因为要一个方法兼具更新密码或者更新年龄的功能,那么我们直接使用一个 实体类对象 作为方法参数即可
/**
 * 更新数据,比如密码或者年龄
 * @param user  User对象,其中封装了用户密码或者用户的年龄
 * @return 受影响的行数,成功返回1,否则返回0
 */
Integerupdate(User user);
  • UserMapper.xml 中配置 <update> 节点
    • 只能修改密码或者年龄,不能同时修改,因为如果同时修改拼接而成的 sql 语句将会少了一个逗号 ,
<updateid="update"parameterType="cn.tedu.spring.entity.User">
	update user 
	set
	<iftest="password!=null">
		password=#{password}
	</if>
	<iftest="age!=null">
		age=#{age}
	</if>
	where id=#{id}
</update>
  • 测试
    • 修改年龄 age ,因此只需要在新建的 User 对象中添加 age 的值即可,那么此时 password 的值不能设置
    • 同时要设置 id 的值
@Test
public void testUpdate(){
	//加载Spring的配置文件
	AbstractApplicationContext ac
		= new ClassPathXmlApplicationContext(
			"spring-mvc.xml",
			"spring-dao.xml");
	
	//获取UserMapper的bean,这个是spring通过扫描mapper.xml文件自动为mybatis自动创建的,首字母小写
	UserMapper userMapper
		= ac.getBean(
			"userMapper", UserMapper.class);
	//新建一个User对象
	User user=new User();
	user.setId(3);  //设置id
	user.setAge(33);  //设置年龄
	int affectRows=userMapper.update(user);
	System.out.println(affectRows);
	ac.close();
}

根据用户名或者用户id查询信息

  • UserMpper.java 中添加接口方法
/**
 * 查找用户信息,根据用户名或者用户id查询
 * @param user  User对象,其中封装了用户名或者用户id
 * @return 用户对象
 */
UserfindUser(User user);
  • UserMapper.xml 中配置
<!--
		User findUser(User user); 
		不能同时查询,缺少连接符号 and or
	-->
	<selectid="findUser"parameterType="cn.tedu.spring.entity.User"resultType="cn.tedu.spring.entity.User">
		select * from user 
		where 
		<iftest="id!=null">
			id=#{id}
		</if>
		
		<iftest="username!=null">
			username=#{username}
		</if>
		
	</select>
  • 测试方法
@Test
	public void testFind(){
		//加载Spring的配置文件
		AbstractApplicationContext ac
			= new ClassPathXmlApplicationContext(
				"spring-mvc.xml",
				"spring-dao.xml");
		
		//获取UserMapper的bean,这个是spring通过扫描mapper.xml文件自动为mybatis自动创建的,首字母小写
		UserMapper userMapper
			= ac.getBean(
				"userMapper", UserMapper.class);
		//新建一个User对象
		User user=new User();
		user.setId(3);  //设置id
		//根据id查找
		System.out.println(userMapper.findUser(user));
		ac.close();
	}

choose【了解】

  • 相当于java中的 switch ,通常与 when 搭配使用
<select>
	select * from user where
    <choose>
    	<whentest="password!=null">
        	password=#{password}
        </when>
        
        <otherwise>
        	id=#{id}
        </otherwise>
    </choose>
</select>

where元素

问题

  • 我们使用动态sql语句构建的语句如下
<selectid="findUser"parameterType="cn.tedu.spring.entity.User"resultType="cn.tedu.spring.entity.User">
	select * from user 
    where 
    <iftest="password!=null">
    	password=#{password}
    </if>
    
    <iftest="username!=null">
    	and username=#{username}
    </if>
    
</select>
  • 如果传入的参数 User 对象中只是设置了 username 的值,那么此时的sql语句将会变成 select * from user where and username=#{username} ,很明显多了一个 and

作用

  • <where> 标签主要是用于简化 where 子句的编写, <where> 可以替代sql语句中的 where ,而且还可以将后面多余的 and 或者 or 去掉

格式

select 字段 from 表名
	<where>
		.....
	</where>

解决问题

  • 我们使用 <where> 标签解决上面的问题
<selectid="findUser"parameterType="cn.tedu.spring.entity.User"resultType="cn.tedu.spring.entity.User">
	select * from user 
    <where>
        <iftest="password!=null">
           and password=#{password}
        </if>

        <iftest="username!=null">
            and username=#{username}
        </if>
    </where>
    
</select>
  • 如果此时在 User 对象中只是设置了一个 username 的值,那么会去掉前面的 and 关键字,并且此时的sql语句会变成: select * from user where username=#{username}

set元素

问题

  • 我们使用动态sql构建一个更新语句,如下:
<updateid="update"parameterType="cn.tedu.spring.entity.User">
	 	update user 
	 	set
	 	<iftest="password!=null">
	 		password=#{password},
	 	</if>
	 	
	 	<iftest="age!=null">
	 		age=#{age},
	 	</if>
	 	
	 	<iftest="username!=null">
	 		username=#{username}
	 	</if>
	 	
	 	where id=#{id}
	 </update>
  • 从上面的 <update> 中可以看出,如果我们在 User 对象中没有设置 password,age,username 的值,那么构建出来的sql语句变成了 update user set where id=#{id} ,很明显是一个错误的语句。
  • 如果在 User 对象中值设置了 password 的值,那么这里的sql语句变成了 update user set password=#{password}, where id=#{id} ,很明显,这个sql多了一个逗号

解决

  • 我们可以使用 <set> ,可以在 <set> 元素所在位置输出一个 set 关键字,而且可以去除内容结尾中无关的 逗号 ,有了 <set> 元素,那么我们可以动态的修改字段

格式

update table_name 
	<set>
		......
	</set>

实例

  • 解决上面的问题
<updateid="update"parameterType="cn.tedu.spring.entity.User">
	 	update user 
	 	<set>
            <iftest="password!=null">
                password=#{password},
            </if>

            <iftest="age!=null">
                age=#{age},
            </if>

            <iftest="username!=null">
                username=#{username}
            </if>
	 	</set>
	 	where id=#{id}
	 </update>

where 元素

作用

  • 使用动态sql可以解决SQL语句中代码复用问题,即2处或者多处高度相似的代码,在使用动态SQL之后,1个方法和1个映射就可以解决

总结

  1. 虽然在动态sql中,有很多标签可以实现对 SQL 语句的编程,但是,使用动态SQL的原则应该是希望代码复用,而不是编程,更不要用动态sql解决业务方法的问题
原文  https://chenjiabing666.github.io/2018/05/04/动态sql/
正文到此结束
Loading...