动态 SQL 是 MyBatis 的强大特性之一。
优点:根据传入的值动态的改变代码,可以减少代码的冗余提高复用性。
目录:
首先我们需要准备一张表用来测试动态的SQL
建立一个实体类(VoteUser)
为实体类编写持久层接口
public interface VoteUserDao { //实现分页查询(传入两个参数) public abstract List<VoteUser> LimitVoteUser(int index, int pagesize); }
配置Mapper.xml文件
<mapper namespace="dao.VoteUserDao"> <!--分页查询(不加注解@param时候使用下标) --> <select id="LimitVoteUser" resultType="entity.VoteUser"> SELECT * FROM voteuser LIMIT #{0},#{1} </select> </mapper>
大体流程如上接下来的代码会只挑重点展示。
条件判断--IF标签
//定义接口:实现根据传入的姓名来分页,当传入的值为null时则查询全部在分页 public abstract List<VoteUser> LimitByVoteid(@Param("voteid")int voteid,@Param("index")int index, @Param("pagesize")int pagesize);
<!--id挂载接口的名称,设置返回的类型为VoteUser类--> <select id="Limit" resultType="entity.VoteUser"> SELECT * FROM VOTEUSER where <if test="name!=null and name!=''"> username=#{name} </if> limit #{index},#{pagesize} </select>
当username不为空:
SELECT * FROM VOTEUSER where username=? limit ?,? (可以实现查询)
当username是空:
SELECT * FROM VOTEUSER where limit ?,? (很明显报错了)
解决方案:如下
WHERE标签
<select id="Limit" resultType="entity.VoteUser"> SELECT * FROM VOTEUSER <!--把where单独写成一个标签 当where有内容时会自动拼接一个where单词 当where内部没有内容的时候不会拼接where单词 当where内部有and时会过滤and --> <where> <if test="name!=null and name!=''"> username=#{name} </if> and userpower=0 </where> limit #{index},#{pagesize} </select>
当username是空:
Preparing: SELECT * FROM VOTEUSER WHERE userpower=0 limit ?,?
双分支标签CHOOSE标签
依然是查询上面的业务使用双分支和if想差无几
<!--sql是一种复用代码抽离标签将重复使用的sql写在标签里--> <sql id="all">* FROM</sql> <select id="sele" resultType="entity.VoteUser"> SELECT <include refid="all"></include> voteuser <where> <!--双分支选择结构 --> <choose> <when test="name!=null and name!=''"> username=#{name} </when> <otherwise> 1=1 </otherwise> </choose> </where> </select>
循环标签:FOREACH标签
我们使用批量插入业务来学习它
//接口传入一个List public abstract int insertmuch(@Param("list") List<VoteUser> list);
<!--foreach实现批量插入 --> <insert id="insertmuch" > insert into voteuser(userName,userPwd,userrank) values <foreach collection="list" item="user" separator=","> (#{user.userName,jdbcType=VARCHAR},#{user.userPwd,jdbcType=VARCHAR},#{user.userRank,jdbcType=INTEGER}) </foreach> </insert>
foreach会循环遍历传入的list拼接到sql上
字符串拼接标签:bind标签
<select id="selectLike" resultType="entity.VoteUser"> <bind name="uname" value="'%'+looklike+'%'"></bind> select * from voteuser where username like #{uname}; </select>
<select id="selectLike" resultType="entity.VoteUser"> select * from voteuser where username like concat("%",#{looklike},"%"); </select>
更新标签:set标签
<!--set 会自动在语句之前加上set--> <update id="Update"> update voteuser <set> userPwd=#{password} </set> <where> username=#{name} </where> </update>
${}与#{}的区别
1.#{}使用的是preparestament方法来注入占位符,读取参数后会在后面加上字符串" "的引号符
2.${}采用的是拼接的方发,并且容易引起注入攻击。