• Mybatis开发要点:resultType和resultMap的区别?


    Mybatis返回Xml返回值有resultType和resultMap,我们一般都该如何选择呢?

    一、resultType

    1.1 resultType介绍

    当使用resultType做SQL语句返回结果类型处理时,对于SQL语句查询出的字段在相应的pojo中必须有和它相同的字段对应,而resultType中的内容就是pojo在本项目中的位置。

    1.2 映射规则

    • 基本类型 :resultType=基本类型
    • List类型: resultType=List中元素的类型
    • Map类型 单条记录:resultType =map 多条记录:resultType =Map中value的类型

    1.3 自动映射注意事项

    • 前提:SQL列名和JavaBean的属性是一致的;
    • 使用resultType,如用简写需要配置typeAliases (别名);
    • 如果列名和JavaBean不一致,但列名符合单词下划线分割,Java是驼峰命名法,则mapUnderscoreToCamelCase可设置为true;

    1.4 代码演示

    (1)t_user_test.sql准备

    1. CREATE TABLE `t_user_test` (
    2. `id` int(20) NOT NULL AUTO_INCREMENT,
    3. `user_name` varchar(60) DEFAULT NULL COMMENT '用户名称',
    4. `real_name` varchar(60) DEFAULT NULL COMMENT '真实名称',
    5. `sex` tinyint(3) DEFAULT NULL COMMENT '姓名',
    6. `mobile` varchar(20) DEFAULT NULL COMMENT '电话',
    7. `email` varchar(60) DEFAULT NULL COMMENT '邮箱',
    8. `note` varchar(200) DEFAULT NULL COMMENT '备注',
    9. PRIMARY KEY (`id`)
    10. ) ENGINE=InnoDB AUTO_INCREMENT=142 DEFAULT CHARSET=utf8;

    (2)实体类

    1. package com.enjoylearning.mybatis.entity;
    2. import java.io.Serializable;
    3. import java.util.List;
    4. import org.apache.ibatis.annotations.Param;
    5. import com.mysql.jdbc.Blob;
    6. public class TUser implements Serializable{
    7. private Integer id;
    8. private String userName;
    9. private String realName;
    10. private Byte sex;
    11. private String mobile;
    12. private String email;
    13. private String note;
    14. private TPosition position;
    15. private List<TJobHistory> jobs ;
    16. private List<HealthReport> healthReports;
    17. private List<TRole> roles;
    18. @Override
    19. public String toString() {
    20. String positionId= (position == null ? "" : String.valueOf(position.getId()));
    21. return "TUser [id=" + id + ", userName=" + userName + ", realName="
    22. + realName + ", sex=" + sex + ", mobile=" + mobile + ", email="
    23. + email + ", note=" + note + ", positionId=" + positionId + "]";
    24. }
    25. public Integer getId() {
    26. return id;
    27. }
    28. public void setId(Integer id) {
    29. this.id = id;
    30. }
    31. public String getUserName() {
    32. return userName;
    33. }
    34. public void setUserName(String userName) {
    35. this.userName = userName;
    36. }
    37. public String getRealName() {
    38. return realName;
    39. }
    40. public void setRealName(String realName) {
    41. this.realName = realName;
    42. }
    43. public Byte getSex() {
    44. return sex;
    45. }
    46. public void setSex(Byte sex) {
    47. this.sex = sex;
    48. }
    49. public String getMobile() {
    50. return mobile;
    51. }
    52. public void setMobile(String mobile) {
    53. this.mobile = mobile;
    54. }
    55. public String getEmail() {
    56. return email;
    57. }
    58. public void setEmail(String email) {
    59. this.email = email;
    60. }
    61. public String getNote() {
    62. return note;
    63. }
    64. public void setNote(String note) {
    65. this.note = note;
    66. }
    67. public TPosition getPosition() {
    68. return position;
    69. }
    70. public void setPosition(TPosition position) {
    71. this.position = position;
    72. }
    73. public List<TJobHistory> getJobs() {
    74. return jobs;
    75. }
    76. public void setJobs(List<TJobHistory> jobs) {
    77. this.jobs = jobs;
    78. }
    79. public List<HealthReport> getHealthReports() {
    80. return healthReports;
    81. }
    82. public void setHealthReports(List<HealthReport> healthReports) {
    83. this.healthReports = healthReports;
    84. }
    85. public List<TRole> getRoles() {
    86. return roles;
    87. }
    88. public void setRoles(List<TRole> roles) {
    89. this.roles = roles;
    90. }
    91. }

    (3)Mapper接口类

    1. public interface TUserTestMapper {
    2. TUser selectByPrimaryKey(Integer id);
    3. List<TUser> selectAll();
    4. }

    (4)Mapper xml

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    3. <mapper namespace="com.mybatis.mapper.TUserTestMapper">
    4. <select id="selectByPrimaryKey" resultType="TUser">
    5. select
    6. id, user_name, real_name, sex, mobile, email, note
    7. from t_user_test
    8. where id = #{id,jdbcType=INTEGER}
    9. </select>
    10. <select id="selectAll" resultType="TUser">
    11. select
    12. id, user_name, real_name, sex, mobile, email, note
    13. from t_user_test
    14. </select>
    15. </mapper>

    (5)配置文件

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    3. <configuration>
    4. <properties resource="db.properties"/>
    5. <settings>
    6. <!-- 设置自动驼峰转换 -->
    7. <setting name="mapUnderscoreToCamelCase" value="true" />
    8. <!-- 开启懒加载 -->
    9. <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。默认:true -->
    10. <setting name="aggressiveLazyLoading" value="false" />
    11. </settings>
    12. <!-- 别名定义 -->
    13. <typeAliases>
    14. <package name="com.enjoylearning.mybatis.entity" />
    15. </typeAliases>
    16. <plugins>
    17. <plugin interceptor="com.enjoylearning.mybatis.Interceptors.ThresholdInterceptor">
    18. <property name="threshold" value="10"/>
    19. </plugin>
    20. <plugin interceptor="com.github.pagehelper.PageInterceptor">
    21. <property name="pageSizeZero" value="true" />
    22. </plugin>
    23. </plugins>
    24. <!--配置environment环境 -->
    25. <environments default="development">
    26. <!-- 环境配置1,每个SqlSessionFactory对应一个环境 -->
    27. <environment id="development">
    28. <transactionManager type="JDBC" />
    29. <dataSource type="POOLED">
    30. <property name="driver" value="com.mysql.jdbc.Driver" />
    31. <property name="url" value="jdbc:mysql://ip:port/test?useUnicode=true" />
    32. <property name="username" value="root" />
    33. <property name="password" value="123456" />
    34. </dataSource>
    35. </environment>
    36. </environments>
    37. <!-- 映射文件,mapper的配置文件 -->
    38. <mappers>
    39. <!--直接映射到相应的mapper文件 -->
    40. <mapper resource="sqlmapper/TUserTestMapper.xml" />
    41. </mappers>
    42. </configuration>

    (6)启动测试类

    1. public class MybatisDemo2 {
    2. private SqlSessionFactory sqlSessionFactory;
    3. @Before
    4. public void init() throws IOException {
    5. //--------------------第一阶段---------------------------
    6. // 1.读取mybatis配置文件创SqlSessionFactory
    7. String resource = "mybatis-config.xml";
    8. InputStream inputStream = Resources.getResourceAsStream(resource);
    9. // 1.读取mybatis配置文件创SqlSessionFactory
    10. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    11. inputStream.close();
    12. }
    13. @Test
    14. //知识点:resultType
    15. public void testAutoMapping() throws IOException {
    16. // 2.获取sqlSession
    17. SqlSession sqlSession = sqlSessionFactory.openSession();
    18. // 3.获取对应mapper
    19. TUserTestMapper mapper = sqlSession.getMapper(TUserTestMapper.class);
    20. // 4.执行查询语句并返回多条数据
    21. List<TUser> users = mapper.selectAll();
    22. for (TUser tUser : users) {
    23. System.out.println(tUser);
    24. }
    25. }
    26. }

    (7)执行结果

    1. sql语句:“com.mysql.jdbc.JDBC4PreparedStatement@654f0d9c: select
    2. id, user_name, real_name, sex, mobile, email, note
    3. from t_user_test”执行时间为:35毫秒,已经超过阈值!
    4. TUser [id=1, userName=zhangsan, realName=张三, sex=1, mobile=186995587411, email=zhangsan@qq.com, note=zhangsan的备注, positionId=]
    5. TUser [id=2, userName=lisi, realName=李四, sex=1, mobile=18677885200, email=lisi@qq.com, note=lisi的备注, positionId=]
    6. TUser [id=3, userName=wangwu, realName=王五, sex=2, mobile=18695988747, email=xxoo@163.com, note=wangwu's note, positionId=]

    resultType当返基本类型的时候建议选择,当返回POJO类的时候由于需要完全和数据库字段进行对应,存在不灵活、问题排查难等问题。

    二、resultMap

    2.1 resultMap 介绍

    resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,在对复杂语句进行联合映射的时候,它很可能可以代替数千行的同等功能的代码。ResultMap 的设计思想是,简单的语句不需要明确的结果映射,而复杂一点的语句只需要描述它们的关系就行了。

    2.2 resultMap属性

    2.3 使用场景

    • 字段有自定义的转化规则
    • 复杂的多表查询

    2.4 resultMap子元素属性

    • id –一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能,一对多的查询中用于结果集合并;
    • result – 注入到字段或 JavaBean 属性的普通结果
    • association – 一个复杂类型的关联;许多结果将包装成这种类型。关联可以指定为一个 resultMap 元素,或者引用一个
    • collection – 一个复杂类型的集合

    2.5 代码演示

    实体类,配置文件同上

    (1)mapper接口

    1. public interface TUserMapper {
    2. List<TUser> selectTestResultMap();
    3. }

    (2)Mapper.xml

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    3. <mapper namespace="com.mybatis.mapper.TUserMapper">
    4. <resultMap id="UserResultMap" type="TUser" autoMapping="true">
    5. <id column="id" property="id" />
    6. <result column="userName" property="userName"/>
    7. <result column="realName" property="realName" />
    8. <result column="sex" property="sex" />
    9. <result column="mobile" property="mobile" />
    10. <result column="email" property="email" />
    11. <result column="note" property="note" />
    12. <association property="position" javaType="TPosition" columnPrefix="post_">
    13. <id column="id" property="id"/>
    14. <result column="name" property="postName"/>
    15. <result column="note" property="note"/>
    16. </association>
    17. </resultMap>
    18. <select id="selectTestResultMap" resultMap="UserResultMap" >
    19. select
    20. a.id,
    21. userName,
    22. realName,
    23. sex,
    24. mobile,
    25. email,
    26. a.note,
    27. b.id post_id,
    28. b.post_name,
    29. b.note post_note
    30. from t_user a,
    31. t_position b
    32. where a.position_id = b.id
    33. </select>
    34. </mapper>

    (3)启动测试

    1. public class MybatisDemo2 {
    2. private SqlSessionFactory sqlSessionFactory;
    3. @Before
    4. public void init() throws IOException {
    5. //--------------------第一阶段---------------------------
    6. // 1.读取mybatis配置文件创SqlSessionFactory
    7. String resource = "mybatis-config.xml";
    8. InputStream inputStream = Resources.getResourceAsStream(resource);
    9. // 1.读取mybatis配置文件创SqlSessionFactory
    10. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    11. inputStream.close();
    12. }
    13. @Test
    14. public void testResultMap() throws IOException {
    15. //--------------------第二阶段---------------------------
    16. // 2.获取sqlSession
    17. SqlSession sqlSession = sqlSessionFactory.openSession();
    18. // 3.获取对应mapper
    19. TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);
    20. //--------------------第三阶段---------------------------
    21. // 4.执行查询语句并返回单条数据
    22. List<TUser> users = mapper.selectTestResultMap();
    23. for (TUser tUser : users) {
    24. System.out.println(tUser.getUserName());
    25. System.out.println(tUser.getPosition().getPostName());
    26. }
    27. }
    28. }

    (4)执行结果

    1. sql语句:“com.mysql.jdbc.JDBC4PreparedStatement@19bb07ed: select
    2. a.id,
    3. userName,
    4. realName,
    5. sex,
    6. mobile,
    7. email,
    8. a.note,
    9. b.id post_id,
    10. b.post_name,
    11. b.note post_note
    12. from t_user a,
    13. t_position b
    14. where a.position_id = b.id”执行时间为:52毫秒,已经超过阈值!
    15. zhangsan
    16. 总经理
    17. lisi
    18. 零时工
    19. wangwu
    20. 总经理

    三、结论

    当返回对象为基础类型时建议走resultType,当返回对象为POJO时,强制走resultMap。同时可以参考阿里巴巴JAVA开发手册中的5.4.3节,返回要解耦,不讷讷更直接使用resultClass。

    作者:Dark_King_

    原文链接:
    https://blog.csdn.net/b379685397/article/details/114265301

  • 相关阅读:
    macOS 查验国家税务总局发票
    Maven在IDEA中的使用,<buid>、<properties>标签
    【PyTorch】2-主要组成模块(数据读入、模型构建、损失函数、评价指标、训练和测试、优化器)
    计算机网络的性能指标
    【无标题】
    [excel与dict] python 读取excel内容并放入字典、将字典内容写入 excel文件
    【c++】——类和对象(中)——实现完整的日期类(优化)万字详细解疑答惑
    从实例来看DAO:权力分散的伟大尝试
    Socket编程基础(1)
    市场逆风中,海尔智家如何续写增长故事
  • 原文地址:https://blog.csdn.net/m0_67645544/article/details/124804183