1. 程式人生 > >Mybatis在接口上使用註解配置SQL語句以及接口與xml一起使用

Mybatis在接口上使用註解配置SQL語句以及接口與xml一起使用

Mybatis 持久層框架

在接口上使用註解配置SQL語句

MyBatis對於大部分的基於XML的映射器元素(包括<select>,<update>)提供了對應的基於註解的配置項。然而在某些情況下,基於註解配置 還不能支持基於XML的一些元素。MyBatis提供了多種註解來支持不同類型的語句(statement)如SELECT,INSERT,UPDATE,DELETE。下面我們通過一個小demo來簡單演示一下這些基本註解的使用方式:

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

首先編寫表格的字段封裝類,代碼如下:

package org.zero01.pojo;

public class Student {

    private int sid;
    private String sname;
    private int age;
    private String sex;
    private String address;
    ... getter setter 略 ...
}

然後需要寫一個接口,在該接口的方法上配置註解,註解的名稱基本都能自註釋了,我這裏就不贅述它們的作用了。代碼如下:

package org.zero01.mapper;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.zero01.pojo.Student;

import java.util.List;

public interface StudentMapper {

    @Insert("insert into student(sname,age,sex,address) values(#{sname},#{age},#{sex},#{address})")
    public int insertStu(Student student);

    @Delete("delete from student where sid=#{0}")
    public int delStu(int sid);

    @Select("select * from student where sid=#{0}")
    public Student selectById(int sid);

    @Select("select * from student")
    public List<Student> selectAll();

    @Select("select * from student limit #{param1},#{param2}")
    public List<Student> selectByLimit(int startRow, int endRow);

    @Update("update student set sname=#{sname},age=#{age},sex=#{sex},address=#{address} where sid=#{sid}")
    public int updateStu(Student student);

}

mybatis配置文件內容如下:

<?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">
<configuration>
    <typeAliases>
        <typeAlias type="org.zero01.pojo.Student" alias="Student"/>
        <typeAlias type="org.zero01.pojo.StudentLog" alias="StudentLog"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <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>
    <mappers>
        <!-- 通過包名引入接口 -->
        <mapper class="org.zero01.mapper.StudentMapper"/>
    </mappers>
</configuration>

編寫一個測試類進行測試,代碼如下:

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.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.zero01.student.Student;

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

public class TestMyBatis {

    private SqlSession sqlSession;
    private StudentMapper studentMapper;

    // 加載資源
    @Before
    public void testStart() throws IOException {
        // 配置文件路徑
        String confPath = "mybatis-config.xml";
        // 讀取配置文件得到輸入流
        InputStream inputStream = Resources.getResourceAsStream(confPath);
        // 創建sql Session工廠對象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 建立與數據庫的會話
        sqlSession = sqlSessionFactory.openSession();
        // 得到的是一個動態代理類
        studentMapper = sqlSession.getMapper(StudentMapper.class);
    }

    @Test
    public void testInsertStu() {
        Student student = new Student();
        student.setSname("Milen");
        student.setAge(20);
        student.setSex("女");
        student.setAddress("深圳");
        int result = studentMapper.insertStu(student);
        Assert.assertNotEquals(result, 0);
        sqlSession.commit();
    }

    @Test
    public void testDelStu() {
        int result = studentMapper.delStu(23);
        Assert.assertNotEquals(result, 0);
        sqlSession.commit();
    }

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

    @Test
    public void testSelectAll() {
        List<Student> students = studentMapper.selectAll();
        Assert.assertNotEquals(students.size(), 0);
        Assert.assertNotNull(students);
        System.out.println("id\tsname\tage\tsex\taddress");
        for (Student student : students) {
            System.out.print(student.getSid() + "\t");
            System.out.print(student.getSname() + "\t");
            System.out.print(student.getAge() + "\t");
            System.out.print(student.getSex() + "\t");
            System.out.print(student.getAddress() + "\n");
        }
    }

    @Test
    public void testSelectByLimit() {
        List<Student> students = studentMapper.selectByLimit(0, 5);
        Assert.assertNotEquals(students.size(), 0);
        Assert.assertNotNull(students);
        System.out.println("id\tsname\tage\tsex\taddress");
        for (Student student : students) {
            System.out.print(student.getSid() + "\t");
            System.out.print(student.getSname() + "\t");
            System.out.print(student.getAge() + "\t");
            System.out.print(student.getSex() + "\t");
            System.out.print(student.getAddress() + "\n");
        }
    }

    @Test
    public void testUpdateStu() {
        Student student = new Student();
        student.setSid(7);
        student.setSname("Mkans");
        student.setAge(23);
        student.setSex("男");
        student.setAddress("湖南");
        int result = studentMapper.updateStu(student);
        Assert.assertNotEquals(result, 0);
        sqlSession.commit();
    }

    // 關閉資源
    @After
    public void testEnd() {
        if (sqlSession != null) {
            // 結束與數據庫的會話
            sqlSession.close();
        }
    }
}

結果映射

除了基本的sql語句的配置外,我們還可以通過註解配置結果映射,如下示例:

@Select("select * from student")
@Results({
        @Result(id = true, property = "sid",column = "sid"),
        @Result(property = "sname",column = "sname"),
        @Result(property = "age",column = "age"),
        @Result(property = "sex",column = "sex"),
        @Result(property = "address",column = "address")
})
public List<Student> selectAll();

註:@Results註解與XML配置文件中的&lt;resultMap&gt;標簽相對應。

我們在XML配置文件中可以配置一對多的連接查詢,但是需要通過標簽設置結果集與字段的映射關系。在註解裏我們沒法這麽做,因為沒有對應的註解支持。但是我們可以先在XML配置好映射關系,然後通過@ResultMap註解來引用它。如下示例:

<?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.mapper.StudentMapper">
    <resultMap id="stuMap" type="Student">
        <id property="sid" column="sid"/>
        <result property="sname" column="sname"/>
        <result property="age" column="age"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
        <association property="studentLog" resultMap="stuLogMap"/>
    </resultMap>
    <resultMap id="stuLogMap" type="StudentLog">
        <id property="log_id" column="log_id"/>
        <result property="sid" column="sid"/>
        <result property="sname" column="sname"/>
        <result property="age" column="age"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
        <result property="operation_type" column="operation_type"/>
        <result property="log_time" column="log_time"/>
    </resultMap>
</mapper>

註解配置內容如下:

@Select("select * from student stu inner join studentlog stulog on  stu.`sid`=stulog.`sid`")
@ResultMap("org.zero01.mapper.StudentMapper.stuMap")  // 引用XML裏配置的映射器
public List<Student> selectInnerLog();

接口與xml一起使用

通常情況下我們都是將接口與XML配置文件混合使用,這樣比純XML或者純註解的方式要簡單一些。

將接口代碼的註解刪除,修改如下:

package org.zero01.mapper;

import org.zero01.pojo.Student;

import java.util.List;

public interface StudentMapper {

    public int insertStu(Student student);

    public int delStu(int sid);

    public Student selectById(int sid);

    public List<Student> selectAll();

    public List<Student> selectByLimit(int startRow, int endRow);

    public int updateStu(Student student);

    public List<Student> selectInnerLog();

}

然後在mybatis配置文件中,加入如下內容:

<mappers>
    <mapper class="org.zero01.mapper.StudentMapper"/>
    <mapper resource="org/zero01/mapper/StudentMapper.xml"/>
</mappers>

新增的StudentMapper.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.mapper.StudentMapper">
    <resultMap id="stuMap" type="Student">
        <id property="sid" column="sid"/>
        <result property="sname" column="sname"/>
        <result property="age" column="age"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
        <association property="studentLog" resultMap="stuLogMap"/>
    </resultMap>
    <resultMap id="stuLogMap" type="StudentLog">
        <id property="log_id" column="log_id"/>
        <result property="sid" column="sid"/>
        <result property="sname" column="sname"/>
        <result property="age" column="age"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
        <result property="operation_type" column="operation_type"/>
        <result property="log_time" column="log_time"/>
    </resultMap>
    <select id="selectInnerLog" resultMap="stuMap">
        select * from student stu inner join studentlog stulog on  stu.`sid`=stulog.`sid`
    </select>

    <insert id="insertStu" parameterType="Student">
        insert into student(sname,age,sex,address) values(#{sname},#{age},#{sex},#{address})
    </insert>
    <delete id="delStu" parameterType="int">
        delete from student where sid=#{0}
    </delete>
    <select id="selectById" parameterType="int" resultType="Student">
        select * from student where sid=#{0}
    </select>
    <select id="selectAll" resultType="Student">
        select * from student
    </select>
    <update id="updateStu" parameterType="Student">
        update student set sname=#{sname},age=#{age},sex=#{sex},address=#{address} where sid=#{sid}
    </update>
</mapper>

註:標簽id屬性的值需要與接口方法的名稱相對應。

Mybatis在接口上使用註解配置SQL語句以及接口與xml一起使用