Mybatis在Maven項目中使用


Mybatis概覽

ORM是什么?

ORM是Object Realtion Mapping的縮寫,顧名思義,即對象關系映射。

ORM是一種以面向對象的方式來進行數據庫操作的技術。Web開發中常用的語言,都會有對應的ORM框架,而Mybatis就是Java開發中一種常用的ORM框架。

簡單地理解,通過Java進行數據庫訪問的正常流程可以分為以下幾步:

  1. 准備好SQL語句
  2. 調用JDBC的API傳入SQL語句,設置參數
  3. 解析JDBC返回的結果

這個過程實際上非常麻煩,比如:

  • 在Java代碼中拼接SQL非常麻煩,而且易於出錯
  • JDBC的代碼調用有很多重復性的代碼
  • 從JDBC返回的結果轉換成領域模型的Java對象非常繁瑣

而使用ORM框架,則可以讓我們用面向對象的方式來操作數據庫,比如通過一個簡單的函數就完成上面的流程,直接返回映射為Java對象的結果。這個流程中很大一部分工作就交給ORM自動化幫我們執行了。

Mybatis是支持定制化SQL,存儲過程以及高級映射的優秀持久層框架。MyBatis避免了幾乎所有的JDBC代碼和手動設置參數以及獲取結果集。Mybatis可以對配置和原生Map使用簡單的XML或標注,將接口和Java的POJOS(Plan Old Java Objects,普通的Java對象)映射成數據庫中的記錄。

簡單地理解,你可以認為Mybatis將SQL語句,以及SQL返回結果到Java對象的映射,都放到一個易於配置的XML文件里了,你的Java代碼會變得異常簡單。當然除了XML,Mybatis同時也支持基於標注的方式,但是功能上會有一些限制。總體來說,還是推薦使用XML方式,一些簡單的SQL使用標注會更方便一些。

創建項目

新建一個Maven項目,接下來引入Mybatis和MySQL的依賴:

<!-- mybatis依賴 -->
    <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.0</version>
    </dependency>
    
    <!-- MySQL數據庫依賴 -->
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.6</version>
    </dependency>

既然是ORM的練習,先設計Object,再設計Relation,最后再看怎么做Mapping

實體類設計

分析我們的業務場景,可以設計三個類:

  • Question表示問題
  • Answer表示回答
  • Tag表示問題標簽

其中:

  • Question可以有多個Answer,一個Answer對應唯一一個Question,一對多的關系
  • Question可以有多個Tage,一個Tag可用於多個Question,多對多的關系

暫時先不管Answer和Tag,只關注Question:

Question.java

package com.fpc.Entity;

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

public class Question {
    private int id;
    private String title;
    private String description;
    private Date createdTime;
    private List<Tag> tags;
    private List<Answer> answers;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Date getCreatedTime() {
        return createdTime;
    }
    public void setCreatedTime(Date createdTime) {
        this.createdTime = createdTime;
    }
    public List<Tag> getTags() {
        return tags;
    }
    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }
    public List<Answer> getAnswers() {
        return answers;
    }
    public void setAnswers(List<Answer> answers) {
        this.answers = answers;
    }
    
    
}

這里的Question實現了Serializable接口,實現這個接口是為了后面緩存查詢結果是需要的。

數據庫設計

除了設計Question,Answer和Tag數據表,還需要定義一張維護Question和Tag之間多對多關系的表。最終數據庫設計如下:

創建question表:

CREATE TABLE question(
 id INT PRIMARY KEY AUTO_INCREMENT,
 createdTime DATETIME,
 description LONGTEXT,
 title VARCHAR(255)
);

接下來添加MyBatis的配置,在resources目錄下簡歷mybatis.xml文件:

<?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>
    <!-- 引用db.properties配置文件 -->
    <properties resource="db.properties"></properties>
    <!--
        development:開發模式
        work:工作模式 
     -->
     <typeAliases>
         <!-- <typeAlias type="com.fpc.Entity.User" alias="_User"/> -->
         <package name="com.fpc.Entity"/>
     </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!-- 配置數據庫連接信息 -->
            <dataSource type="POOLED">
                <!-- value屬性值引用db.properties配置文件中配置的值 -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${name}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <!-- 注冊userMapper.xml文件, 
        userMapper.xml位於me.gacl.mapping這個包下,所以resource寫成me/gacl/mapping/userMapper.xml-->
        <mapper resource="com/fpc/Mapping/questionMapper.xml"/>
        <!-- <mapper class="com.fpc.Mapping.questionMapperI"/> -->
    </mappers>
    
</configuration>

這就是一個最簡單的MyBatis配置文件,定義了數據源和mapper文件的位置。

關於MyBatis配置:

后面會發現有了Spring和SpringBoot支持,很多配置不需要手動設置了,比如映射文件的位置,數據源和事務管理器等,這個文件需要的內容非常少,甚至可以不需要這個文件了。

需要修改MyBatis配置文件的幾種常用的情況包括:

  • 要增加插件,比如后面需要用到的分頁插件
  • 修改MyBatis的運行時行為,參考settings選項
  • 重寫類型處理器或創建自定義的類型處理器來處理非標准類型。

定義Mapper接口

Mapper的Java接口,這是數據庫訪問的接口:

package com.fpc.Mapping;

import org.apache.ibatis.annotations.Param;

import com.fpc.Entity.Question;

public interface questionMapperI {
    Question findOne(@Param("id") int id);
}

@Param是MyBatis提高的一個標注,表示id會解析成SQL語句的參數。

使用XML定義Mapper

對應於Mapper接口,還需要通過XML來給出Mapper的實現,將映射放在com/fpc/Mapping/下

<?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,namespace的值習慣上設置成包名+sql映射文件名,這樣就能夠保證namespace的值是唯一的
例如namespace="me.gacl.mapping.userMapper"就是me.gacl.mapping(包名)+userMapper(userMapper.xml文件去除后綴)
 -->
<mapper namespace="com.fpc.Mapping.questionMapperI">
    <select id="findOne" resultType="com.fpc.Entity.Question">
        select * from question where id = #{id}
    </select>
</mapper>

Mapper的配置是MyBatis的精華,注意兩點:

  • 對應於每一個Mapper的Java接口方法,XML配置中有對應的一個元素來描述其SQL語句
  • resultType元素定義了數據庫返回(一行記錄)如何映射到一個Java對象

使用Mapper

已經有一個可以根據id獲取問題的接口方法了,編寫測試類測試:

package com.fpc.Test;

import java.io.IOException;
import java.io.Reader;

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 com.fpc.Entity.Question;
import com.fpc.Mapping.questionMapperI;

public class TestMybatis {
    public static void main(String[] args) {
        String resource = "mybatis.xml";
        Reader reader;
        try {
            reader = Resources.getResourceAsReader(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            questionMapperI questionMapper = sqlSession.getMapper(questionMapperI.class);
            Question question = questionMapper.findOne(1);
            System.out.println(question.getDescription());
            sqlSession.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
}

把這個main方法運行起來就能看到結果了,調用看起來有點復雜,這里涉及Mybatis的幾個關鍵類:

  • SqlSessionFactoryBuilder
  • SqlSessionFactory
  • SqlSession

其實引入Spring Boot之后,你會發現這幾個類都被屏蔽掉了,你只需專注於寫Mapper即可。不過了解一下這幾個類,對於我們調試程序和理解MyBatis都是大有裨益的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM