一、动态修改
在保存到数据库时,应当保存修改的数据,没有改动的数据应保留原来的。set标签里可以加入判断完成动态修改
<update id="update">
UPDATE student
<set>
<if test="name!=null and name!=''">
name=#{name},
</if>
<if test="age!=null">
age=#{age},
</if>
<if test="email!=null and email!=''">
email=#{email},
</if>
<if test="sex!=null">
sex=#{sex},
</if>
</set>
WHERE id=#{id}
</update>
多对一保存和查询
注意: 映射关联对象 association
映射集合使用collection
保存
在多方中定义一个一方类
public class Employee {
private Long id;
private String name;
private Integer age;
private Dept dept;
先保存一方再保存多方
deptMapper.save(dept);
employeeMapper.save(e);
保存一方时需要返回主键
<insert id="save" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO t_dept(name) VALUES (#{name})
</insert>
保存多方时保存一方的主键
<insert id="save" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO t_employee(name, age, dept_id) VALUES (#{name},#{age},#{dept.id})
</insert>
查询的两种方式
关联查询
查询语句和以前一样 注意取别名
<select id="selectAllG" resultMap="employeeResultMap">
SELECT e.id,e.name,e.age,d.id did,d.name dname
FROM employee e JOIN dept d
on e.dept_id = d.id
</select>
自定义映射
<!--
映射关联对象 association
property="dept" 映射Employee中的dept属性
javaType="cn.itsource._02many2one.domain.Dept dept属性对应的类型
注意:当你使用了association映射之后,默认映射规则失效
-->
<resultMap id="employeeResultMap" type="cn.itsource._02many2one.domain.Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<association property="dept" javaType="cn.itsource._02many2one.domain.Dept">
<id column="did" property="id"/>
<result column="dname" property="name"/>
</association>
</resultMap>
子查询
发送多条sql语句 性能差
<select id="selectAllZ" resultMap="employeeResultMap2">
SELECT * FROM employee
</select>
<resultMap id="employeeResultMap2" type="cn.itsource._02many2one.domain.Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<!--
把dept_id这一列对应的值,到DeptMapper中selectById该sql语句中进行查询,把查询出来的对象
封装到Employee中的dept属性中
-->
<association property="dept" column="dept_id"
select="cn.itsource._02many2one.mapper.DeptMapper.selectById"/>
</resultMap>
一对多保存和查询
保存
先保存一方(返回主键)
再遍历一方中的多方集合 逐个保存
deptMapper.save(dept);
/*遍历部门中的员工 保存*/
dept.getEmployees().forEach(e->employeeMapper.save(e, dept.getId()));
sqlSession.commit();
}
取别名
void save(@Param("e") Employee employee, @Param("deptId") Long deptId);
利用别名确定保存的类型
<insert id="save">
INSERT INTO employee(name, age, dept_id) VALUES (#{e.name},#{e.age},#{deptId})
</insert>
查询
关联查询和子查询
<select id="selectAllG" resultMap="deptResultMap">
SELECT d.id,d.name,e.id eid,e.name ename,e.age eage
FROM dept d JOIN employee e
ON d.id = e.dept_id
ORDER BY d.id
</select>
<resultMap id="deptResultMap" type="cn.itsource._03one2many.domain.Dept">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--
映射集合要使用collection
注意:使用了collection映射之后,默认映射规则失效
-->
<collection property="employees" ofType="cn.itsource._03one2many.domain.Employee">
<id column="eid" property="id"/>
<result column="ename" property="name"/>
<result column="eage" property="age"/>
</collection>
</resultMap>
<select id="selectAllZ" resultMap="deptResultMap2">
SELECT * FROM dept
</select>
<resultMap id="deptResultMap2" type="cn.itsource._03one2many.domain.Dept">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="employees" ofType="cn.itsource._03one2many.domain.Employee"
column="id"
select="cn.itsource._03one2many.mapper.EmployeeMapper.selectByDeptId"/>
</resultMap>
注意事项
#与$符号的区别:
共同点: #和$都是用来取值的
参数传递普通类型(8大基本数据类型8大包装类。再加一个String)
#: 正常发送的sql语句 SELECT * FROM t_student WHERE id=?
$: 传递普通类型,它是要报错的,取不到值
参数传递对象
#: 正常发送的sql语句 SELECT * FROM t_student WHERE id=?
$: 正常发送sql语句 SELECT * FROM t_student WHERE id=2
区别:
1.
#它可以取任意类型的参数
$只能取对象中的值,不能取普通类型的值
2. #取值可以有效防止sql注入 ,$符号取值它是sql拼接,不能有效防止sql注入
3. #取值让sql语句支持预编译的功能,而$符号是不支持的,所以在性能上来说#取值性能要高于$符号
4. 使用#一般是用来取值的,而$符号一般用于动态排序