MyBatis——MyBatis開發流程

城北有個混子發表於2020-11-17

建立專案(IDEA中)

  在IDEA中建立 MyBatis專案,詳細流程如下:

  這裡有一點需要注意,我們建立的是Maven專案,如果大家以前沒有配置過Maven環境的話,在建立完專案之後,需要配置一下Maven環境,否則就無法成功匯入相關的依賴包。

  建立完成後的專案是這個樣子的:

專案概述:

  ★ src目錄就是我們專案的開發目錄,裡面有兩個目錄:main和test。

  ➷ main目錄是我們開發專案的目錄,裡面是專案的幾乎所有資訊,包括Java的類檔案、一些properties配置檔案和MyBatis配置檔案等。

  ✈ main目錄下有兩個資料夾:Java和resources,顧名思義,Java目錄下肯定就是Java類檔案了;resources目錄下放的的是配置檔案。

  ➷ test目錄是我們專案開發的測試目錄,我們在這個目錄下來寫我們的測試類,來測試我們所寫的功能是否能夠正常運作。

  ✄ 還有一個pom.xml檔案,這個檔案是我們所建立的Maven專案的依賴匯入配置檔案,我們在這個配置檔案中寫上專案所需要依賴的包的相關資訊,Maven會替我們自動匯入專案,不用我們主動下載並新增依賴包,這樣能極大的減輕我們的工作量。

  其他檔案我們不用過多關注,都是一些專案配置資訊,一般很少用到。

 


匯入依賴(配置pom檔案)

我們需要匯入的專案依賴主要由以下幾個:

  ① MyBatis核心依賴

  ② MySql驅動依賴

  ③ 日誌依賴:Log4J

  ④ 測試依賴:junit

  ⑤ 連線池依賴

  這些都是專案基礎的依賴配置,後面根據專案需求可新增其他的依賴項,比如:分頁元件依賴等。

  我們是在pom.xml檔案中配置的,在pom.xml檔案中的project標籤中加入下面的資訊:

<!-- 匯入依賴 -->
<dependencies>
    <!--MyBatis核心依賴-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>

    <!--MySql驅動依賴-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.25</version>
    </dependency>

    <!-- 日誌依賴:Log4J -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <!-- 測試依賴:junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
    <!-- 連線池依賴:阿里的druid(可選其他,目前這個是比較好的) -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>

</dependencies>

  我這裡選用的連線池是阿里的druid連線池,目前來說應該是比較好的連線池了,大家可根據自己的需求自行調整,更換其他的連線池。

  依賴的版本之間可能存在衝突現象,大家可選擇普遍都用的版本,可參考Maven儲存庫

 


建立並編寫MyBatis配置檔案(mybatis-config.xml)

  在resources目錄下建立『mybatis-config.xml』配置檔案,這個檔案就是我們MyBatis專案的配置檔案,之後我們也要通過它來建立SqlSessionFactory物件,因一步來建立SqlSession物件。

『mybatis-config.xml』初始模板:

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

<configuration>
    <!--配置標籤的順序:(properties?, settings?, typeAliases?,
        typeHandlers?, objectFactory?, objectWrapperFactory?,
        reflectorFactory?, plugins?, environments?,
        databaseIdProvider?, mappers?)-->


</configuration>

  我們是在configuration標籤中新增我們的配置項的,配置項是有順序的,必須依照官方給的順序從上往下依次放置,否則會導致一些問題,比如配置失效等。

資料庫配置資訊(jdbc.properties)

  MyBatis要和資料庫打交道,那肯定需要連線資料庫了,所以,我們現在要配置的就是資料庫資訊。

  首先,在resources目錄下建立『jdbc.properties』配置檔案,這個是資料庫配置檔案,在裡面新增如下資訊:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/{資料庫名}?useUnicode=true&characterEncoding=utf-8
jdbc.username={使用者名稱}
jdbc.password={密碼}

  大家根據自己的資訊,替換配置中的{XXX}。上面這個是MySQL的連線配置,如果大家連線的是其他資料庫的話,可更該此配置中的資訊。

  然後,我們需要『mybatis-config.xml』的configuration標籤中配置相關資訊:

<configuration>

    <!-- 匯入外部的引數 -->
    <properties resource="jdbc.properties"></properties>

    <!--核心配置資訊-->
    <environments default="ss_config">
        <!--資料庫相關配置-->
        <environment id="ss_config">
            <!--事務控制型別-->
            <transactionManager type="jdbc"></transactionManager>
            <!--資料庫連線配置-->
            <dataSource type="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory">
                <property name="driver" value="${jdbc.driver}"/>
                <!-- &轉義&amp; -->
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

</configuration>

  我們匯入了jdbc的配置檔案,然後在environments標籤項中配置相關資訊,default屬性和id屬性可根據自己意願填寫(其實就是個名字而已),我們在這選用的是MyBatis預設的連線池,dataSource 標籤的type屬性就是,之後我們可選擇更改效能更好的連線池。

  其他的配置資訊應和上述配置一致。

日誌配置資訊(log4j.properties)

  我們之前已經匯入了Log4j日誌框架的依賴,這個日誌框架可以幫我們輸出日誌資訊,以便我們更好的除錯可開發專案。我們還需要做的是編寫一個日誌配置檔案,填寫相關配置資訊。

  在resources目錄下建立『log4j.properties』配置檔案,注意名稱是全小寫的,在其內新增如下資訊:

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

  好了,日誌配置已完成,MyBatis會自動檢索配置資訊。

 


建立表(資料庫表)

  在剛才『jdbc.properties』配置檔案中所填的資料庫中建立資料表,我們在這以users表為例:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `password` varchar(50) DEFAULT '12345',
  `sex` varchar(1) DEFAULT NULL,
  `birthday` datetime DEFAULT NULL,
  `registtime` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
)DEFAULT CHARSET=utf8;

  建立成功後,在表中新增一些資訊,如:

 


建立實體對映(entity實體)

  好了,我們需要建立一個實體,來對應資料庫中的表中的資料項。

  在java目錄下建立com.entity實體類包,在包中建立User實體類:

  User實體類的屬性要和資料表的欄位對應,型別和名字要相同,最好使用駝峰命名法,因為當MyBatis從資料庫中得到資料後時進行set注入的,就是呼叫對應屬性名字的set方法進行賦值,如果屬性名字不一致,MyBatis就無法找到其set方法,其值會為預設值。

  當名字不一致時我們的解決方法是:Sql語句加別名 或者 新增關係對映(推薦使用)。

  例如下面的User實體的最後一個屬性名就和資料表的最後一個欄位名不一致,我們在後面會進行處理。

User實體類如下:

package com.entity;

import java.util.Date;

public class User {
    private Integer id;
    private String name;
    private String password;
    private String sex;
    private Date birthday;
    private Date registTime;

    public User() {}

    public User(Integer id, String name, String password, String sex, Date birthday, Date registTime) {
        this.id = id;
        this.name = name;
        this.password = password;
        this.sex = sex;
        this.birthday = birthday;
        this.registTime = registTime;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                ", registTime=" + registTime +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Date getRegistTime() {
        return registTime;
    }

    public void setRegistTime(Date registTime) {
        this.registTime = registTime;
    }
}

定義別名

  我們還需要在MyBatis配置檔案『mybatis-config.xml』中為我們的實體類定義別名,這樣我們就不用總帶著包名一起來書寫了,可以提高我們的書寫效率。

  定義別名有兩種方式,一般我們選擇第二種:

<!-- 實體類別名 -->
<typeAliases>
    <!-- 方式一:單獨定義-->
    <!--<typeAlias type="com.entity.User" alias="user_shine"/>-->
    
    <!-- 方式二:定義實體類所在的package,每個實體類都會自動註冊一個別名=類名 -->
    <package name="com.entity"/>
</typeAliases>

  在『mybatis-config.xml』的configuration標籤內的properties標籤後面新增上述配置資訊。

 


建立Dao層

  接下來我們要編寫資料訪問層了,也就是DAO層。

  在java目錄下建立一個包:com.Dao。

建立xxDao介面檔案

  在剛才所建立的包內建立User實體類所對應的Dao介面檔案:UserDao.java。

  在這個介面檔案中,定義我們要對資料進行的操作方法,如:

package com.Dao;

import com.entity.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserDao {

    // 查詢全部
    public List<User> queryAll();

    // 通過id查詢
    public User selectUserById(@Param("id") Integer id);

    // 模糊查詢
    public List<User> selectUserByKeyword(@Param("keyword") String keyword);

    // 插入
    public Integer insertUser(User user);

    // 刪除
    public Integer deleteUser(@Param("id") Integer id);

    // 修改
    public Integer updateUser(User user);
}

  在上面的方法中涉及到引數的傳遞,也就是引數繫結方式,常見的引數繫結方式有:

    ➷ 序號引數繫結

    ➷ 註解引數繫結(推薦)

    ➷ Map引數繫結

    ➷ 物件引數繫結

  我們上面所用的就是註解引數繫結,因為篇幅考慮,就不做過多闡述了。

建立xxDaoMapper.xml配置檔案

  建立了上面的這些方法,如何去實現它們呢?

  這就要靠我們的Mapper配置檔案了,一個Dao介面檔案對應一個Mapper配置檔案。MyBatis替我們封裝了資料訪問的其他操作,我們只需要關注Sql語句本身就可以了,而Sql語句寫在哪呢?就是Mappe配置檔案中。

  在com.Dao包中建立Mapper配置:UserDaoMapper.xml。

 


配置xxDaoMapper.xml

下面是Mapper檔案的初始模板:

<?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="com.dao.UserDao">


</mapper>

  mapper標籤中的namespace屬性是我們這個Mapper檔案所對應的Dao介面檔案,mapper標籤中書寫Dao介面中每個方法所對應的Sql語句。

  上面的Dao介面所對應的完整Mapper配置如下:

<?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="com.Dao.UserDao">

<resultMap id="UserResultMap" type="com.entity.User">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <result property="password" column="password"/>
    <result property="sex" column="sex"/>
    <result property="birthday" column="birthday" />
    <result property="registTime" column="registtime" />
</resultMap>

<sql id="user_field">
        select id, name, password,sex,birthday,registtime
        from s_user where
    </sql>

<select id="queryAll" resultType="User">
        select * from s_user
    </select>

<select id="selectUserById" resultMap="UserResultMap">
    <include refid="user_field"/>
    id = #{id}
</select>

<select id="selectUserByKeyword" resultMap="UserResultMap">
    <include refid="user_field"/>
    name like concat('%',#{keyword},'%')
</select>

<insert id="insertUser" parameterType="User">
    <selectKey keyProperty="id" resultType="int" order="AFTER">
        SELECT LAST_INSERT_ID()
    </selectKey>
    insert into s_user
    values(#{id},#{name},#{password},#{sex},#{birthday},#{registTime})
</insert>

<delete id="deleteUser" parameterType="int">
        delete from s_user
        where id=#{id}
    </delete>

<update id="updateUser" parameterType="User">
        update s_user set name=#{name},password=#{password},sex=#{sex},birthday=#{birthday},
        registtime=#{registTime} where id=#{id}
    </update>


</mapper>

  resultMap 標籤就是我們上面提到的屬性關係對映,來解決欄位名不一致的問題,當我們需要用的時候,將select標籤的resultType屬性改為resultMap就可以了。

  每種操作有對應的標籤,id就是其方法名,後面是傳遞的值型別。

註冊Mapper

  寫完Mapper後,是需要註冊的,在『mybatis-config.xml』的configuration標籤內新增如下資訊:

<!-- 註冊mapper檔案 -->
<mappers>
    <mapper resource="com/Dao/UserDaoMapper.xml"/>
</mappers>

  註冊成功後,MyBatis才會去尋找這個配置檔案

配置編譯路徑

  此時這個配置檔案,MyBatis是找不到的,為什麼呢?因為MyBatis只會自動查詢resources目錄下的配置檔案,而我們的Mapper配置檔案並不在resources目錄下。那如何解決呢?

  我們需要在pom.xml檔案的project標籤中新增如下資訊:

<build>
    <!-- 更改maven編譯規則 -->
    <resources>
        <resource>
            <!-- 資源目錄 -->
            <directory>src/main/java</directory>
            <includes>
                <include>*.xml</include><!-- 預設(新新增自定義則失效) -->
                <include>**/*.xml</include><!-- 新新增 */代表1級目錄 **/代表多級目錄 -->
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

  自此,Mapper配置才會生效。

 


編寫工具類

  MyBatis的核心是SqlSessionFactoryBuider、SqlSessionFactory和SqlSession物件,三者依次為建立關係,最終我們要得到的是SqlSession物件,通過SqlSession物件來進項資料的訪問,但每次訪問時都需要編寫建立SqlSession物件的這一系列過程,完成後又要反向依次關閉,使得程式碼有很多的重複。

  因此,我們可以編寫一個工具類,幫我們同一來完成這些操作,每次訪問資料時呼叫工具類來獲取SqlSession物件,完成後用工具類統一來關閉物件。

  在java目錄下建立一個工具包:com.Utils。

  在包中建立工具類:MyBatisUtils.java。

MyBatisUtils.java 詳細資訊如下:

package com.Utils;


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.IOException;
import java.io.InputStream;

/**
 * 1. 載入配置
 * 2. 建立SqlSessionFactory
 * 3. 建立Session
 * 4. 事務管理
 * 5. Mapper獲取
 */
public class MyBatisUtils {

    // 獲取SqlSessionFactory
    private static SqlSessionFactory factory;

    //建立ThreadLocal繫結當前執行緒中的SqlSession物件
    private static final ThreadLocal<SqlSession> t1 = new ThreadLocal<SqlSession>();

    //載入配置資訊,並構建session工廠
    static{
        try {
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 獲取連線(從 t1 中獲取當前執行緒SqlSession)
    private static SqlSession openSession(){
        SqlSession session = t1.get();
        if (session == null){
            session = factory.openSession();
            t1.set(session);
        }
        return session;
    }

    // 獲取連線(新建立的)
    public static SqlSession getSession(){
        return factory.openSession();
    }

    // 釋放連線(釋放當前執行緒中的SqlSession)
    public static void closeSession(){
        SqlSession sqlSession = t1.get();
        sqlSession.close();
    }

    // 提交事務(提交當前執行緒中的SqlSession所管理的事務)
    public static void commit(){
        SqlSession sqlSession = openSession();
        sqlSession.commit();
        closeSession();
    }

    // 回滾事務(回滾當前執行緒中SqlSession所管理的事務)
    public static void rollback(){
        SqlSession sqlSession = openSession();
        sqlSession.rollback();
        closeSession();
    }

    // 獲取介面實現類物件
    public static <T> T getMapper(Class<T> mapper){
        SqlSession sqlSession = openSession();
        return sqlSession.getMapper(mapper);
    }
}

 


編寫測試類

  在test目錄下的java目錄下建立測試類包:com.Test,並建立測試類test.java。

編寫測試類:

package com.Test;

import com.Utils.MyBatisUtils;
import com.Dao.UserDao;
import com.entity.User;
import org.junit.Before;

import java.util.Date;
import java.util.List;

public class Test {
    UserDao userDao;

    @Before
    public void init(){
        userDao = MyBatisUtils.getMapper(UserDao.class);
    }

    // 測試查詢全部
    @org.junit.Test
    public void TestQueryAll(){
        List<User> users = userDao.queryAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

    // 測試通過id查詢
    @org.junit.Test
    public void TestselectUserById(){
        User user = userDao.selectUserById(2);
        System.out.println(user);
    }

    // 測試模糊查詢
    @org.junit.Test
    public void TestselectUserByKeyword(){
        List<User> users = userDao.selectUserByKeyword("明");
        for (User user : users) {
            System.out.println(user);
        }
    }

    // 測試插入
    @org.junit.Test
    public void TestinsertUser(){
        User user = new User(null, "辰東", "123472", "男", new Date(), new Date());
        userDao.insertUser(user);
        MyBatisUtils.commit();
        System.out.println("剛插入的使用者id為:" + user.getId());
    }

    // 測試刪除
    @org.junit.Test
    public void TestdeleteUser(){
        userDao.deleteUser(15);
        MyBatisUtils.commit();
    }

    // 測試修改
    @org.junit.Test
    public void TestupdateUser(){
        User user = new User(14, "辰南", "888888", "男", new Date(), new Date());
        userDao.updateUser(user);
        MyBatisUtils.commit();
    }
}

執行TestQueryAll方法,結果如下:

  一個簡單的MyBatis專案搭建完畢。除了上述的這些點之外,還有許多的知識點,如快取、動態SQL、註解、級聯等等,後面有時間了,我會進一步整理。

  感謝大家的耐心閱讀,如有不足,請多多指教!☺

 

相關文章