MyBatis 教程

constructor 标签

本章节将介绍 <constructor> 标签的用法,该标签用来根据 JavaBean 中不同的构造器创建出 JavaBean 对象。<constructor> 标签需要配合 <idArg> 和 <arg> 标签一起使用,下面通过实例来介绍它的用法:

(1)假设我们定义了如下 UserBean:

public class UserBean {
   private Integer userId;
   private String name;
   private String sex;
   private Integer age;

   public UserBean(Integer userId, String name) {
      this.userId = userId;
      this.name = name;
   }
   
   // 忽略 getter 和 setter
}

(2)XML 结果映射代码如下:

<resultMap id="RESULT_MAP" type="com.hxstrive.mybatis.resultmap.demo5.UserBean">
   <!-- constructor 用来映射 UserBean(Integer userId, String name) 构造方法 -->
   <constructor>
      <idArg column="user_id" javaType="int" />
      <arg column="name" javaType="String" />
   </constructor>
   <result column="sex" jdbcType="VARCHAR" property="sex" />
   <result column="age" jdbcType="INTEGER" property="age" />
</resultMap>

上面实例使用 <constructor> 标签匹配 UserBean(Integer userId, String name) 构造器,其中:

  • idArg:用来映射参数时数据表ID字段

  • arg:用来映射普通参数

    • column:用来指定构造器参数对应的数据库表列

    • javaType:用来指定参数的Java类型,如:int、String

上面定义的 UserBean 中仅有一个 UserBean(Integer userId, String name) 构造器。<resultMap> 默认情况下会根据默认构造器(无参构造器)来创建该JavaBean的对象。如果我们不使用 <constructor> 标签匹配该构造器,将抛出如下错误:

### Cause: org.apache.ibatis.reflection.ReflectionException:
    Error instantiating class com.hxstrive.mybatis.resultmap.demo5.UserBean with invalid types () or values ().
    Cause: java.lang.NoSuchMethodException: com.hxstrive.mybatis.resultmap.demo5.UserBean.<init>()

constructor 属性列表:

属性描述
column数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName) 方法的参数一样。
javaType一个 Java 类的完全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。
jdbcTypeJDBC 类型,所支持的 JDBC 类型参见这个表格之前的“支持的 JDBC 类型”。只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可能存在空值的列指定这个类型。
typeHandler我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。这个属性值是一个类型处理器实现类的完全限定名,或者是类型别名。
select用于加载复杂类型属性的映射语句的 ID,它会从 column 属性中指定的列检索数据,作为参数传递给此 select 语句。具体请参考关联元素。
resultMap结果映射的 ID,可以将嵌套的结果集映射到一个合适的对象树中。它可以作为使用额外 select 语句的替代方案。它可以将多表连接操作的结果映射成一个单一的 ResultSet。这样的 ResultSet将会将包含重复或部分数据重复的结果集。为了将结果集正确地映射到嵌套的对象树中,MyBatis 允许你 “串联”结果映射,以便解决嵌套结果集的问题。想了解更多内容,请参考下面的关联元素。
name构造方法形参的名字。从 3.4.3 版本开始,通过指定具体的参数名,你可以以任意顺序写入 arg 元素。参看上面的解释。               

完整示例

(1)MyBatis 配置文件 mybatis-cfg.xml 内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="database.properties"/>
    <environments default="MySqlDatabase" >
        <environment id="MySqlDatabase" >
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com\hxstrive\mybatis\resultmap\demo5\UserMapper.xml" />
    </mappers>
</configuration>

(2)Mapper 接口 UserMapper 内容如下:

package com.hxstrive.mybatis.resultmap.demo5;

import java.util.List;

public interface UserMapper {
   /** 查询所有用户信息 */
   List<UserBean> findAll();
}

(3)Mapper XML 文件 UserMapper 内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
   "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hxstrive.mybatis.resultmap.demo5.UserMapper">

   <!--
      如果我们没有使用 <constructor> 则会抛出如下错误信息:
      ### Cause: org.apache.ibatis.reflection.ReflectionException:
      Error instantiating class com.hxstrive.mybatis.resultmap.demo5.UserBean with invalid types () or values ().
      Cause: java.lang.NoSuchMethodException: com.hxstrive.mybatis.resultmap.demo5.UserBean.<init>()
      抛出这个错误的原因是因为 UserBean 中没有提供默认构造方法
   -->
   <resultMap id="RESULT_MAP" type="com.hxstrive.mybatis.resultmap.demo5.UserBean">
      <!-- constructor 用来映射 UserBean(Integer userId, String name) 构造方法 -->
      <constructor>
         <idArg column="user_id" javaType="int" />
         <arg column="name" javaType="String" />
      </constructor>
      <result column="sex" jdbcType="VARCHAR" property="sex" />
      <result column="age" jdbcType="INTEGER" property="age" />
   </resultMap>

   <select id="findAll" resultMap="RESULT_MAP">
      select `user_id`, `name`, `sex`, `age` from `user`
   </select>

</mapper>

(4)JavaBean UserBean 内容如下:

package com.hxstrive.mybatis.resultmap.demo5;

public class UserBean {
   private Integer userId;
   private String name;
   private String sex;
   private Integer age;

   public UserBean(Integer userId, String name) {
      this.userId = userId;
      this.name = name;
   }

   // 忽略 getter 和 setter

   @Override
   public String toString() {
      return "UserBean{" +
            "userId=" + userId +
            ", name='" + name + '\'' +
            ", sex='" + sex + '\'' +
            ", age=" + age +
            '}';
   }
}

(5)客户端代码如下:

package com.hxstrive.mybatis.resultmap.demo5;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;
import java.util.List;

public class ResultMapDemo5 {

   public static void main(String[] args) throws Exception {
      // 获取 Mapper 对象
      String cfgName = "com/hxstrive/mybatis/resultmap/demo5/mybatis-cfg.xml";
      InputStream input = Resources.getResourceAsStream(cfgName);
      SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
      SqlSessionFactory sqlFactory = factoryBuilder.build(input);
      SqlSession sqlSession = sqlFactory.openSession(true);
      UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

      List<UserBean> userBeanList = userMapper.findAll();
      for(UserBean userBean : userBeanList) {
         System.out.println("结果:" + userBean);
      }
   }
   
}
说说我的看法
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号