1. 程式人生 > >MyBatis結果集映射

MyBatis結果集映射

Mybatis 數據持久層框架 結果集映射 一對一 一對多

MyBatis配置文件常用配置

1.typeAliases標簽,該標簽用於配置全局的別名,配置別名後則不再需要寫全名,在映射文件中只需要寫配置的別名即可,例如:

<configuration>
    <typeAliases>
        <!-- type屬性的值為全名,alias的值則為別名 -->
        <typeAlias type="org.zero01.dao.pojo.Student" alias="Student"/>
    </typeAliases>
</configuration>

除了可以配置別名之外,還可以直接配置包掃描,這樣映射文件中只需要寫相應的類名即可:

<configuration>
    <typeAliases>
        <!-- name屬性的值為包名 -->
        <package name="org.zero01.dao.pojo"/>
    </typeAliases>
</configuration>

2.environments標簽,該標簽用於配置環境,在該標簽內可以對事務的管理以及數據庫連接池進行配置,例如:

<configuration>
    <typeAliases>
        <!-- name屬性的值為包名 -->
        <package name="org.zero01.dao.pojo"/>
    </typeAliases>
    <!-- 配置環境,default為表示默認的 -->
    <environments default="development">

    </environments>
</configuration>

3.environment標簽,該標簽用於配置具體的環境,可以寫多個,例如:

<configuration>
    <typeAliases>
        <!-- name屬性的值為包名 -->
        <package name="org.zero01.dao.pojo"/>
    </typeAliases>
    <!-- 配置環境,default為表示默認的 -->
    <environments default="development">
        <!-- 可配置多個數據庫環境,id的值為environments標簽中default屬性的值則表示該數據庫為默認的 -->
        <environment id="development">

        </environment>
        <environment id="testDevelopment">

        </environment>
    </environments>
</configuration>

4.transactionManager標簽,該標簽用於配置事務管理類型,其中的type屬性的值為JDBC時代表開啟事務,為MANAGED時代表關閉事務,例如:

<configuration>
    <typeAliases>
        <!-- name屬性的值為包名 -->
        <package name="org.zero01.dao.pojo"/>
    </typeAliases>
    <!-- 配置環境,default為表示默認的 -->
    <environments default="development">
        <!-- 可配置多個數據庫環境,id的值為environments標簽中default屬性的值則表示該數據庫為默認的 -->
        <environment id="development">
            <!-- 事務管理器配置 -->
            <transactionManager type="JDBC"/>
                or
            <transactionManager type="MANAGED"/>
        </environment>
    </environments>
</configuration>

5.dataSource標簽,該標簽用於配置數據源,以及指定是否使用數據庫連接池,例如

<configuration>
    <typeAliases>
        <!-- name屬性的值為包名 -->
        <package name="org.zero01.dao.pojo"/>
    </typeAliases>
    <!-- 配置環境,default為表示默認的 -->
    <environments default="development">
        <!-- 可配置多個數據庫環境,id的值為environments標簽中default屬性的值則表示該數據庫為默認的 -->
        <environment id="development">
            <!-- 事務管理器配置 -->
            <transactionManager type="JDBC"/>
            <!-- 配置數據源,POOLED表示使用數據庫連接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///school"/>
                <property name="username" value="root"/>
                <property name="password" value="your_password"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

6.mappers標簽,在該標簽內可配置映射文件路徑或者映射接口類以及映射文件的url路徑,例如:

<configuration>
    <typeAliases>
        <!-- name屬性的值為包名 -->
        <package name="org.zero01.dao.pojo"/>
    </typeAliases>
    <!-- 配置環境,default為表示默認的 -->
    <environments default="development">
        <!-- 可配置多個數據庫環境,id的值為environments標簽中default屬性的值則表示該數據庫為默認的 -->
        <environment id="development">
            <!-- 事務管理器配置 -->
            <transactionManager type="JDBC"/>
            <!-- 配置數據源,POOLED表示使用數據庫連接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///school"/>
                <property name="username" value="root"/>
                <property name="password" value="your_password"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 可配置映射文件路徑或者映射接口以及url路徑 -->
    <mappers>
        <!-- 配置映射文件的本地路徑 -->
        <mapper resource="mapper/StudentMapper.xml"/>
        <!-- 配置映射接口類 -->
        <mapper class="org.zero01.dao.mapperif.StudentMapper"/>
        <!-- 配置映射文件的url路徑 -->
        <mapper url="http://url.xxxx.com/mapper/StudentMapper.xml"/>
    </mappers>
</configuration>

mappers標簽內也可以配置包掃描,與typeAliases標簽內的配置方式是一樣的:

<mappers>
    <package name="org.zero01.dao.mapperif"/>
</mappers>

註:當接口與XML配置文件混合使用的時候,要註意避免命名空間發生沖突。


MyBatis結果集映射配置

當我們表格的字段名稱與字段封裝類裏的屬性名稱對應不上的時候,我們就得在配置文件中手動配置結果集對對象屬性的映射,不然MyBatis是不會自動映射的,得出來的就會是一個空對象。

例如,我現在有一張student表,表格結構如下:
技術分享圖片

然後編寫了一個表格的字段封裝類,代碼如下:

package org.zero01.dao.pojo;

public class Student {

    private int id;
    private String name;
    private int stuAge;
    private String stuSex;
    private String stuAddress;
    ... getter setter 略 ...
}

接口類代碼如下:

package org.zero01.dao.mapperif;

import org.zero01.dao.pojo.Student;

public interface StudentMapper {
    public Student selectById(int id);
}

可以看到對象屬性名稱與表格字段名稱不一致,這時候就需要配置結果集的映射器,在XML配置文件裏進行配置,如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zero01.dao.mapperif.StudentMapper">
    <resultMap id="stuMap" type="Student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="stuAge" column="age"/>
        <result property="stuSex" column="sex"/>
        <result property="stuAddress" column="address"/>
    </resultMap>
    <select id="selectById" resultMap="stuMap" parameterType="int">
        select * from student where sid=#{0}
    </select>
</mapper>

編寫一個簡單的測試用例進行測試,測試代碼如下:

package org.zero01.test;

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 org.json.JSONObject;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.zero01.dao.mapperif.StudentMapper;
import org.zero01.dao.pojo.Student;

import java.io.IOException;
import java.io.InputStream;

public class TestMybatis {

    private SqlSession sqlSession;
    private StudentMapper studentMapper;

    @Before
    public void startTest() throws IOException {
        String confPath = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(confPath);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession = sqlSessionFactory.openSession();
        studentMapper = sqlSession.getMapper(StudentMapper.class);
    }

    @Test
    public void testSelectById() {
        Student student = studentMapper.selectById(24);
        Assert.assertNotNull(student);
        System.out.println(new JSONObject(student));
    }

    @After
    public void endTest() {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

控制臺打印結果如下,沒有問題:

{"stuSex":"女","name":"Milen","stuAddress":"深圳","id":24,"stuAge":20}

如果我們需要進行連接查詢的時候,也需要用到結果集映射,例如我現在要查詢student表與studentlog中sid一致的記錄。studentlog表格結構如下:
技術分享圖片

同樣的,需要先創建一個表格字段封裝類:

package org.zero01.dao.pojo;

import java.util.Date;

public class StudentLog {

    private int log_id;
    private int id;
    private String name;
    private int stuAge;
    private String stuSex;
    private String stuAddress;
    private String operation_type;
    private Date log_time;
    ... getter setter 略 ...
}

然後在Student類中,增加StudentLog屬性:

package org.zero01.dao.pojo;

public class Student {

    private int id;
    private String name;
    private int stuAge;
    private String stuSex;
    private String stuAddress;
    private StudentLog studentLog;
    ... getter setter 略 ...
}

然後需要在XML文件中使用association標簽來配置連接查詢的結果集映射,如下示例:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zero01.dao.mapperif.StudentMapper">
    <resultMap id="stuMap" type="Student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="stuAge" column="age"/>
        <result property="stuSex" column="sex"/>
        <result property="stuAddress" column="address"/>
        <association property="studentLog" javaType="StudentLog" fetchType="lazy">
            <id property="log_id" column="log_id"/>
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="stuAge" column="age"/>
            <result property="stuSex" column="sex"/>
            <result property="stuAddress" column="address"/>
            <result property="operation_type" column="operation_type"/>
            <result property="log_time" column="log_time"/>
        </association>
    </resultMap>
    <select id="selectInnerLog" resultMap="stuMap">
        select * from student stu inner join studentlog stulog on  stu.`sid`=stulog.`sid`
    </select>
</mapper>

其中javaType屬性用於指定將結果集數據封裝成哪種Java類型,在這裏為自定義類型,而fetchType屬性指定是否開啟延遲加載,lazy為開啟,eager為禁止。也可以在mybatis配置文件中通過settings標簽來配置開啟或關閉延遲加載,這種配置方式是全局生效的,如下示例:

<configuration>
    ...
    <settings>
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>
    ...
</configuration>

association標簽中有一個select屬性,通過該屬性我們可以執行指定的查詢語句。例如我現在需要查詢一個學生的記錄,我希望查詢的時候能統計出表格中與該學生同名的學生數量。在Studnet中加多一個count屬性:

package org.zero01.dao.pojo;

public class Student {

    private int id;
    private String name;
    private int stuAge;
    private String stuSex;
    private String stuAddress;
    private StudentLog studentLog;
    private int count;
    ... getter setter 略 ...
}

然後編輯XML文件內容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zero01.dao.mapperif.StudentMapper">
    <resultMap id="stuMap" type="Student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="stuAge" column="age"/>
        <result property="stuSex" column="sex"/>
        <result property="stuAddress" column="address"/>
        <association property="count" column="sname" select="countStu"/>
    </resultMap>
    <select id="selectById" resultMap="stuMap" parameterType="int">
        select * from student where sid=#{0}
    </select>
    <select id="countStu" resultType="int">
        select count(*) as total from student where sname=#{0}
    </select>
</mapper>

註:查詢語句不能是無參數值的,因為使用select屬性時必須要有column屬性,這時候的column屬性是用來傳遞參數的。例如:select count(*) as total from student這類語句是無效的。而如果要傳遞多個參數時,需要使用大括號括起來,例如:column="{prop1=sid,prop2=sname,prop3=age,}"

從以上簡單的示例中,可以看到association標簽完成的是一對一的級聯操作的結果集映射,如果是一對多的操作時就需要使用collection標簽進行結果集的映射。例如,我在Student裏增加一個studentLogs屬性,要求把查詢出來的StudentLog對象都放在這個集合裏,這種操作就是一對多:

package org.zero01.dao.pojo;

public class Student {

    private int id;
    private String name;
    private int stuAge;
    private String stuSex;
    private String stuAddress;
    private StudentLog studentLog;
    private int count;
    private List<StudentLog> studentLogs;
    ... getter setter 略 ...
}

編輯XML文件內容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zero01.dao.mapperif.StudentMapper">
    <resultMap id="stuMap" type="Student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="stuAge" column="age"/>
        <result property="stuSex" column="sex"/>
        <result property="stuAddress" column="address"/>
        <!-- ofType屬性用於指定將數據封裝成哪個對象 -->
        <collection property="studentLogs" javaType="List" ofType="StudentLog">
            <id property="log_id" column="log_id"/>
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="stuAge" column="age"/>
            <result property="stuSex" column="sex"/>
            <result property="stuAddress" column="address"/>
            <result property="operation_type" column="operation_type"/>
            <result property="log_time" column="log_time"/>
        </collection>
    </resultMap>
    <select id="selectInnerLog" resultMap="stuMap">
        SELECT * FROM student stu INNER JOIN studentlog stulog ON stu.`sid`=stulog.`sid`
    </select>
</mapper>

MyBatis結果集映射