七、MyBatis自定义映射resultMap

@[toc]

七、自定义映射resultMap

注意:下面两行表看看就行,实际案例只用了很少很少的属性进行练习。

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

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

ini 复制代码
/**
     * 解决字段名和属性名不一致的情况:
     * a>为字段起别名,保持和属性名的一致
     * b>设置全局配置,将_自动映射为驼峰
     * <setting name="mapUnderscoreToCamelCase" value="true"/>
     * c>通过resultMap设置自定义的映射关系
     * <resultMap id="userResultMap" type="User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <result property="mobile" column="mobile"></result>
        <result property="gender" column="gender"></result>
        <result property="lastLoginIp" column="last_login_ip"></result>
    </resultMap>
     */
    @Test
    public void testGetUserById2(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        System.out.println(mapper.getUserById2(4));
    }
less 复制代码
User getUserById2(@Param("id") Integer id);

方式1:只设置resultType="User",通过as设置别名

xml 复制代码
<!--方式1:只设置resultType="User",通过as设置别名-->
<select id="getUserById2" resultType="User">
        select id,username,password,gender,mobile,last_login_ip as lastLoginIp from litemall.litemall_user where id = #{id}
</select>

方式2:设置全局配置,将_自动映射为驼峰
mybatis-config.xml

xml 复制代码
<settings>
        <!--将表中字段的下划线自动转换为驼峰-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
xml 复制代码
<!--方式2:设置全局配置,将_自动映射为驼峰<setting name="mapUnderscoreToCamelCase" value="true"/>-->
<select id="getUserById2" resultType="User">
        select id,username,password,gender,mobile,last_login_ip from litemall.litemall_user where id = #{id}
</select>

方式3:只设置resultMap="userResultMap

xml 复制代码
<!--
        resultMap:设置自定义映射关系
        id:唯一标识,不能重复
        type:设置映射关系中的实体类类型
        子标签:
        id:设置主键的映射关系
        result:设置普通字段的映射关系
        属性:
        property:设置映射关系中的属性名,必须是type属性所设置的实体类类型中的属性名
        column:设置映射关系中的字段名,必须是sql语句查询出的字段名
-->
<resultMap id="userResultMap" type="User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <result property="mobile" column="mobile"></result>
        <result property="gender" column="gender"></result>
        <result property="lastLoginIp" column="last_login_ip"></result>
</resultMap>

<!--方式3:只设置resultMap="userResultMap"-->
<select id="getUserById2" resultMap="userResultMap">
        select * from litemall.litemall_user where id = #{id}
</select>

若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)

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

  • 可以通过为字段起别名的方式,保证和实体类中的属性名保持一致

  • 可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可

以在查询表中数据时,自动将_类型的字段名转换为驼峰

例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName

7.2 多对一映射处理

User对象

less 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
    //id
    private Integer id;
    //用户名称
    private String username;
    //用户密码
    private String password;
    //用户手机号码
    private String mobile;
    //性别
    private Integer gender;
    //最近一次登录IP地址
    private String lastLoginIp;
    private Address address;
}

Address对象

less 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Address {
    //id
    private Integer id;
    //用户名称
    private String name;
    //用户ID
    private Integer userId;
}

查询员工信息以及员工所对应的部门信息

级联方式处理映射关系

ini 复制代码
/**
     * 处理多对一的映射关系:
     * a>级联属性赋值
     * b>association
     * c>分步查询
     */
    @Test
    public void getUserAndAddressById(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper selectMapper = sqlSession.getMapper(SelectMapper.class);
        User user = selectMapper.getUserAndAddressById(4);
        System.out.println(user);
    }
less 复制代码
User getUserAndAddressById(@Param("id") Integer id);
xml 复制代码
<resultMap id="userAndAddressResultMap" type="User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <result property="mobile" column="mobile"></result>
        <result property="gender" column="gender"></result>
        <result property="lastLoginIp" column="last_login_ip"></result>
        <result column="id" property="address.id"></result>
        <result column="name" property="address.name"></result>
        <result column="user_id" property="address.userId"></result>
</resultMap>
<!--方式1:级联方式处理映射关系-->
<select id="getUserAndAddressById" resultMap="userAndAddressResultMap">
        select litemall_user.*, litemall_address.* from litemall_user left join litemall_address on litemall_user.id = litemall_address.user_id where litemall_user.id = #{id}
</select>

使用association处理映射关系

注意:使用\<association>标签和property属性、javaType属性

ini 复制代码
/**
     * 处理多对一的映射关系:
     * a>级联属性赋值
     * b>association
     * c>分步查询
     */
    @Test
    public void getUserAndAddressById(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper selectMapper = sqlSession.getMapper(SelectMapper.class);
        User user = selectMapper.getUserAndAddressById(4);
        System.out.println(user);
    }
less 复制代码
User getUserAndAddressById(@Param("id") Integer id);
xml 复制代码
<resultMap id="userAndAddressResultMap2" type="User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <result property="mobile" column="mobile"></result>
        <result property="gender" column="gender"></result>
        <result property="lastLoginIp" column="last_login_ip"></result>
        <association property="address" javaType="Address">
            <id column="id" property="id"></id>
            <result column="name" property="name"></result>
            <result column="user_id" property="userId"></result>
        </association>
</resultMap>
<!--方式2:使用association处理映射关系-->
<select id="getUserAndAddressById" resultMap="userAndAddressResultMap2">
        select litemall_user.*, litemall_address.* from litemall_user left join litemall_address on litemall_user.id = litemall_address.user_id where litemall_user.id = #{id}
</select>

分步查询

  • 查用户表
ini 复制代码
/**
     * 处理多对一的映射关系:
     * a>级联属性赋值
     * b>association
     * c>分步查询
     */
    @Test
    public void getUserAndAddressById(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper selectMapper = sqlSession.getMapper(SelectMapper.class);
        User user = selectMapper.getUserById2(4);
        AddressMapper addressMapper = sqlSession.getMapper(AddressMapper.class);
        Address address = addressMapper.getAddressByUserId(user.getId());
        user.setAddress(address);
        System.out.println(user);
    }
less 复制代码
User getUserById2(@Param("id") Integer id);
sql 复制代码
<resultMap id="userResultMap" type="User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <result property="mobile" column="mobile"></result>
        <result property="gender" column="gender"></result>
        <result property="lastLoginIp" column="last_login_ip"></result>
</resultMap>
<select id="getUserById2" resultMap="userResultMap">
        select * from litemall.litemall_user where id = #{id}
</select>
  • 查地址表
less 复制代码
Address getAddressByUserId(@Param("userId") Integer userId);
csharp 复制代码
<select id="getAddressByUserId" resultType="Address">
        select * from litemall_address where user_id = #{userId}
</select>

7.3 一对多映射处理

Address对象

less 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Address {
    //id
    private Integer id;
    //用户名称
    private String name;
    //用户ID
    private Integer userId;

    private List<User> userList = new ArrayList<>();
}

collection

注意:使用\<collection>标签和property属性、ofType属性

ini 复制代码
/**
     * 处理一对多的映射关系
     * a>collection
     * b>分步查询
     */
    @Test
    public void getAddressAndUserById(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        AddressMapper addressMapper = sqlSession.getMapper(AddressMapper.class);
        //collection
        Address address = addressMapper.getAddressAndUserById(1);
        System.out.println(address);
    }
less 复制代码
Address getAddressAndUserById(@Param("id") Integer id);
xml 复制代码
<resultMap id="addresAndUsersResultMap" type="address">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="user_id" property="userId"></result>
        <!--ofType:设置collection标签所处理的集合属性中存储数据的类型-->
        <collection property="userList" ofType="User">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="password" column="password"></result>
            <result property="mobile" column="mobile"></result>
            <result property="gender" column="gender"></result>
            <result property="lastLoginIp" column="last_login_ip"></result>
        </collection>
    </resultMap>
    <select id="getAddressAndUserById" resultMap="addresAndUsersResultMap">
        select litemall_user.*, litemall_address.* from litemall_address  left JOIN litemall_user on litemall_user.id = litemall_address.user_id where litemall_address.id = #{id}
    </select>

分步查询

  • 查地址表
ini 复制代码
/**
     * 处理一对多的映射关系
     * a>collection
     * b>分步查询
     */
    @Test
    public void getAddressAndUserById(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        AddressMapper addressMapper = sqlSession.getMapper(AddressMapper.class);

        //分步查询
        Address address = addressMapper.getAddressById(1);
        SelectMapper selectMapper = sqlSession.getMapper(SelectMapper.class);
        User user = selectMapper.getUserById(address.getUserId());
        address.getUserList().add(user);
        System.out.println(address);
    }
less 复制代码
Address getAddressById(@Param("id") Integer id);
csharp 复制代码
<select id="getAddressById" resultType="Address">
        select * from litemall_address where id = #{id}
</select>
  • 查用户表
less 复制代码
User getUserById(@Param("id") Integer id);
csharp 复制代码
<select id="getUserById" resultType="User">
        select * from litemall_user where id = #{id}
</select>

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

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

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

此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType="lazy(延迟加载)|eager(立即加载)"

本人其他相关文章链接

1.一、MyBatis简介:MyBatis历史、MyBatis特性、和其它持久化层技术对比、Mybatis下载依赖包流程 2.二、搭建MyBatis采用xml方式,验证CRUD(增删改查操作) 3.三、MyBatis核心配置文件详解 4.四、MyBatis获取参数值的两种方式(重点) 5.五、MyBatis的增删改查模板(参数形式包括:String、对象、集合、数组、Map) 6.六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性 7.七、MyBatis自定义映射resultMap 8.八、(了解即可)MyBatis懒加载(或者叫延迟加载) 9.九、MyBatis动态SQL 10.十、MyBatis的缓存 11.十一、MyBatis的逆向工程 12.十二、MyBatis分页插件

重要信息

相关推荐
丝斯20114 分钟前
AI学习笔记整理(20)—— AI核心技术(深度学习4)
人工智能·笔记·学习
love530love4 分钟前
【笔记】重建 Stable Diffusion WebUI 虚拟环境实录
人工智能·windows·笔记·python·stable diffusion·aigc·虚拟环境
语落心生8 分钟前
流式数据湖Paimon探秘之旅 (二十一) 企业级最佳实践和案例分析
大数据
数据与后端架构提升之路10 分钟前
感知模块详解:从 OpenCV/YOLO 脚本到 多模态多任务 BEV 架构
人工智能·机器学习·自动驾驶
语落心生14 分钟前
流式数据湖Paimon探秘之旅 (二十) 性能测试与基准对标
大数据
咚咚王者15 分钟前
人工智能之数据分析 Matplotlib:第五章 常见函数
人工智能·数据分析·matplotlib
爱写代码的liding18 分钟前
git 常用命令
大数据·git·elasticsearch
天天找自己20 分钟前
TransNeXt 深度解析:聚合注意力机制的突破性视觉骨干网络
人工智能·pytorch·python·深度学习·神经网络
yangmf204021 分钟前
ES 服务编排利器--INFINI Cloud
大数据·elasticsearch·搜索引擎·全文检索
黄焖鸡能干四碗22 分钟前
软件试运行方案试运行报告文档下载(WORD)
大数据·运维·数据库·安全