Java MyBatis传出参数resultType和resultMap解读

2022-12-21 11:38:46

目录MyBatis输出参数resultType和resultMap一、resultType1、简单类型2、Map类型3、对象类型二、resultMap三、模糊like总结MyBatis输出参数...

目录
MyBATis输出参数 resultType 和 resultMap
一、resultType
1、简单类型
2、Map类型
3、对象类型
二、resultMap
三、模糊 like 
总结

MyBatis输出参数 resultType 和 resultMap

我们需要在 mybatis-config.XML 文件中加如下配置

<!--定义别名-->
  <typeAliases>
    <!--
      第一种方式:
      指定一个类型一个自定义别名
      type:自定义类型的全限定名称
      alias:别名
    -->
    <typeAlias type="com.mycompany.domain.User" alias="user" />
    <typeAlias type="com.mycompany.vo.ViewUser" alias="vUser" />

    <!--
     第二种方式
     <package> name是包名, 这个包中的所有类,类名就是别名(类名不区分大小写)
    -->
    <package name="com.mycompany.domain" />
    <package name="com.mycompany.vo" />

  </typeAliases>

文件完全内容如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">

<!--
  mybatis的主配置文件:主要定义了数据库的配置信息,SQL映射文件的位置
  1、约束文件
    <!DOCTYPE configuration
      PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-config.dtd">
    mybatis-3-config.dtd:约束文件名称
  2、configuration:根标签
-->
<configuration>

  <!-- settings:mybatis全局行为 -->
  <settings>
    <!-- 设置mybatis输出日志 -->
    <setting name="logImpl" value="STDOUT_LOGGING" />
  </settings>

  <!--定义别名-->
  <typeAliases>
    <!--
      第一种方式:
      指定一个类型一个自定义别名
      type:自定义类型的全限定名称
      alias:别名
    -->
    <typeAlias type="com.mycompany.domain.User" alias="user" />
    <typeAlias type="com.mycompany.vo.ViewUser" alias="vUser" />

    <!--
     第二种方式
     <package> name是包名, 这个包中的所有类,类名就是别名(类名不区分大小写)
    -->
    <package name="com.mycompany.domain" />
    <package name="com.mycompany.vo" />

  </typeAliases>

  <!--
    环境配置:数据库的连接信息
      default:必须和某个environment的id值一样
      告诉mybatis使用哪个数据库的连接信息(访问哪个数据库)
  -->
  <environments default="development">

    <!--
      environment:一个数据库的配置,环境
      id:一个唯一值(可自定义,表示环境的名称)
    -->
    <environment id="development">
      <!--
        transactionManaer:mybatis的事务类型
          type:JDBC(表示使用JDBC中的Connection对象的commit,rollback做事务处理)
      -->
      <transactionManager type="JDBC"/>
      <!--
        dataSource:表示数据源,连接数据库的
          type:表述数据源的类型,POOLED表示使用连接池
      -->
      <dataSource type="POOLED">
        <!--
         driver, user, username, password 是固定的,不能自定义。
        -->
        <!-- 数据库驱动类名 -->
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <!-- 连接数据库的URL字符串 -->
        <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
        <!-- 访问数据库的用户名 -->
        <property name="username" value="root"/>
        <!-- 访问数据库的密码 -->
        <property name="password" value="123456"/>
      </dataSource>
    </environment>

    <!--表示线上的数据库,是项目真实使用的库-->
    <environment id="online">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/onlinedb"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
      </dataSource>
    </environment>

  </environments>

  <!-- sql mapper(SQL映射文件)的位置 -->
  <mappers>
    <!--
      一个mapper标签指定一个文件的位置
        从类路径开始的路径信息(target/classes)类路径
    -->
    <mapper resource="com/mycompany/dao/UserDao.xml"/>
  </mappers>
</configuration>

一、resultType

执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名

1、简单类型

UserDao接口文件

public User selectUserByUserId(@Param("userId") Integer id);

List<User> selectMultiParam(@Param("username") String userName,
                @Param("userage") Integer age);

UserDao.xml文件

<!--
  resultType:
      表示结果类型,SQL语句执行后得到ResultSet结果集,遍历这个结果集得到的Java对象类型
      值写Java对象的全限定名称
  1、resultType="vUser"
    mybatis-config.xml文件中第一种方式
    指定一个类型一个自定义别名
      type:自定义类型的全限定名称
      alias:别名
  2、resultType="ViewUser"
    mybatis-config.xml文件中第二种方式:js
     <package> name是包名, 这个包中的所有类,类名就是别名(类名不区分大小写)
  注:
    resultType="User" 如果一个项目中有多个User类文件,会报错
    Could not resolve type alias 'User'. Cause: java.lang.ClassNotFoundException: Cannot find class: User
  -->
  <select id="selectUserByUserId" resultType="User">
    select user_id,user_name,email,age
    from user
    where user_id = #{userId}
  </select>

  <!--多个参数,使用@Param命名-->
  <select id="selectMultiParam" resultType="com.mycompany.domain.User" >
    select user_id,user_name,email,age
    from user
    where user_name = #{username} or age = #{userage}
  </select>

TestMyBatis测试类

@Test
  public void testSelectUserByUserId(){
    try {
      SqlSession sqlSession = MyBatisUtil.getSqlSession();
      UserDao userDao = sqlSession.getMapper(UserDao.class);

      User user = userDao.selectUserByUserId(1);
      System.out.println("user="+user);
      sqlSession.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Test
  public void testSelectMultiParam(){
    try {
      SqlSession sqlSession = MyBatisUtil.getSqlSession();
      UserDao userDao = sqlSession.getMapper(UserDao.class);

      List<User> userList = userDao.selectMultiParam("zhangsan",20);
      for(User user: userList){
        System.out.println("用户="+user);
      }
      sqlSession.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

2、Map类型

UserDao接口文件

//定义方法返回Map
  Map<Object,Object> selectMapById(Integer id);
UserDao.xml文件

<select id="selectMapById" resultType="java.util.HashMap">
    select user_id,user_name,email,age
    from user
    where user_id=#{userId}
  </select>

TestMyBatis测试类

@Test
  public void testSelectMapById(){
    try {
      SqlSession sqlSession = MyBatisUtil.getSqlSession();
      UserDao userDao = sqlSession.getMapper(UserDao.class);

      Map<Object,Object> map = userDao.selectMapById(1);
      System.out.println("map=="+map);
      sqlSession.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

3、对象类型

UserDao接口文件

ViewUser selectUserReturnViewUser(@Param("userId") Integer id);

UserDao.xml文件

<!--
    1、resultType="vUser"
    mybatis-config.xml文件中第一种方式
    指定一个类型一个自定义别名
      type:自定义类型的全限定名称
      alias:别名
    2、resultType="ViewUser"
    mybatis-config.xml文件中第二种方式:
     <package> name是包名, 这个包中的所有类,类名就是别名(类名不区分大小写)
  -->
  <select id="selectUserReturnViewUser" resultType="ViewUser">
    select user_id,user_name
    from user
    where user_id = #{userId}
  </select>

TestMyBatis测试类

@Test
  public void testSelectUserReturnViewUser(){
    try {
      SqlSession sqlSession = MyBatisUtil.getSqlSession();
      UserDao userDao = sqlSession.getMapper(UserDao.class);

      ViewUser user = userDao.selectUserReturnViewUser(1);
      System.out.println("ViewUser="+user);
      sqlSession.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

注:

(1)如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身

(2)resultType 和 resultMap,不能同时使用

(3)resultType="User" 如果一个项目中有多个User类文件,会报错

Could not resolve type alias 'User'. Cause: java.lang.

ClassNotFoundException: Cannot find class: User

此时最好指定全限定名称

二、resultMap

resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系;更灵活的把列值赋值给指定属性

常用在列名和python java 对象属性名不一样的情况

使用方式:

(1)先定义 resultMap,指定列名和属性的对应关系

(2)在<select>中把 resultType 替换为 resultMap

列名和Java对象属性名不一样时,有两种处理方式

(1)使用resultMap映射

(2)resultType的默认原则是 同名的列值赋值给同名的属性, 使用列别名(java对象的属性名)

如下Java类属性

public class User {
  private int userId;
  private String userName;
  private String email;
  private int age;
}


public class MyUser {
  private int myUserId;
  private String myUserName;
  private String myUserEmail;
  private int myUserAge;
}

UserDao接口文件

/*
  使用resultMap定义映射关系
  */
  List<User> selectAllUsers();

  List<MyUser> selectMyUser();

  List<MyUser> selectDiffColProperty();

UserDao.xml文件

<!--使用resultMap
    (1)先定义resultMap
    (2)在select标签,使用resultMap来引用定义
    id:自定义名称,表示定义的这个resultMap
    type:java类型的全限定名称
  -->
  <resultMap id="userMap" type="com.mycompany.domain.User">
    <!--列名和java属性的关系
      注解列,使用id标签
      column :列名(数据库表字段列名)
      property:java类型的属性名
    -->
    <!-- 主键列使用 id 标签-->
    <id column="user_id" property="userId" />
    <!-- 非主键列使用 result 标签-->
    <result column="user_name" property="userName" />
    <result column="email" property="email" />
    <result column="age" property="age" />
  </resultMap>

  <select id="selectAllUsers" resultMap="userMap">
    select user_id,user_name,email,age
    from user
    where user_id=#{userId}
  </select>

  <resultMap id="myUserMap" type="com.mycompany.domain.MyUser">
    <id column="user_id" property="myUserId" />
    <result column="user_name" property="myUserName" />
    <result column="email" property="myUserEmail" />
    <result column="age" property="myUserAge" />
  </resultMap>

  <!--列名和属性名不一样:第一种方式
    使用resultMap映射
  -->
  <select id="selectMyUser" resultMap="myUserMap">
    select user_id,user_name,email,age
    from user
  </select>

  <!--列名和属性名不一样:第二种方式
   resultType的默认原则是 同名的列值赋值给同名的属性, 使用列别名(java对象的属性名)
  -->
  <select id="selectDiffColProperty" resultType="com.mycompany.domain.MyUser">
    select user_id as myUserId ,user_name as myUserName, email as myUserEmail , age myUserAge
    from user
  </select>

TestMyBatis测试类

@Test
  public void testSelectAllUsers(){
    try {
      SqlSession sqlSession = MyBatisUtil.getSqlSession();
      UserDao userDao = sqlSession.getMapper(UserDao.class);

      List<User> userList = userDao.selectAllUsers();
      for(User user: userList){
        System.out.println("用户="+user);
      }
      sqlSession.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Test
  public void testSelectMyUser(){
    try {
      SqlSession sqlSession = MyBatisUtil.getSqlSession();
      UserDao userDao = sqlSession.getMapper(UserDao.class);

      List<MyUser> userList = userDao.selectMyUser();
      for(MyUser user: userList){
        System.out.println("MyUser用户="+user);
      }
      sqlSession.close();
    } catch (IOException e) {
      e.printStackTrace();
 GlKgZwLAOS   }
  }

  @Test
  public void testSelectDiffColProperty(){
    try {
      SqlSession sqlSession = MyBatisUtil.getSqlSession();
      UserDao userDao = sqlSession.getMapper(UserDao.class);

      List<MyUser> userList = userDao.selectDiffColProperty();
      for(MyUser user: userList){
        System.out.println("MyUser用户="+user);
      }
      sqlSession.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

三、模糊 like 

模糊查询的实现有两种方式, 一是 java 代码中给查询数据加上“%” ; 二是在 mapper 文件 sql 语句的条件位置加上“%”

UserDao接口文件

/*第一种模糊查询, 在java代码指定 like的内容*/
  List<User> selectLikeOne(String name);

  /*name就是李值, 在mapper中拼接 like "%" li "%" */
  List<User> selectLikeTwo(String name);

UserDao.xml文件

<!--第一种 like ,java代码指定 like的内容-->
  <select id="selectLikeOne" resultType="com.mycompany.domain.User">
    select user_id, user_name, email, age
    from user
    where user_name like #{user_name}
  </select>

  <!--第二种方式:在mapper文件中拼接 like的内容-->
  <select id="selectLikeTwo" resultType="com.mycompany.domain.User">
    select user_id, user_name, email, age
    from user
    where user_name like "%" #{user_name} "%"
  </select>

TestMyBatis测试类

@Test
  public void testSelectLikeOne(){
    try {
      SqlSession sqlSession = MyBatisUtil.getSqlSession();
      UserDao userDao = sqlSession.getMapper(UserDao.class);

      //like的内容
      String name = "%li%";
      List<User> userList = userDao.selectLikeOne(name);
      for(User user: userList){
        System.out.println("User用户="+user);
      }
      sqlSession.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Test
  public void testSelectLikeTwo(){
    try {
      SqlSession sqlSession = MyBatisUtil.getSqlSession();
      UserDao userDao = sqlSession.getMapper(UserDao.class);

      //like的内容
      String name = "li";
      List<User> userList = userDao.selectLikeTwo(name);
      for(User user: userList){
        System.out.println("User用户="+user);
      }
      sqlSession.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。