ssm复习第三天

84 阅读4分钟

4. 模糊查询

package cn.chenmanman.mapper;

import cn.chenmanman.pojo.User;

import java.util.List;

public interface SpecialSqlMapper {
    /**
* <p>通过username来模糊查询</p>
* @param username 用户名
* @return 模糊查询出来的一组用户
* */
    List<User> selectUserForUsername(String username);
}
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.chenmanman.mapper.SpecialSqlMapper">

  <select id="selectUserForUsername" resultType="User">
    select * from user where username like '%#{username}%'
  </select>

</mapper>

select * from user where username like '%#{username}%'

此处不可以使用这条sql来进行模糊查询,因为mybatis会将#{username}变为?放入'%%'内。然后预编译设置值时,?属于''内的一部分,因此会报错。

可以使用下面三种方式:

select * from user where username like '%${username}%'

这条使用了${},因为它是字符串拼接的方式。

select * from user where username like concat('%', #{username}, '%')

这个也可以,因为是sql字符串拼接,会将这仨拼接为一个字符串,这里#{username}会被设置上值。

select * from user where username like "%"#{username}"%"

5. 批量删除

delete from user where user.id in(#{list})

批量删除这里不可以使用#{},如果使用#{}的方法的话因为是字符串类型,字符串类型的参数会加上单引号。

delete from user where user.id in(${list})

因此可以使用${}

6. 动态设置表名

select * from #{tablename}

这里也不行,原因是字符串类型的参数会加上单引号

所以使用:

select * from ${tablename}

5. ResultMap自定义映射

1. 处理java类属性名与数据库字段名不一致

可以用三种方法来解决名字不一样的问题。

  1. sql查询在select中起别名
  2. 在mybatis配置文件中的settings标签中设置mapUnderscoreToCamelCase属性为true,但是前提是java类属性的名字遵守驼峰命名,数据库字段中的名字各单词之间_连接
  3. 自定义映射,resultMap
package cn.chenmanman.pojo;

public class Dept {
    private Integer empId;
    private String empName;

    public Dept() {
    }

    public Dept(Integer empId, String empName) {
        this.empId = empId;
        this.empName = empName;
    }

    public Integer getEmpId() {
        return empId;
    }

    public void setEmpId(Integer empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    @Override
    public String toString() {
        return "Dept{" +
            "empId=" + empId +
            ", empName='" + empName + ''' +
            '}';
    }
}
package cn.chenmanman.pojo;

public class Emp {
    private Integer empId;
    private String empName;
    private Integer age;
    private String gender;
    private Dept dept;

    public Emp() {
    }

    public Emp(Integer empId, String empName, Integer age, String gender, Dept dept) {
        this.empId = empId;
        this.empName = empName;
        this.age = age;
        this.gender = gender;
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empId=" + empId +
                ", empName='" + empName + ''' +
                ", age=" + age +
                ", gender='" + gender + ''' +
                ", dept=" + dept +
                '}';
    }

    public Integer getEmpId() {
        return empId;
    }

    public void setEmpId(Integer empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }
}

emp字段:

dept字段:

处理不一致关系的xml:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.chenmanman.mapper.EmpMapper">
  <!-- 自定义映射规则 -->
  <resultMap id="empResultMap" type="emp">
    <!--
    column: 数据库字段列
    property: 实体类属性
    -->
    <!-- 处理主键和实体类属性的映射 -->
    <id column="emp_id" property="empId"/>
    <!-- 处理普通字段和实体类属性的映射 -->
    <result column="emp_name" property="empName"/>
    <result column="age" property="age"/>
    <result column="gender" property="gender"/>
  </resultMap>
  <select id="selectEmpAll" resultMap="empResultMap">
    select * from t_emp
  </select>
</mapper>

2. 处理多对一关系映射

package cn.chenmanman.pojo;

public class Dept {
    private Integer empId;
    private String empName;

    public Dept() {
    }

    public Dept(Integer empId, String empName) {
        this.empId = empId;
        this.empName = empName;
    }

    public Integer getEmpId() {
        return empId;
    }

    public void setEmpId(Integer empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    @Override
    public String toString() {
        return "Dept{" +
            "empId=" + empId +
            ", empName='" + empName + ''' +
            '}';
    }
}
package cn.chenmanman.pojo;

public class Emp {
    private Integer empId;
    private String empName;
    private Integer age;
    private String gender;
    private Dept dept;

    public Emp() {
    }

    public Emp(Integer empId, String empName, Integer age, String gender, Dept dept) {
        this.empId = empId;
        this.empName = empName;
        this.age = age;
        this.gender = gender;
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empId=" + empId +
                ", empName='" + empName + ''' +
                ", age=" + age +
                ", gender='" + gender + ''' +
                ", dept=" + dept +
                '}';
    }

    public Integer getEmpId() {
        return empId;
    }

    public void setEmpId(Integer empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }
}

此处一方为emp,多方为dept。

希望在查询emp的时候能知道这个emp属于哪个dept

有三种解决办法

  1. 级联赋值
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.chenmanman.mapper.EmpMapper">
    <resultMap id="empResultMap" type="emp">
        <!--
         column: 数据库字段列
         property: 实体类属性
         -->
        <!-- 处理主键和实体类属性的映射 -->
        <id column="emp_id" property="empId"/>
        <!-- 处理普通字段和实体类属性的映射 -->
        <result column="emp_name" property="empName"/>
        <result column="age" property="age"/>
        <result column="gender" property="gender"/>
        <result column="dept_id" property="dept.deptId"/>
        <result column="dept_name" property="dept.deptName"/>
    </resultMap>
    <select id="selectEmpAll" resultMap="empResultMap">
        select * from t_emp emp left join t_dept td on emp.dept_id = td.dept_id
    </select>
</mapper>

  1. 使用association

association标签用于处理多对一关系(实际上是用来处理实体类中的实体类属性)。

其中属性property为实体类属性中的属性,javaType为实体类属性的类型。

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.chenmanman.mapper.EmpMapper">
  <!-- 自定义映射规则 -->
  <resultMap id="empResultMapOne" type="emp">
    <!--
    column: 数据库字段列
    property: 实体类属性
    -->
    <!-- 处理主键和实体类属性的映射 -->
    <id column="emp_id" property="empId"/>
    <!-- 处理普通字段和实体类属性的映射 -->
    <result column="emp_name" property="empName"/>
    <result column="age" property="age"/>
    <result column="gender" property="gender"/>
  </resultMap>


  <resultMap id="empResultMapTwo" type="emp">
    <!--
    column: 数据库字段列
    property: 实体类属性
    -->
    <!-- 处理主键和实体类属性的映射 -->
    <id column="emp_id" property="empId"/>
    <!-- 处理普通字段和实体类属性的映射 -->
    <result column="emp_name" property="empName"/>
    <result column="age" property="age"/>
    <result column="gender" property="gender"/>
    <result column="dept_id" property="dept.deptId"/>
    <result column="dept_name" property="dept.deptName"/>
  </resultMap>


  <resultMap id="empResultMap" type="emp">
    <!--
    column: 数据库字段列
    property: 实体类属性
    -->
    <!-- 处理主键和实体类属性的映射 -->
    <id column="emp_id" property="empId"/>
    <!-- 处理普通字段和实体类属性的映射 -->
    <result column="emp_name" property="empName"/>
    <result column="age" property="age"/>
    <result column="gender" property="gender"/>
    <association property="dept" javaType="dept">
      <id column="dept_id" property="deptId"/>
      <id column="dept_name" property="deptName"/>
    </association>
  </resultMap>
  <select id="selectEmpAll" resultMap="empResultMap">
    select * from t_emp emp left join t_dept td on emp.dept_id = td.dept_id
  </select>
</mapper>

  1. 分步查询

首先查emp查到emp将dept_id传给第二步查询

column: 查询到的字段传给select

select: 下一步的查询方法

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.chenmanman.mapper.EmpMapper">
    <!-- 自定义映射规则 -->
    <resultMap id="empResultMapByStep" type="Emp">
        <id column="emp_id" property="empId"/>
        <!-- 处理普通字段和实体类属性的映射 -->
        <result column="emp_name" property="empName"/>
        <result column="age" property="age"/>
        <result column="gender" property="gender"/>
        <association property="dept"
                    column="emp_id"
                    select="cn.chenmanman.mapper.DeptMapper.selectDeptByIdForStepTwo"/>
    </resultMap>
    <select id="selectEmpByIdForStepOne" resultMap="empResultMapByStep">
        select * from t_emp where  emp_id = #{empId}
    </select>
</mapper>
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.chenmanman.mapper.DeptMapper">
    <select id="selectDeptByIdForStepTwo" resultType="Dept">
        select * from t_dept where dept_id = #{dept_id}
    </select>
</mapper>

3. 延迟加载

在settings标签中设置下面两个属性

lazyLoadingEnabled:延迟加载的全局开关,开启的时候,所有关联独享都会延迟加载。特定关联关系中可以通过设置fetchType属性来覆盖,在此处设置为true

aggressiveLazyLoading:开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载

将lazyLoadingEnabled设置为true aggressiveLazyLoading设置为false

当在某些地方不希望使用延迟加载属性的话,使用fetchType属性设置为eager

4. 一对多关系映射

一对多关系映射的两种方式

  1. collection标签

在collection标签使用的是ofType集合中所包含的元素类型

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.chenmanman.mapper.DeptMapper">
    <resultMap id="deptAndEmpResultMap" type="Dept">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
        <collection property="empList" ofType="emp">
            <id property="empId" column="emp_id"/>
            <result property="empName" column="emp_name"/>
            <result property="age" column="age"/>
            <result property="gender" column="gender"/>
        </collection>
    </resultMap>
    <select id="selectDeptAndEmpById" resultMap="deptAndEmpResultMap">
        select * from t_dept left join t_emp te on t_dept.dept_id = te.dept_id where te.dept_id = #{dept_id}
    </select>
</mapper>
  1. 分布查询

这个一对多分布查询,先查一方的然后再根据入参查一方对应的多方。

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.chenmanman.mapper.DeptMapper">
    <resultMap id="deptAndEmpResultMapByStep" type="Dept">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
        <collection property="empList"
                    select="cn.chenmanman.mapper.EmpMapper.selectDeptAndEmpByIdForStepTwo"
                    column="dept_id"/>
    </resultMap>
    <!-- 通过查询部门分布查询 -->
    <select id="selectDeptAndEmpByIdForStepOne" resultMap="deptAndEmpResultMapByStep">
        select * from t_dept where dept_id = #{dept_id}
    </select>
</mapper>
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.chenmanman.mapper.EmpMapper">
    <select id="selectDeptAndEmpByIdForStepTwo" resultType="emp">
        select * from t_emp where dept_id = #{deptId}
    </select>
</mapper>