一、动态修改

在保存到数据库时,应当保存修改的数据,没有改动的数据应保留原来的。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. 使用#一般是用来取值的,而$符号一般用于动态排序