mybatis学习笔记(第三部分)

简介: 自学笔记

7、特殊SQL的执行

7.1、模糊查询

/**
* 测试模糊查询
* @param mohu
* @return
*/
List<User> testMohu(@Param("mohu") String mohu);
<!--List<User> testMohu(@Param("mohu") String mohu);-->
<select id="testMohu" resultType="User">
<!--select * from t_user where username like '%${mohu}%'-->
<!--select * from t_user where username like concat('%',#{mohu},'%')-->
select * from t_user where username like "%"#{mohu}"%"
</select>

7.2、批量删除

/**
* 批量删除
* @param ids
* @return
*/
int deleteMore(@Param("ids") String ids);
<!--int deleteMore(@Param("ids") String ids);-->
<delete id="deleteMore">
delete from t_user where id in (${ids})
</delete>

7.3、动态设置表名

/**
* 动态设置表名,查询所有的用户信息
* @param tableName
* @return
*/
List<User> getAllUser(@Param("tableName") String tableName);
<!--List<User> getAllUser(@Param("tableName") String tableName);-->
<select id="getAllUser" resultType="User">
select * from ${tableName}
</select>

7.4、添加功能获取自增的主键

  • 场景模拟:
  • t_clazz(clazz_id,clazz_name)
  • t_student(student_id,student_name,clazz_id)
    • 1、添加班级信息
    • 2、获取新添加的班级的id
    • 3、为班级分配学生,即将某学的班级id修改为新添加的班级的id
/**
* 添加用户信息
* @param user
* @return
* useGeneratedKeys:设置使用自增的主键
* keyProperty:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参
数user对象的某个属性中
*/
int insertUser(User user);
<!--int insertUser(User user);-->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into t_user values(null,#{username},#{password},#{age},#{sex})
</insert>

8、自定义映射resultMap

8.1、resultMap处理字段和属性的映射关系

8.1.1、三种方式

对于字段名和属性名不一致的情况,如何处理映射关系

  • 1、为查询的字段设置别名,和属性名保持一致 (一般不用)

  • 2、当字段符合mysql的要求使用_,而属性符合java要求使用驼峰

  • 此时可以在mybatis的核心配置文件中设置一个全局配置
  • 可以自动将下划线映射为驼峰
  • emp_id:empId,emp_name:empName
<!--设置将下划线映射为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
  • 3、使用resultMap自定义处理映射
  • resultMap:
    • resultMap:自定义的映射关系
    • id:唯一标识
    • type:处理映射关系的实体类的类型
    • 使用了resultMap就需要把每个映射关系都写出来
    • 常用的标签:
      • id:处理主键和实体类中属性的映射关系
      • result:处理普通字段和实体类中属性的映射关系
      • association:处理多对一的映射关系(处理实体类类型的属性)
      • column:设置映射关系中的字段名,必须是SQL查询出的某个字段
      • property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名
//测试处理字段和属性名不一致情况下的映射关系
Emp getEmpByEmpId(@Param("empId") Integer empId);
<!--Emp getEmpByEmpId(@Param("empId") Integer empId);-->
<!--
    处理字段名和属性名不一致的情况,如何处理映射关系
    1、为查询的字段设置别名,和属性名保持一致 (一般不用)
    2、当字段符合mysql的要求使用_,而属性符合java要求使用驼峰
    此时可以在mybatis的核心配置文件中设置一个全局配置,
    可以自动将下划线映射为驼峰
    emp_id:empId,emp_name:empName
    3、使用resultMap自定义处理映射
 -->

<!--
    resultMap:自定义的映射关系
    id:唯一标识
    type:处理映射关系的实体类的类型
    使用了resultMap就需要把每个映射关系都写出来
   常用的标签:
   id:处理主键和实体类中属性的映射关系
   result:处理普通字段和实体类中属性的映射关系
   association:处理多对一的映射关系(处理实体类类型的属性)
   column:设置映射关系中的字段名,必须是SQL查询出的某个字段
   property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名
-->
<resultMap id="empResultMap" type="Emp">
    <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="getEmpByEmpId" resultMap="empResultMap">
    select * from t_emp where emp_id = #{empId}
</select>
<select id="getEmpByEmpIdOld" resultType="Emp">
    select * from t_emp where emp_id = #{empId}
</select>

8.2、多对一映射处理

  • 场景模拟:查询员工信息以及员工所对应的部门信息
  • 一个部门对应着多个员工,要查询完整的员工信息,就需要根据数据库中员工所在部门的部门id查询到对应的部门信息。

8.2.1、级联方式处理映射关系

<resultMap id="empDeptMap" type="Emp">
<id column="eid" property="eid"></id>
<result column="ename" property="ename"></result>
<result column="age" property="age"></result>
<result column="sex" property="sex"></result>
<result column="did" property="dept.did"></result>
<result column="dname" property="dept.dname"></result>
</resultMap>
<!--Emp getEmpAndDeptByEid(@Param("eid") int eid);-->
<select id="getEmpAndDeptByEid" resultMap="empDeptMap">
select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did =
dept.did where emp.eid = #{eid}
</select>

8.2.2、使用association处理映射关系

<resultMap id="empAndDeptResultMap" 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:设置需要处理映射关系的属性的属性名
        JavaType:表示要处理属性的类型,使用别名
    -->
    <association property="dept" javaType="Dept">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
    </association>
</resultMap>
<!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">
    select *
    from t_emp
    left join t_dept on t_emp.dept_id = t_dept.dept_id
    where emp_id = #{empId}
</select>

8.2.3、分步查询

//通过分步查询获取员工和部门的信息第一步
Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);
//通过分步查询获取员工和部门的信息第二步,查询部门信息
Dept getEmpAndDeptByStepTwo(@Param("deptId")Integer deptId);
<resultMap id="empAndDeptByStepResultMap" type="Emp">
    <id column="emp_id" property="empId"/>
    <result column="emp_name" property="empName"/>
    <result column="age" property="age"/>
    <result column="gender" property="gender"/>
    <!--
        fetchType:在开启延迟加载的环境中,指定当前的sql是延迟加载还是立即加载
                   eager表示立即加载,lazy表示懒加载
        property:设置需要处理映射关系的属性的属性名
        select:设置分步查询的SQL的唯一标识
        column:将查询出来的某个字段作为分布查询的SQL条件
    -->
    <association fetchType="eager"
                 property="dept"
                 select="com.zylai.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                 column="dept_id">
    </association>
</resultMap>

<!--Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
    select * from t_emp where emp_id = #{empId}
</select>

8.2.4、延迟加载

  • 在核心配置文件中配置
<!--开启延迟加载
    对于分步查询,关联的对象将会延迟加载。
    比如获取emp信息,如果只是打印emp.getEmpName(),用不到Dept的信息
    那么查询Dept的第二步将不会执行。
-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--value为false时按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
  • 开启之后还可以在mapper映射文件特定sql中的association标签的fetchType属性选择是立即加载还是延迟加载

8.3、一对多映射处理

8.3.1、collection

  • collection标签表示一端中的集合,标签的ofType属性指定集合中的类型
/**
* 根据部门id查新部门以及部门中的员工信息
* @param did
* @return
*/
Dept getDeptEmpByDid(@Param("did") int did);
<resultMap id="deptEmpMap" type="Dept">
<id property="did" column="did"></id>
<result property="dname" column="dname"></result>
<!--
ofType:设置collection标签所处理的集合属性中存储数据的类型
-->
<collection property="emps" ofType="Emp">
<id property="eid" column="eid"></id>
<result property="ename" column="ename"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
</collection>
</resultMap>
<!--Dept getDeptEmpByDid(@Param("did") int did);-->
<select id="getDeptEmpByDid" resultMap="deptEmpMap">
select dept.*,emp.* from t_dept dept left join t_emp emp on dept.did =
emp.did where dept.did = #{did}
</select>

8.3.2、分步查询

  • 1、 查询部门信息
/**
* 分步查询部门和部门中的员工
* @param did
* @return
*/
Dept getDeptByStep(@Param("did") int did);
<resultMap id="deptEmpStep" type="Dept">
<id property="did" column="did"></id>
<result property="dname" column="dname"></result>
<collection property="emps" fetchType="eager"
select="com.atguigu.MyBatis.mapper.EmpMapper.getEmpListByDid" column="did">
</collection>
</resultMap>
<!--Dept getDeptByStep(@Param("did") int did);-->
<select id="getDeptByStep" resultMap="deptEmpStep">
select * from t_dept where did = #{did}
</select>
  • 2、根据部门id查询部门里的所有员工
/**
* 根据部门id查询员工信息
* @param did
* @return
*/
List<Emp> getEmpListByDid(@Param("did") int did);
<!--List<Emp> getEmpListByDid(@Param("did") int did);-->
<select id="getEmpListByDid" resultType="Emp">
select * from t_emp where did = #{did}
</select>
  • 分步查询的优点:可以实现延迟加载
  • 但是必须在核心配置文件中设置全局配置信息:
  • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
  • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属 性会按需加载
  • 此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和 collection中的fetchType属性设置当前的分步查询是否使用延迟加载, fetchType="lazy(延迟加 载)|eager(立即加载)"
相关文章
|
XML Java 数据库连接
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述2
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述2
57 0
java202304java学习笔记第六十六天-ssm-mybatis-接口代理方法实现
java202304java学习笔记第六十六天-ssm-mybatis-接口代理方法实现
43 0
|
7月前
|
SQL Java 关系型数据库
MyBatisPlus学习笔记(SpringBoot版)
MyBatisPlus学习笔记(SpringBoot版)
514 0
|
SQL Java 关系型数据库
java202304java学习笔记第六十六天-ssm-mybatis的dao层实现1
java202304java学习笔记第六十六天-ssm-mybatis的dao层实现1
38 0
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-foreach之2
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-foreach之2
65 0
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-if之1
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-if之1
39 0
|
XML Java 数据库连接
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述1
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述1
65 0