SQL动态查询
if 标签
● 作用 :
①用于判断条件是否满足,满足就拼接sql,不满足不拼接
②会自动加上空格,避免造成sql语法错误
● 注意:
①如果参数是字符串类型,那么需要判断null和空字符串【去空白】;
②如果参数是数值类型,只需要判断null值;
<select id="方法名" resultType="返回值类型">
select * from table where
<if test="判断条件">
sqly语句
</if>
</select>
where 标签
● 作用:
● ①拼接了一个where
● ②忽略第一个多余的and 或者 or
● ③自动加空格
模糊查询
● 方案一:直接用#,日志中发现值并没有替换,所有不能直接使用#
○ and (name like '%#{keywords}%' or password like '%#{keywords}%')
● 方案二:使用$符号,测试成功,但是可能会出现SQL注入
○ and (name like '%${keywords}%' or password like '%${keywords}%')
● 方案三:用mysql中字符串拼接函数concat,测试成功,也不会出现SQL注入,建议使用
○ and(name like concat('%',#{keywords},'%') or password like concat('%',#{keywords},'%')
特殊符号处理
● 在xml的转义字符:
①符号:<【<】、<=【<=】、>【>】、>=【>=】、&【&】、'【'】 、"【"】
②【gt -> greater than(大于 )lt -> less than(小于)】
● 或者可以用CDATA代码段:
①大于等于 <![CDATA[ >= ]]>
②小于等于 <![CDATA[ <= ]]>
sql代码块的抽取
<!--抽取公共sql
sql标签
id="唯一标识符"
include标签 包含公共sql
refid=“公共sql的id”
-->
<select id="finByDIY" resultType="com.jxh.domain.Emp">
select * from emp <include refid="select"/>
</select>
<sql id="select">
<where>
<if test="name!=null and !' '.equals(name.trim())">
name=#{name}
</if>
<if test="address!=null and !' '.equals(address.trim())">
and address like concat('%',#{address},'%')
</if>
and <![CDATA[age < 21]]>
</where>
</sql>
批量增删
批量新增
<!--批量新增
void addList(List<Dept> depts);
foreach 遍历
collection=“集合的名称”
特殊情况只有一个参数的时候,可以直接写集合list类型,数组array
item 遍历出的对象
separator 以什么分开
insert into dept(id, name) VALUES (#{dept.id},#{dept.name}),(#{dept.id},#{dept.name}),(#{dept.id},#{dept.name});
-->
<insert id="addList">
insert into dept(id, name) VALUES
<foreach collection="list" item="dept" separator=",">
(#{dept.id},#{dept.name})
</foreach>
</insert>
批量删除
<!--批量删除
void deleteDeptByIds(Long[] ids);
foreach 遍历
collection=“集合的名称”
特殊情况只有一个参数的时候,可以直接写集合list类型,数组array
item 遍历出的对象
open 以什么开始 一次
separator 以什么分开
close 以什么结束 一次
delete from dept where id in (#{id},#{id},#{id},#{id})
-->
<delete id="deleteDeptByIds">
delete from dept where id in
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
数据映射
映射:就是讲数据库表的数据 映射给 java对象
使用原因
原因一:解决表字段名和对象属性名不一样的情况
原因二:关联对象查询,就必须要使用resultMap来配置
案例
一对多,关联查询
<!--查询所有部门,以及每个部门对应的员工列表list
List<Dept> findDeptAll();
自动映射 满足不了多表查询的业务需求
需要自定义映射, 某一个部门对应的多个员工
resultMap="自定义映射的 id"
-->
<select id="findDeptAll" resultMap="deptMap">
select d.*,e.id eid,e.name ename,e.age,e.address,e.dept_id
from dept d
left join emp e
on d.id = e.dept_id
</select>
<!--自定义映射,自己定义规则封装结果集
resultMap 标签 自定义映射
id=唯一标识符
type="封装的java对象类型"
id 标签 标识主键
column 查询结果对应的列名
property java类型对应的 对象属性名称
result 标签,非主键的列,结果集封装
column 查询结果对应的列名
property java类型对应的 对象属性名称
collection 标签,封装集合
property java类型对应的 对象属性名称
ofType 集合的java类型
-->
<resultMap id="deptMap" type="cn.itsource.domain.Dept">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<collection property="empList" ofType="cn.itsource.domain.Emp">
<id column="eid" property="id"></id>
<result column="ename" property="name"></result>
<result column="age" property="age"></result>
<result column="address" property="address"></result>
<result column="dept_id" property="dept_id"></result>
</collection>
</resultMap>
多对一,关联查询
<!--
关联查询 多对一
查询每一个员工所属的部门信息
List<Emp> findMsgAll();-->
<select id="findMsgAll" resultMap="empMap">
select e.*,d.id did,d.name dname from emp e
left join dept d on d.id = e.dept_id
</select>
<!--自定义映射
collection 标签,封装集合
association 标签,封装的单个对象
-->
<resultMap id="empMap" type="cn.itsource.domain.Emp">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="age" property="age"></result>
<result column="address" property="address"></result>
<result column="dept_id" property="dept_id"></result>
<association property="dept" javaType="cn.itsource.domain.Dept">
<id column="did" property="id"></id>
<result column="dname" property="name"></result>
</association>
</resultMap>