MyBatis(三)特殊SQL执行和自定义映射resultMap

特殊SQL执行

模糊查询

mapper接口

/**
* 模糊匹配
*/
List<User> getUserByLike(@Param("username") String username);

xml配置

<!--    List<User> getUserByLike();-->
<select id="getUserByLike" resultType="user">
    <!--select * from t_user where username like '%${username}%'-->
    <!--select * from t_user where username like concat('%',#{username},'%')-->
    select * from t_user where username like "%"#{username}"%"
</select>

单元测试

@Test
public void testSQLMapperTest(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession("mybatis-config.xml");
    SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
    List<User> userList = mapper.getUserByLike("a");
    userList.forEach(user -> {
         System.out.println(user);
    });
}

批量删除

mapper接口

/**
* 批量删除
*/
int deleteMore(@Param("ids") String ids);

xml配置

<!--    int deleteMore(@Param("id") String ids);-->
<delete id="deleteMore">
    delete from t_user where id in (${ids});
</delete>

单元测试

@Test
public void testDeleteMore(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession("mybatis-config.xml");
    SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
    int result = mapper.deleteMore("1,2,3");
    System.out.println(result);
}

动态设置表名

mapper接口

/**
* 动态设置表名
*/
List<User> getAllUser(@Param("tableName") String tableName);

xml配置

<!--    List<User> getAllUser(@Param("tableName") String tableName);-->
<select id="getAllUser" resultType="user">
    select * from ${tableName};
</select>

单元测试

@Test
public void testGetAllUser(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession("mybatis-config.xml");
    SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
    List<User> userList = mapper.getAllUser("t_user");
    userList.forEach(System.out::println);
}

添加功能获取自增的主键

mapper接口

/**
* 插入获取自增主键
*/
int insertGetPrimaryKey(User user);

xml配置

<!--    int insertGetPrimaryKey(User user);-->
<insert id="insertGetPrimaryKey" useGeneratedKeys="true" keyProperty="id">
    insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>

单元测试

@Test
public void testInsertGePrimaryKey(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession("mybatis-config.xml");
    SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
    User user = new User(null, "云缨", "yunying168", 21, "女", "yunying@wz.com");
    mapper.insertGetPrimaryKey(user);
    System.out.println(user);
}

自定义映射resultMap

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

若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射。

其中resultMap属性

  • id:标识自定义映射的唯一标识。
  • type:查询的数据要映射的实体类类型

子标签

  • id:设置主键的映射关系
  • result:设置普通字段的映射关系
  • association:设置多对一的映射关系
  • collection:设置一对多的映射关系

子标签中的属性

  • property:设置映射关系中实体类中的属性名
  • column:设置映射关系中表中的字段名
<resultMap id="EmpMap" type="emp">
    <id property="eid" column="eid"></id>
    <result property="empName" column="emp_name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>
    <result property="email" column="email"></result>
</resultMap>

<select id="getAllEmp" resultMap="EmpMap">
    select * from t_emp
</select>

若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(即两个单词之间用_连接),实体类中的属性符合Java的规则(驼峰规则)。

此时可以通过以下两种方式来处理字段名和实体类中属性的映射关系:

  1. 通过为字段起别名,来保证和实体类中的属性名保持一致。
<select id="getAllEmpOne" resultType="emp">
    select eid,emp_name empName,age,sex,email from t_emp;
</select>
  1. 在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,就可以在查询表中数据时,自动将_类型的字段名转换为驼峰。

mybatis-config.xml核心配置文件

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

xml配置

<select id="getAllEmpTwo" resultMap="EmpMap">
    select * from t_emp
</select>

多对一映射处理

级联方式处理映射关系

mapper接口

/**
* 通过eid获取员工和部门信息
* @param eid
* @return
*/
Emp getEmpAndDeptByEid(@Param("eid") Integer eid);

xml配置文件

<resultMap id="empDeptMap" type="emp">
    <id property="eid" column="eid"></id>
    <result property="empName" column="emp_name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>
    <result property="dept.did" column="did"></result>
    <result property="dept.deptName" column="dept_name"></result>
</resultMap>
<select id="getEmpAndDeptByEid" resultMap="empDeptMap">
    select * from t_emp left join t_dept on t_emp.did = t_dept.did where eid = #{eid};
</select>

单元测试

@Test
public void testEmpAndDeptByEid(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession("mybatis-config.xml");
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp emp = mapper.getEmpAndDeptByEid(4);
    System.out.println(emp);
}

使用association处理映射关系

association标签用于处理多对一的映射关系。

其属性值:

  • property:需要处理多对映射关系的属性名
  • javaType:该属性的类型
    <resultMap id="empDeptMapTwo" type="emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
        <result property="dept.did" column="did"></result>
        <result property="dept.deptName" column="dept_name"></result>
        <association property="dept" javaType="Dept">
            <id property="did" column="did"></id>
            <result property="deptName" column="dept_name"></result>
        </association>
    </resultMap>
    <select id="getEmpAndDeptByEid" resultMap="empDeptMapTwo">
        select * from t_emp left join t_dept on t_emp.did = t_dept.did where eid = #{eid};
    </select>

分步查询

association的属性:

  • select:设置分步查询,查询某个属性的值的sql的标识(namespace.sqliD或mapper接口的全类名.方法名)
  • column:将sql以及查询结果中某个字段设置为分步查询的条件

  1. 查询员工信息

mapper接口

    /**
     * 通过分步查询查询员工以及员工的部门信息
     */
    Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);

xml配置

<resultMap id="empAndDeptByStepResultMap" type="emp">
    <id property="eid" column="eid"></id>
    <result property="empName" column="emp_name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>
    <result property="email" column="email"></result>
    <association property="dept" select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo" column="did"></association>
</resultMap>

<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
    select * from t_emp where eid = #{eid}
</select>

2.根据员工所对应的部门id查询部门信息

mapper接口

    /**
     * 通过分步查询查询员工以及员工的部门信息
     */
	Dept getEmpAndDeptByStepTwo(@Param("eid") Integer did);

xml配置

<!--    Dept getEmpAndDeptByStepTwo(@Param("eid") Integer did);-->
<select id="getEmpAndDeptByStepTwo" resultType="dept">
    select * from t_dept where did = #{did}
</select>

单元测试

@Test
public void testEmpAndDeptByStepOne(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession("mybatis-config.xml");
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp emp = mapper.getEmpAndDeptByStepOne(3);
    System.out.println(emp);
}

分步查询的优点是可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息

mybatis-config,xml

<settings>
    <!--   将_自动映射为驼峰,emp_name:empName     -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <!--开启延迟加载-->
    <setting name="lazyLoadingEnabled" value="true"/>    
</settings>

lazyLoadingEnabled:延迟加载的全局开关,当开启时,所有关联对象都会延迟加载。默认为false。

aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性都会按需加载,获取的数据是什么,就只会执行相应的sql。MyBatis 3.4.1版本以上默认为false,反之为true。

MyBatis 3.5.9版本不需要设置延迟加载的全局开关,通过association和collection标签中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”。

一对多映射处理

collection

mapper接口

/**
* 获取部门以及部门中所有的员工信息
*/
Dept getDeptAndEmp(@Param("did") Integer did);

xml配置

需要注意的是,collection集合中用到了ofType属性。

ofType:表示该属性所对应的集合中存储数据的类型。

<resultMap id="deptAndEmpResultMap" type="dept">
    <id property="did" column="did"></id>
    <result property="deptName" column="dept_name"></result>
    <collection property="emps" ofType="emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
    </collection>
</resultMap>

<select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
    select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}
</select>

单元测试

@Test
public void testDeptAndEmp(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession("mybatis-config.xml");
    DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
    Dept dept = mapper.getDeptAndEmp(3);
    System.out.println(dept);
}

分步查询

  1. 查询部门信息

mapper接口

/**
* 通过分步查询查询部门以及部门中所有的员工信息
* 分步查询第一步:查询部门信息
*/
Dept getDeptAndEmpStepOne(@Param("did") Integer did);

xml配置

<!--    Dept getDeptAndEmpStepOne(@Param("did") Integer did);-->
<resultMap id="deptAndEmpStepResultMap" type="dept">
    <id property="did" column="did"></id>
    <result property="deptName" column="dept_name"></result>
    <collection property="emps" select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo" column="did"></collection>
</resultMap>

<select id="getDeptAndEmpStepOne" resultMap="deptAndEmpStepResultMap">
    select * from t_dept where did = #{did}
</select>

2.根据部门id查询部门中的所有员工

mapper接口

/**
* 通过分步查询查询部门以及部门中所有的员工信息
* 分步查询第二步:根据did查询部门信息
*/
List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);

xml配置

<!--    List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);-->
<select id="getDeptAndEmpByStepTwo" resultType="emp">
    select * from t_emp where did = #{did}
</select>

单元测试

@Test
public void testDeptAndEmpByStep(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession("mybatis-config.xml");
    DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
    Dept dept = mapper.getDeptAndEmpStepOne(3);
    System.out.println(dept);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis自连接级联动和resultMap映射是一种常见的数据查询和映射方式。下面我来解释一下。 首先,自连接级联动是指在数据库中,存在一个表,其中的某些字段关联到该表的自身字段。通常情况下,我们需要使用连续的JOIN语句来实现多级联动查询。在MyBatis中,可以使用XML配置文件或注解来定义SQL语句,然后使用resultMap进行结果的映射。 在XML配置文件中,可以使用<resultMap>元素来定义映射关系。对于自连接的情况,可以使用嵌套的<association>或<collection>元素来表示关联关系。例如: ```xml <resultMap id="userMap" type="User"> <id property="id" column="id" /> <result property="name" column="name" /> <association property="manager" javaType="User"> <id property="id" column="manager_id" /> <result property="name" column="manager_name" /> <collection property="subordinates" ofType="User"> <id property="id" column="subordinate_id" /> <result property="name" column="subordinate_name" /> ... </collection> </association> </resultMap> ``` 上述代码中,定义了一个名为userMapresultMap映射了User对象及其关联的manager和subordinates字段。 在实际查询时,可以使用嵌套的SELECT语句或连续的JOIN语句来实现自连接的多级联动查询。例如: ```xml <select id="getUserWithManagerAndSubordinates" resultMap="userMap"> SELECT u.id, u.name, m.id AS manager_id, m.name AS manager_name, s.id AS subordinate_id, s.name AS subordinate_name FROM user u LEFT JOIN user m ON u.manager_id = m.id LEFT JOIN user s ON u.id = s.manager_id WHERE u.id = #{id} </select> ``` 上述代码中,使用了连续的LEFT JOIN语句来查询用户及其关联的上级经理和下级员工信息。 通过以上的配置和查询,就可以实现MyBatis中的自连接级联动和resultMap映射。希望能对你有所帮助!如果还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值