Use of resultType and resultMap in MyBatis

Posted by jlive on Sat, 06 Nov 2021 01:04:22 +0100

Encapsulate output results: MyBatis executes sql statements to get ResultSet, which is converted into java objects

Here we have two, resultType and resultMap

1.resultType

resultType attribute: used when executing select and appears as the attribute of the tag.

resultType: execute sql to get the type of ResultSet conversion, using the fully qualified name or alias of the type. Note that if a collection is returned, it should be set to the type contained in the collection, not the collection itself.

It has two values:

  1. Fully qualified name of java type
  2. Use alias

1.1 fully qualified name of Java type

Methods defined in dao interface

Student selectStudentById(Integer id);

mapper file

<select id="selectStudentById" parameterType="int" resultType="com.lu.entity.Student">
	select id, name, email, age from student where id = #{studentId}
</select>

resultType: the fully qualified name of the java type is now used. It means that mybatis executes sql and converts the data in the ResultSet into Student type objects.

mybatis will do the following:

1. Call the parameterless construction method of com.lu.entity.Student to create the object.

Student student = new Student();	//Creating objects with reflections

2. Assign a column with the same name to an attribute with the same name

student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));

3. Get the java object. If the returned value of dao interface is the List set, mybatis puts the student object into the List set

Therefore, execute Student mystudent = dao.selectById(1001);

Get the row of data with id = 1001 in the database, and assign the column value of this row of data to the attribute of mystudent object. You can get the mystudent object, which is equivalent to the row of data with id = 1001.

1.2 user defined alias

mybatis provides a short, memorable name for java type definitions.

There are two ways to customize aliases: typeAlias and package

1.2.1 typeAlias custom alias

To customize an alias using typeAlias:

1. In the mybatis main configuration file, use the typeAliases tag to declare aliases

<typeAliases>
    <!--First syntax format
    	type:java The fully qualified name of the type(Custom type)
    	alias:Custom alias
    -->
	<typeAlias type="com.lu.entity.Student" alias="stu"></typeAlias>
</typeAliases>

Note: the label must be written after the label

2. In the mapper file, resultType = "alias"

<select id="selectStudentById" parameterType="int" resultType="stu">
	select id, name, email, age from student where id = #{studentId}
</select>

3. Test in test class

    @Test
    public void testselectStudentById() {
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        Student student = dao.selectStudentById(1002);
        System.out.println(student);
        session.close();
    }

Console output:


Using typeAlias has both advantages and disadvantages

Advantage: alias can be customized

Disadvantages: each type must be defined separately

1.2.2 package user defined alias

In the master profile:

<!--The second way
	name:Package name, mybatis All class names in this package will be used as aliases
-->
<package name="com.lu.entity"/>

In the mapper file:

<select id="selectStudentById" parameterType="int" resultType="student">
	select id, name, email, age from student where id = #{studentId}
</select>

In this way, the resultType is not case sensitive, so it is also possible to use all lowercase

Test in test class:

Similarly, the test was successful

Advantages: it is easy to use and defines aliases for multiple classes at a time.

Disadvantages: alias cannot be defined casually. It must be a class name.

Both of these user-defined aliases have advantages and disadvantages, so it is recommended to use fully qualified names if they are not applicable to aliases.

1.3 resultType represents a simple type

We first define a method in the dao interface

long countStudent();

Write sql statements in the mapper file

<!--implement sql Statement to get a value(Row by column)-->
<select id="countStudent" resultType="java.lang.Long">
	select count(*) from student
</select>

Test in test class

    @Test
    public void testCountStudent() {
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        long nums = dao.countStudent();
        System.out.println("nums = " + nums);

        session.close();
    }

Console output:

1.4 resultType

Methods defined in dao interface:

Map<Object, Object> selectMap(Integer id);

Write sql statements in mapper file:

<!--
	implement sql Get one Map Structural data, mybatis implement sql,hold ResultSet Turn into map
-->
<select id="selectMap" resultType="java.util.HashMap">
	select id, name from student where id = #{studentid}
</select>

Test in test class:

    @Test
    public void testSelectMap() {
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        Map<Object, Object> map = dao.selectMap(1001);
        System.out.println("map = " + map);
        System.out.println("name = " + map.get("name"));
        System.out.println("id = " + map.get("id"));
        session.close();
    }

Console output:

We can see the execution result. The column name is the key of the map and the column value is the value

The dao interface returns a map. The sql statement can obtain at most one line of records. More than one line is an error

2.resultMap

resultMap: result map. Customize the correspondence between column names and Java object properties. It is often used when the column name and attribute name are different.

Usage:

1. First define the resultMap tag and specify the corresponding relationship between column name and attribute name

2. Use the resultMap attribute in the select tab to specify the id value of the resultMap defined above

Let's take an example

First define a CustomObject class

package com.lu.entity;

public class CustomObject {
    private Integer cid;
    private String cname;
    private String email;
    private Integer age;

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "CustomObject{" +
                "cid=" + cid +
                ", cname='" + cname + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

We found that cid and cname are inconsistent with the column names in the database

We define a method in the dao interface

CustomObject selectById2(Integer id);

If we want to assign the content extracted from the database to the CustomObject object, if we continue to use resultType, the data extracted from the database can only be assigned to email and age, not cid and cname. At this time, we need to use resultMap

We write this in the mapper file:

    <!--
        use resultMap Define the relationship between columns and attributes
        definition resultMap
            id:to resultMap The mapping relationship of has a name and unique value
            type:Java The fully qualified name of the type
    -->
    <resultMap id="customMap" type="com.lu.entity.CustomObject">
        <!--Define the correspondence between the column name and the property name-->
        <!--Primary key type usage id label-->
        <id column="id" property="cid"></id>
        <!--Non primary key type use result label-->
        <result column="name" property="cname"></result>
        <!--The column name is the same as the attribute name, and there is no need to define it-->
    </resultMap>

    <!--use resultMap Property that specifies the of the mapping relationship id-->
    <select id="selectById2" resultMap="customMap">
        select id, name, email, age from student where id = #{studentid}
    </select>

In this way, we can use resultMap to define the relationship between database columns and attributes

We test in the test class:

    @Test
    public void testSelectById2() {
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        CustomObject co = dao.selectById2(1001);
        System.out.println(co);
        session.close();
    }

Console output:


In this way, resultMap successfully solves the inconsistency between column names and attribute names.

Note: resultType and resultMap cannot be used at the same time.

3. Solution to inconsistency between column name and Java object attribute name

3.1 using resultMap: customize the correspondence between column names and attribute names

This method is explained when explaining resultMap above. You can look at it directly

3.2 using resultType

Use the column alias to make the alias the same as the Java object property name

We define a method in the dao interface:

CustomObject selectById3(Integer id);

We write in the mapper file:

<!--Use column aliases to solve the problem of different column names and attribute names-->
<select id="selectById3" resultType="com.lu.entity.CustomObject">
	select id AS cid, name AS cname, email, age where id = #{studentid}
</select>

We test in the test class

    @Test
    public void testSelectById3() {
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        CustomObject co = dao.selectById2(1003);
        System.out.println(co);
        session.close();
    }

Console output:

Topics: Java Mybatis Back-end