动态SQL

动态 SQL 是 MyBatis 的强大特性之一。

优点:根据传入的值动态的改变代码,可以减少代码的冗余提高复用性。

目录:

Mybatis知识点(动态SQL)_sql

首先我们需要准备一张表用来测试动态的SQL

Mybatis知识点(动态SQL)_sql_02

建立一个实体类(VoteUser)

Mybatis知识点(动态SQL)_复用_03

为实体类编写持久层接口

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