mybatis动态sql
一、Mybatis 中$与#的区别
- #是将传入的值当做字符串的形式,例:select id,name,age from student where id =#{id},当前端把id值1,传入到后台的时候,就相当于 select id,name,age from student where id =‘1’.
- $是将传入的数据直接显示生成sql语句,例:select id,name,age from student where id =${id},当前端把id值1,传入到后台的时候,就相当于 select id,name,age from student where id = 1.
- 使用#可以很大程度上防止sql注入。(语句的拼接)
- 但是如果使用在order by 中就需要使用 $.
- 在大多数情况下还是经常使用#,但在不同情况下必须使用$.
#与$的区别最大在于:#{} 传入值时,sql解析时,参数是带引号的,而${}穿入值,sql解析时,参数是不带引号的。
一 、 理解mybatis中$与#
在mybatis中的$与#都是在sql中动态的传入参数。
例:select id,name,age from student where name=#{name} 这个name是动态的,可变的。当你传入什么样的值,就会根据你传入的值执行sql语句。
二、使用$与#
#{}: 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符,一个 #{ } 被解析为一个参数占位符 。
${}: 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。
name–>cy
eg:
select id,name,age from student where name=#{name} – name=‘cy’
select id,name,age from student where name=${name} – name=cy
二、常用标签
<resultMap id="BaseResultMap" type="com.tg.domain.User">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="username" jdbcType="VARCHAR" property="username" />
<result column="password" jdbcType="VARCHAR" property="password" />
</resultMap>
<spl id="Base_Column_List">
id, username, `password`
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where id = #{id, jdbcType=BIGINT}
</select>
- if标签
test中写判断条件 参数直接paramN或者别名
特点:
只要成立就拼接在Sql语句中,都成立就全部都拼接
注意:
where子句中加上1=1来规避and的风险
<select id="selectByParam" resultType="log">
select * from log where 1=1
<if test="param1 != null and param1 != ''">
and outno = #{param1}
</if>
<if test="param2 != null and param2 != ''">
and inno = #{param2}
</if>
</select>
- where标签:
特点:
会自动的给Sql语句添加where关键字,并将第一个and去除。
<select id="selectByParam" resultType="log">
select * from log
<where>
<if test="param1 != null and param1 != ''">
and outno = #{param1}
</if>
<if test="param2 != null and param2 != ''">
and inno = #{param2}
</if>
</where>
</select>
- choose when otherwise标签
特点:
条件只要有一个成立,其他的就不会再判断了。
如果没有成立的条件则默认执行otherwise中的内容
<select id="selectByParam" resultType="log">
select * from log
<where>
<choose>
<when test="param1 != null and param1 != ''">
and outno = #{param1}
</when>
<when test="param2 != null and param2 != ''">
and inno = #{param2}
</when>
<otherwise>
and 1=1
</otherwise>
</choose>
</where>
</select>
- set标签:
产生一个set关键字,自动去除最后一个逗号。
注意:
在判断条件中最后保持有一个永远成立的条件。避免sql错误。
<update id="updateByParam" parameterType="account">
update account
<set>
<if test="aname != null and aname != ''">
aname = #{aname},
</if>
<if test="money != null and money != ''">
money = #{money},
</if>
<if test="ano != null and ano != ''">
ano = #{ano},
</if>
</set>
where ano = #{ano}
</update>
- trim标签:
prefix:在trim的内容前添加指定的内容
prefixOverrides在trim的内容前去除指定的内容
suffix:在trim的内容后添加指定的内容
suffixOverrides:在trim的内容后去除指定的内容
注意:
先去除后添加
添加内容会默认添加一个空格。
<update id="updateByParam" parameterType="account">
update account
<trim prefix="$" prefixOverrides="" suffix="" suffixOverrides="">
<if test="aname != null and aname != ''">
aname = #{aname},
</if>
<if test="money != null and money != ''">
money = #{money},
</if>
<if test="ano != null and ano != ''">
ano = #{ano},
</if>
</trim>
where ano = #{ano}
</update>
- bind标签:
name:参数名
value:表达式,注意字符串拼接按照变量方式进行拼接
例如:
<bind name=“money” value="’$’+money"/>
给参数重新赋值
<update id="updateByParam" parameterType="account">
<bind name="money" value="money + 100" />
update account
<trim prefix="set" suffixOverrides=",">
<if test="aname != null and aname != ''">
aname = #{aname},
</if>
<if test="money != null and money != ''">
money = #{money},
</if>
<if test="ano != null and ano != ''">
ano = #{ano},
</if>
</trim>
where ano = #{ano}
</update>
- sql和include标签:
sql标签:在外部声明公用SQL语句
id
include标签:引入声明的公共SQL语句
refid:
优点:便于SQL的整体修改
缺点:难于阅读
<select id="selectAll" resultType="account">
select <include refid="mysql"></include> from account
</select>
<sql id="mysql">
ano, aname, apassword, money
</sql>
- foreach标签:
collection:要遍历的集合对象
item:记录每次遍历的结果
open:在结果的左边添加内容
separator:结果和结果之间的内容
close:在最后添加的内容
<select id="selectByAno" parameterType="list" resultType="account">
select * from account where ano in
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
<insert id="save">
insert into log values
<foreach collection="list" item="log" separator=",">
(#{log.outno}, #{log.inno}, #{log.money})
</foreach>
</insert>
三、MyBatis动态SQL执行多条SQL
删除用户的时候需要先删除用户的外键关联数据,否则会触发规则报错。
解决办法不外乎有三个:①多条sql分批执行;②存储过程或函数调用;③sql批量执行。
- 修改数据库连接参数加上allowMultiQueries=true,如:
jdbc.url=jdbc:mysql://localhost:3306/acount?allowMultiQueries=true
- 直接写多条语句,用“;”隔开即可
<delete id="deleteUserById" parameterType="String">
delete from sec_user_role where userId=#{id};
delete from sec_user where id=#{id};
</delete>