动态 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( ("voteid")int voteid, ("index")int index, ("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( ("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.${}采用的是拼接的方发,并且容易引起注入攻击。