特殊SQL和ResultMap

特殊SQL

1.模糊查询

List<User> getUserByLike(@Param("mohu") String mohu);
<select id="getUserByLike" resultType="user">
    SELECT * FROM t_user WHERE username like '%${mohu}%'
</select>

<select id="getUserByLike" resultType="user">
    SELECT * FROM t_user WHERE username like CONCAt('%', #{mohu}, '%');
</select>

<!-- 第三种方式:用的最多的方式的 -->
<select id="getUserByLike" resultType="user">
    SELECT * FROM t_user WHERE username like "%"#{mohu}"%"
</select>

2.批量删除

即传入的参数数量不确定 这里直接先构成一个字符串,再使用拼接方式传入即可。

int deleteMore(@Param("ids") String ids);
<!-- ids = "1,2,3" -->
<delete id="deleteMore" resultType="int">
  DELETE FROM t_user WHERE id in (${ids})
</delete>

3.动态表名

表查询的字段相同,但是表名称不相同

List<User> getUserList(@Param("tableName") String tableName);
<select id="getUserList" resultType="user">
  SELECT * FROM ${tableName}; 
</select>

4 获取自增主键

比如一个班级表和一个学生表,在一个事务当中先创建一个班级(使用的是自增的主键)然后在这个班级里面添加若干的学生。

Integer insertUser(User user);
<insert id="insertUser" resultType="int" useGeneratedKeys="true" keyProperty="id">
  INSERT INTO t_user VALUES(NULL, #{username}, #{password}, #{age}, #{gender}, #{email});
</insert>

ResultMap

1.方式一:查询的时候使用别名 和属性名保持一致

方式二:

当字段符合MysQL的要求使用_,而属性符合java的要求使用驼峰

此时可以在MayBatis的核心配置文件中设置一个全局配置,可以自动将下划线映射为驼峰

emp id : empid, emp name : empName

<settings>
    <!-- 下划线 自动映射 驼峰 -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

方法三:使用resultMap自定义映射处理

Emp getEmpByEmpId(@Param("empId") Integer empId);
<mapper namespace="com.atguigu.mybatis.mapper.EmpMapper">

    <!-- 相同的属性和名称不用写也行的 -->
    <resultMap id="empResultMap" type="Emp">
        <!-- id 处理主键和属性字段的映射关系 -->
        <id column="emp_id" property="empId"></id>

        <!-- result 处理普通字段和属性的映射关系 -->
        <result column="emp_name" property="empName"></result>

    </resultMap>
    
    <!-- Emp getEmpByEmpId(@Param("empId") Integer empId); -->
    <select id="getEmpByEmpId" resultMap="empResultMap">
        SELECT * FROM t_emp WHERE emp_id = #{empId};
    </select>

</mapper>

1.多对一关系

POJO : 多个Emp 对应一个 Dept

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

    private Dept dept;
    
    // getter/setter/toString
}

方式一:级联方式处理

Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);
<resultMap id="getEmpAndDeptByEmpId" type="Emp">
    <id column="emp_id" property="empId"></id>
    <result column="emp_name" property="empName"></result>

    <!-- 级联方式:多对一的映射关系 -->
    <result column="dept_id" property="dept.deptId"></result>
    <result column="dept_name" property="dept.deptName"></result>
</resultMap>

<select id="getEmpAndDeptByEmpId" resultMap="getEmpAndDeptByEmpId">
    SELECT *
    FROM t_emp
    LEFT JOIN t_dept
    ON t_emp.dept_id = t_dept.dept_id
    WHERE emp_id = #{empId};
</select>

方式二: association 标签

<resultMap id="getEmpAndDeptByEmpId" type="Emp">
    <id column="emp_id" property="empId"></id>
    <result column="emp_name" property="empName"></result>

    <!-- association : 专门处理多对一、一对一 的映射关系 -->
    <association property="dept" javaType="Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
    </association>
</resultMap>

<select id="getEmpAndDeptByEmpId" resultMap="getEmpAndDeptByEmpId">
    SELECT *
    FROM t_emp
    LEFT JOIN t_dept
    ON t_emp.dept_id = t_dept.dept_id
    WHERE emp_id = #{empId};
</select>

方式三:分布查询,先查询出Emp,再根据Emp中deptId 查询 Dept

分步查询的优点:可以实现延迟加载

DeptMapper.java

/**
 * 分步查询的第一步
 * @param empId
 * @return
 */
Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);

DeptMapper.java

/**
 * 分步查询的第二步
 * @param deptId
 * @return
 */
Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);

EmpMapper.xml

<resultMap id="getEmpAndDeptByStepResultMap" type="Emp">
    <id column="emp_id" property="empId"></id>
    <result column="emp_name" property="empName"></result>

    <!--
        property: 关联的类型
        fetchType: eager 表示全局配置了懒加载,但是这里我还是想立即加载
        select: 第二步查询的唯一标识
        column: 第一步查询出来的外键
    -->
    <association property="dept" fetchType="eager"
                 select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                 column="dept_id" ></association>
</resultMap>

<!-- Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId); -->
<select id="getEmpAndDeptByStepOne" resultMap="getEmpAndDeptByStepResultMap">
    SELECT * FROM t_emp WHERE emp_id = #{empId};
</select>

DeptMapper.xml

<!-- Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);
     这里没有使用 ResultMap, 因为开启了 下划线 转 驼峰的配置
-->
<select id="getEmpAndDeptByStepTwo" resultType="dept">
    SELECT * FROM t_dept WHERE dept_id = #{dept_id};
</select>

2.一对多关系

POJO:一个 Dept 对应多个 Emp

public class Dept {
    private Integer deptId;
    private String deptName;

    private List<Emp> emps;
  
    // getter/setter/toString
}

方式一:级联 + collection

Dept getDeptAndEmpsByDeptId(@Param("deptId") Integer deptId);
<resultMap id="getDeptAndEmpsByDeptIdResultMap" type="dept">
    <id column="dept_id" property="deptId"></id>
    <result column="dept_name" property="deptName"></result>

    <!--
        property: 关联的属性.
        ofType: 集合内部元素的类型.
     -->
    <collection property="emps" ofType="emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
    </collection>
</resultMap>

<!-- Dept getDeptAndEmpsByDeptId(@Param("deptId") Integer deptId); -->
<select id="getDeptAndEmpsByDeptId" resultMap="getDeptAndEmpsByDeptIdResultMap">
    SELECT *
    FROM t_dept
    LEFT JOIN t_emp
    ON t_dept.dept_id = t_emp.dept_id
    WHERE t_dept.dept_id = #{deptId};
</select>

方式二:分布查询,先查询部门,再根据部门的id查询部门下的员工

DeptMapper.java

/**
 * 分步查询 查询部门以及部门中的员工的信息
 * @param deptId
 * @return
 */
Dept getDeptAndEmpdsStepOne(@Param("deptId") Integer deptId);

EmpMapper.java

/**
 * 分布查询的第二步:查询出一个部门下的员工
 * @param empId
 * @return
 */
Emp getDeptAndEmpdsStepTwo(@Param("empId") Integer empId);

DeptMapper.xml

<resultMap id="getDeptAndEmpdsStepOneResultMap" type="dept">
    <id column="dept_id" property="deptId"></id>
    <result column="dept_name" property="deptName"></result>
    
    <!-- fetchType="eager" 关闭懒加载 -->
    <collection property="emps" fetchType="eager" ofType="emp"
                 select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpdsStepTwo"
                 column="dept_id">

    </collection>
</resultMap>

<!-- Dept getDeptAndEmpdsStepOne(@Param("deptId") Integer deptId); -->
<select id="getDeptAndEmpdsStepOne" resultMap="getDeptAndEmpdsStepOneResultMap">
    SELECT *
    FROM t_dept
    WHERE dept_id = #{deptId};
</select>

EmpMapper.xml

<!-- Emp getDeptAndEmpdsStepTwo(@Param("empId") Integer empId);
     这里没有使用resultMap, 因为已经开启了下划线转驼峰的配置
-->
<select id="getDeptAndEmpdsStepTwo" resultType="emp">
    SELECT *
    FROM t_emp
    WHERE emp_id = #{empId};
</select>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是秀秀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值