1. 程式人生 > 實用技巧 >MyBatis框架介紹以及快速入門

MyBatis框架介紹以及快速入門

MyBatis框架

今日學習內容目標

  • 能夠了解什麼是框架
  • 理解自定義Mybatis框架
  • 掌握Mybatis框架開發快速入門

第一節 認識框架

1.介紹

框架就是一個架子,表演節目,舞臺已經搭建好,表演什麼節目,看自己的需求了。

框架是一個半成品,對於Java語言來說,框架就是封裝了別人的程式碼。在框架的基礎上我們在進一步開發,拿來用。

2.解決的問題

解決的是技術整合問題。軟體開發環境和規模都很大,不可能任何一個專案的程式碼都從零開始,此時就需要一個非常優秀的框架把基礎技術整合完畢,我們在他的基礎上進一步開發。提高效能,易擴充套件,易維護,最終提高整個團隊的開發效率。

3.使用框架

企業級大型專案開發用框架,避免大炮打蚊子。

Java的框架是具有一些共性

  • 匯入jar包
  • 框架執行細節定義,也就是編寫配置檔案(xml)
  • 呼叫框架中的api

第二節 原生JDBC案例

  • 查詢user表
  • 以List集合形式返回
  • 編寫pojo類 (User)
    • domain,pojo本質都是相同的

1.JdbcDemo類

/**
 * 原始的JDBC,對資料表user查詢,結果集儲存List集合
 * */
public class JdbcDemo {
    public static void main(String[] args) throws Exception {
        // 註冊驅動
        Class.forName("com.mysql.jdbc.Driver");
        // 獲取連線
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis","root","root");
        // SQL語句執行物件
        PreparedStatement pst = con.prepareStatement("select * from user");
        // 執行查詢,返回結果集
        ResultSet rs = pst.executeQuery();
        List<User> userList = new ArrayList<User>();
        while (rs.next()){
            User user = new User();
            // 取出表中資料,rs物件的方法getXXX()
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("username"));
            user.setSex(rs.getString("sex"));
            user.setBirthday(rs.getDate("birthday"));
            user.setAddress(rs.getString("address"));
            userList.add(user);
        }

        for (User user : userList){
            System.out.println(user);
        }

        rs.close();
        pst.close();
        con.close();

    }
}

2.User類

// 和資料庫中的鍵對照
public class User {
    private int id;
    private String username;
    private String sex;
    private Date birthday;
    private String address;

    public int getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    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 String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

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

3.原始的JDBC的缺陷

原始程式問題:維護性差,擴充套件性差,出現問題,修改原始碼,程式碼量大

  1. 頻繁連線,釋放資料庫資源,降低系統性能
    • 解決辦法:連線池
  2. 資料庫驅動類,連線四大資訊
    • 解決辦法:寫配置檔案,讀取
  3. SQL語句硬編碼,SQL語句寫死了 SQL語句中的 ? 佔位符
    • 解決辦法:寫配置檔案,讀取
  4. 封裝資料表結果集程式碼,硬編碼
    • 引出連線池,Apache DBUtils

4.框架

框架:最基本的程式碼,整合起來

連線資料庫,執行SQL語句,封裝結果集整合

只要提供:SQL語句,寫xml中

第三節 MyBatis框架

1.歷史

Mybatis原本是Apache軟體基金會的一個開源專案叫做iBatis,2010年這個專案由Apache遷移到了google code管理才改名為Mybatis,2013年又遷移到了GitHub。

2.介紹

Mybatis是一個優秀的持久層框架(Dao層框架),它是對JDBC的封裝,使得開發者只需要關注Sql語句(業務)本身即可,無需開發者處理載驅動、獲取連線、建立Statement等繁瑣的過程。

3.原理

Mybatis最大的特點是把Sql語句寫在XML配置檔案當中。而且Mybatis執行完Sql語句之後可以以物件形式返回(POJO/POJO集合等)。

思想

Mybatis是一個實現了ORM思想的持久層框架。

ORM:Object/Relation Mapping 物件/關係對映。

ORM思想:將資料庫中的關係資料表對映為JAVA中的物件,把對資料表的操作轉換為對物件的操作,實現面向物件程式設計。因此ORM的目的是使得開發人員以面向物件的思想來操作資料庫。

比如:原來insert使用的是insert into…,如果使用實現了ORM思想的持久層框架,就可以在Java程式中直接呼叫api,比如insert(User),達到操作物件即操作資料庫的效果。Hibernate框架是一個全自動的ORM持久層框架,只需要編寫POJO,在xml中定義好Pojo屬性和資料表字段的對映/對應關係,就可以在java中實現類似 insert(User)的操作。Sql語句都不用寫。但是因為效能等問題,市場佔有率越來越低

4.半自動ORM持久層框架

Mybatis框架是一個半自動的ORM持久層框架,也可以在Java中實現類似 insert(User)的操作最終操作資料庫,但是需要我們自己寫Sql語句。Mybatis是目前比較流行的Dao層框架。

第四節 自定義MyBatis框架

1.目的

  • 感受一個框架的生產過程,通過這個過程幫助我們瞭解底層的一些東西,提高競爭力(軟實力)

  • 注意

    • 完整性和嚴謹性不能和真實的相比
    • 今天的課程依然有難度
    • 不影響真正Mybatis框架的使用
  • 所有的Dao層框架都是以介面的形式給我們提供增刪改查的API

  • 我們今天自定義Mybatis框架只完成一個API介面:selectList

2.流程

MyBatis框架的使用流程

3.快速入門

需求:查詢user表,資料儲存到List集合

4.實現步驟

  1. 建立物件 SqlSessionFactoryBuilder (SQL會話工廠建設者) 讀取配置檔案SqlSessionFactory

    方法build(輸入流) 只需要繫結主文配置檔案

    工廠的構造者物件,作用建立SQLSession物件工廠的

  2. SqlSessionFactory 工廠建立

    創SqlSession介面實現類物件

  3. SqlSession介面實現類物件

    方法,執行SQL語句

    呼叫方法 select 查詢資料表

  4. 輸出查詢結果集

  5. 釋放資源

示例程式碼

步驟:

  • 匯入MyBatis框架jar包
  • 配置檔案
  • SqlSessionFactoryBuilder,傳入位元組輸入流,構建工廠
  • SqlSessionFactory,建立SqlSession
  • SqlSession執行selectList方法查詢資料

匯入jar包和SqlMapConfig.xml以及UserMapper.xml配置檔案

建立pojo資料夾 放user類

public class User {
    private int id;
    private String username;
    private String sex;
    private Date birthday;
    private String address;
    // getXXX和SetXXX以及toString方法省略
}

建QuickStart類

public void MyBatisQuickStart(){
        // 1.建立物件  SqlSessionFactory
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 使用SQLSessionFactoryBuilder方法 build(),創建出SqlSessionFactory物件
        // build方法,讀取配置檔案,返回SqlSessionFactory物件,需要傳遞流物件,流物件繫結資料庫配置檔案
        InputStream inputStream = QuickStart.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
        // 2.SqlSessionFactory  工廠建立
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        // 工廠物件,獲取SqlSession介面實現類物件,工廠物件的方法openSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.SqlSession介面實現類物件,呼叫方法select 查詢資料表
        // selectList方法引數不是SQL語句, namespace+"."+id 鎖定SQL語句  test.queryList 在SqlMapConfig.xml配置檔案中
        List<User> userList = sqlSession.selectList("test.queryList");
        for (User user :userList){
            System.out.println(user);
        }
        sqlSession.close();
    }

第五節 Java中的日誌元件

#log4j日誌級別如下:
#A:off     最高等級,用於關閉所有日誌記錄。
#B:fatal   指出每個嚴重的錯誤事件將會導致應用程式的退出。
#C:error   指出雖然發生錯誤事件,但仍然不影響系統的繼續執行。
#D:warn    表明會出現潛在的錯誤情形。
#E:info    一般和在粗粒度級別上,強調應用程式的執行全程。
#F:debug   一般用於細粒度級別上,對除錯應用程式非常有幫助。
#G:all     最低等級,用於開啟所有日誌記錄。

#但log4j只建議使用4個級別,優先順序從高到低分別是:
#error>warn>info>debug

log4j.rootLogger =debug,systemOut,logFile

#輸出到控制檯
log4j.appender.systemOut = org.apache.log4j.ConsoleAppender
log4j.appender.systemOut.layout = org.apache.log4j.PatternLayout
log4j.appender.systemOut.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n
log4j.appender.systemOut.Target = System.out

#輸出到檔案
log4j.appender.logFile = org.apache.log4j.FileAppender
log4j.appender.logFile.layout = org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n
log4j.appender.logFile.File = E:/log/log4j.log
log4j.appender.logFile.Encoding = UTF-8

#將日誌輸記錄到MySQL資料庫
#log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender
#log4j.appender.logDB.layout = org.apache.log4j.PatternLayout
#log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
#log4j.appender.logDB.URL = jdbc:mysql://localhost:3306/log4j?characterEncoding=utf-8
#log4j.appender.logDB.User = root
#log4j.appender.logDB.Password = root
#log4j.appender.logDB.Sql = INSERT INTO t_log4j(project_name,create_date,level,category,file_name,thread_name,line,all_category,message)values('mybatis','%d{yyyy-MM-ddHH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')

第六節 MyBatis配置檔案詳解

1.SqlMapperConfig.xml

enviroments配置資料來源環境 執行環境 可配置多個

default = "development" 預設,值 = development 開發環境

  • default資料來源開關

  • environment具體資料來源環境,可以配置多個

    id 不同作用不同

    • id = "development" id 唯一的屬性 值=id = "development" 開發環境
    • id = "product" 生產環境 互動給使用者使用
    • id = "test" 測試環境 例如測試員測試
  • transactionManager事務管理器

  • datasource資料來源

<!--配置-->
<configuration>
    <!--配置資料來源環境資訊-->
    <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://127.0.0.1:3306/test?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>

        <!--測試環境資料來源 -->
        <environment id="test">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>

        <!-- 生產環境資料來源-->
        <environment id="produce">
            <!--
               事務管理器
               type="JDBC" 當前MyBatis事務管理,使用的是JDBC的事務
               Connection介面方法 commit rollback
               type="MANAGERED" 不管理事務,交給其他框架管理
            -->
            <transactionManager type="JDBC" />
            <!--
                資料來源
                type="POOLED" 使用資料庫連線池
                type="UNPOOLED" 不使用連線池
            -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="UserMapper.xml" />
    </mappers>
</configuration>    

2.MyBatis框架的CRUD

1.根據id查詢使用者

  • SqlMapperConfig.xml
<mappers>
    <!-- 配置User表SQL語句 -->
    <mapper resource="sqlmapper/UserMapper.xml" />
</mappers>
  • UserMapper.xml配置
<mapper namespace="test">
   <!--
        test+.+id 鎖定唯一SQL語句
        resultType 結果集封裝型別
        parameterType 引數的資料型別
        SQL語句中的取引數語法 #{基本型別 任意命名}
    -->
   <select id="queryUserById" parameterType="Integer" resultType="com.itheima.pojo.User">
      select * from user where id=#{id}
</select>
</mapper>
  • 實現步驟

    • Resources獲取位元組輸入流,繫結配置檔案
    • SqlSessionFactoryBuilder構建工廠
    • SqlSessionFactory建立SqlSession物件
    • SqlSession物件方法selectOne執行查詢
public class MyBatisCRUD {
    /**
     * 框架:查詢資料表user,根據主鍵查詢
     * */
    public static void main(String[] args) throws IOException {
        testQueryUserById();
    }
    public static void testQueryUserById() throws IOException {
        // 1.SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // MyBatis框架提供類,Resource靜態方法  getResourceAsStream()  底層封裝的就是載入器,中的流
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        // 2.建立SqlSession介面的實現類物件
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.方法,執行SQL語句
        // selectOne(namespace +"."+id 鎖定唯一SQL)方法,查詢結果一個物件
        User user = sqlSession.selectOne("test.queryUserById",3);
        System.out.println(user);
        sqlSession.close();
    }
}

配置UserMapper.xml

<!--
           配置,主鍵查詢的SQL語句,標籤 select
           id具有唯一性
           查詢是有結果集
              標籤中屬性 resultType:配置結果集的型別
           SQL語句有引數的
              標籤中屬性 parameterType:SQL語句的引數型別
        -->
    <select id="queryUserById" resultType="com.zhuxu.pojo.User" parameterType="Integer">
        <!--
          SQL語句
          MyBatis配置SQL語句,引數不能寫問好
          取引數 #{引數名}
          引數名,如果只有一個引數,基本型別及其包裝類和String,任意
        -->
        select * from user where id = #{id}
    </select>

2.根據使用者名稱模糊查詢

框架:查詢資料表user,根據使用者名稱模糊查詢
大量的重複性程式碼:程式碼壞味道
共性抽取:
目的:SqlSession介面,執行SQL語句
每個功能不同的,SqlSession介面不能抽取

讀取配置檔案可以抽取
SqlSessionFactory sqlSessionFactory 建立SqlSession介面物件,可以抽取
工廠物件,提升為成員變數

public class MyBatisCRUD {

    /**
     * 框架:查詢資料表user,根據使用者名稱模糊查詢
     * 大量的重複性程式碼:程式碼壞味道
     * 共性抽取:
     *    目的:SqlSession介面,執行SQL語句
     *      每個功能不同的,SqlSession介面不能抽取
     *
     *      讀取配置檔案可以抽取
     *      SqlSessionFactory sqlSessionFactory  建立SqlSession介面物件,可以抽取
     *      工廠物件,提升為成員變數
     * */


    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void before() throws IOException {
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }

    
    // 框架:查詢資料表user,根據使用者名稱模糊查詢
    @Test
    public void testQueryUsername() throws IOException{
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> userList = sqlSession.selectList("test.queryUserByUsername", "'%王%'");
        for (User user : userList){
            System.out.println(user);
        }
        sqlSession.close();
    }

    /**
     * 框架:查詢資料表user,根據主鍵查詢
     * */

    @Test
    public void testQueryUserById() throws IOException {
        /*// 1.SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // MyBatis框架提供類,Resource靜態方法  getResourceAsStream()  底層封裝的就是載入器,中的流
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);*/
        // 2.建立SqlSession介面的實現類物件
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.方法,執行SQL語句
        // selectOne(namespace +"."+id 鎖定唯一SQL)方法,查詢結果一個物件
        User user = sqlSession.selectOne("test.queryUserById",3);
        System.out.println(user);
        sqlSession.close();
    }
}

UserMapper.xml配置檔案

<mapper namespace="test">

    <!--
        配置,資料表user模糊查詢
        使用者名稱模糊查詢
        SQL語句引數
        ${引數名} 寫引數名字固定寫為value
    -->
    <select id="queryUserByUsername" resultType="com.zhuxu.pojo.User" parameterType="String">
        select * from user where username like ${value}
    </select>

3.#{}和${} 獲取引數的區別

能用#{}不用${}

使用#的原理是 引數編譯為 ? 佔位符,更快更高效,框架底層使用的是JDBC中的介面 PreparedStatement

$的原理是拼接方式

select * from user where username like #{value}
--運算時為
select * from user where username like ? '%王%'

select * from user where username like ${value}
--運算時為
select * from user where username like '%王%'

4.新增使用者

使用子標籤

selectKey 標籤體中會在執行一次SQL語句

新增操作:insert標籤中,子標籤 獲取上一次新增主鍵值
屬性:
order = "after或者before" 獲取主鍵,是在SQL語句之前,還是之後執行
resultType 獲取逐漸的結果資料型別
keyProperty 屬性,查詢後的值放在哪裡 pojo物件的屬性中

<selectKey order="AFTER" resultType="Integer" keyProperty="id">
    <!--新增資料獲取最新的主鍵-->
    select last_insert_id ()
</selectKey>

5.修改和刪除使用者

修改

實現步驟

  • Resources獲取位元組輸入流,繫結配置檔案
  • SqlSessionFactoryBuilder構建工廠
  • SqlSessionFactory建立SqlSession物件
  • SqlSession物件方法update | delete 更新資料
  • 提交事務

UserMapper.xml配置檔案中

<!--
        配置更新資料,標籤update  修改資料
    -->
    <update id="updateUserById" parameterType="com.zhuxu.pojo.User">
        update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id = #{id}
    </update>

<!--
        配置刪除資料
    -->
    <delete id="deleteUserById" parameterType="Integer">
        delete from user where id = #{id}
    </delete>

java類

private SqlSessionFactory sqlSessionFactory;
    @Before
    public void before() throws IOException {
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }

    @Test
    /*實現更新資料*/
    public void testUpdateUserById(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = new User();
        user.setId(7);// 要修改的主鍵
        user.setUsername("大橋");
        user.setSex("女");
        user.setBirthday(new Date(0));
        user.setAddress("益州");

        int row = sqlSession.update("test.updateUserById", user);
        sqlSession.commit();
        System.out.println(row);
        sqlSession.close();
    }

// 刪除資料
@Test
    public void testDeleteUserById(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        int row = sqlSession.delete("test.deleteUserById", 7);
        sqlSession.commit();
        sqlSession.close();
        System.out.println(row);
    }

6.原始dao層開發方式

  • 實現步驟
    • 定義dao層介面
    • 定義dao層介面實現類
public interface UserDao {
    User queryUserById(Integer id);
}
public class UserDaoImpl implements  UserDao {
    private SqlSessionFactory sqlSessionFactory;

    public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User queryUserById(Integer id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("test.queryUserById", id);
        sqlSession.close();
        return user;
    }
}
@Test
public void userTest() throws IOException {
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    UserDao userDao = new UserDaoImpl(sqlSessionFactory);
    User user = userDao.queryUserById(1);
    System.out.println(user);
}

7.動態代理技術

原理:

利用反射技術

不修改原始碼的情況下,增強功能

java.lang.reflect.Proxy 動態代理類

定義一個Mapper介面,這個介面其實和我們UserDao介面是一樣的,從Mybatis框架中拿到一個代理物件(代理的是這個Mapper介面),通過代理物件呼叫介面當中的方法完成業務。
傳統dao開發方式中的實現類其實起了一個連線、承上啟下的作用,連線了介面和xml對映檔案,效果就是呼叫介面方法時能夠找到xml對映檔案。

  • Mapper動態代理開發遵從的規範
    • sql對映檔案的namespace必須和mapper介面的全限定類名保持一致
    • mapper介面的介面方法名必須和xml中的sql語句id保持一致
    • mapper介面的介面方法形參型別必須和sql語句的輸入引數型別保持一致
    • mapper介面的介面方法返回型別必須和sql語句的resultType保持一致

小結

MyBatis動態代理開發(以後都是用的方式)簡化開發

限制:

  1. dao層包名,修改為mapper

    定義介面 UserMapper,查詢所有資料的方法(抽象)

    MyBatis框架,自動為我們生成介面實現類物件

  2. UserMa.xml配置檔案,配置的是user表下的SQL語句

    配置檔案,必須和介面在同一目錄下

  3. 配置檔案中的屬性 namespace的屬性值必須和介面的全類名一致

  4. 介面中的方法名,必須和SQL語句標籤的id值相同

    引數和返回值都必須相同

  5. XXXMapper.xml配置檔案的路徑不要寫錯

示例程式碼:

SqlMapConfig.xml配置檔案

<mappers>
        <!--
            路徑寫法:動態代理開發
            配置檔案xml和介面在一個目錄下
        -->
        <mapper resource="com/zhuxu/mapper/UserMapper.xml" />
</mappers>

UserMapper.xml配置檔案

<mapper namespace="com.zhuxu.mapper.UserMapper">

    <!--配置查詢所有的user表資料-->
    <select id="queryUser" resultType="com.zhuxu.pojo.User">
            select * from user
    </select>
</mapper>

UserMapper介面

public interface UserMaper{
     /**
     * 查詢所有資料表user的介面
     * */
    List<User> queryUser();
}

實現類

public class MyBatisProxy {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void before() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }

    @Test
    /*
    * 動態代理方式,代理的是mapper包下的介面
    * */
    public void testQueryUser(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // SqlSession介面的方法  getMapper()
        /*
        * 引數是代理的介面的class檔案物件
        * 返回值就是代理介面的實現類物件
        *
        * UserMapper介面的實現類
        * */
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.queryUser();
        for (User user:userList){
            System.out.println(user);
        }
        sqlSession.close();
    }


}

1.主鍵查詢

UserMapper.xml配置檔案

    <!--配置主鍵查詢-->
    <select id="queryUserById" parameterType="Integer" resultType="com.zhuxu.pojo.User">
        select * from user where id = #{id}
    </select>

UserMapper介面

public interface UserMaper{
     /**
     * 根據主鍵查詢
     * */
    User queryUserById(Integer id);
    
}

實現類

/**
     * 動態代理方式,代理mapper包下的介面
     * 主鍵查詢
     * */
    @Test
    public void testQueryById(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.queryUserById(6);
        System.out.println(user);
        sqlSession.close();
    }

2.新增資料

注意 使用註解開發不需要寫UserMapper.xml配置檔案

UserMapper.xml配置檔案

	<!--配置新增-->
    <insert id="saveUser" parameterType="com.zhuxu.pojo.User">
        insert into user values (null ,#{username},#{sex},#{birthday},#{address})
    </insert>

UserMapper介面

public interface UserMaper{
     /**
     * 新增資料
     * */
    // 註解開發
    // @Insert("insert into user values (#{id} ,#{username},#{sex},#{birthday},#{address})")
    
    int saveUser(User user);
    
}

實現類

/**
     * 動態代理方式,代理mapper包下的介面
     * 新增資料
     * */
    @Test
    public void testSaveUser(){
        User user = new User();
        user.setId(7);
        user.setUsername("安琪拉");
        user.setSex("女");
        user.setAddress("中國");
        user.setBirthday(new Date());

        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int row = userMapper.saveUser(user);
        sqlSession.commit();
        System.out.println(row);
        sqlSession.close();

    }

7.全域性properties配置

配置標籤,引用外部的properties檔案

實用價值不大

db.properties配置檔案

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

SqlMapConfig.xml配置檔案

<environment id="development">
    <transactionManager type="JDBC" />
    <dataSource type="POOLED">
        <property name="driver" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </dataSource>
</environment>

8.全域性typeAliases配置

別名 對映的型別
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
map Map

結果集資料型別定義別名,別名不區分大小寫

<typeAliases>
    <!-- 為pojo物件定義別名-->
    <typeAlias type="com.itheima.pojo.User" alias="user"></typeAlias>
</typeAliases>
<!-- 使用別名即可-->
<select id="queryUserById" parameterType="int" resultType="User">
   select * from user where id=#{id}
</select>

掃描所有pojo包下的類。注意:不可以出現相同的類名

<typeAliases>
    <!--<typeAlias type="com.itheima.pojo.User" alias="user"></typeAlias>-->
    <!-- 自動掃描pojo包下的全部類-->
    <package name="com.itheima.pojo" ></package>
</typeAliases>

9.全域性配置檔案mappers

  • mappers註冊sql對映檔案的
    • resource屬性載入sql對映檔案,萬能型選手(crud、原始dao、mapper動態代理)
    • 針對Mapper動態代理進行一個增強(增強兩種用法)
    • mapper class 單個註冊
    • package 批量掃描註冊
    • 以上兩種方式有規範要求
<mappers>
        <!--
            路徑寫法:動態代理開發
            配置檔案xml和介面在一個目錄下
        -->
        <!--
            自動掃描配置
            mapper配置的xml檔案的路徑(SQL語句配置檔案)
            一個數據表對應一個xml

            mapper標籤的屬性 resource="xml路徑"
            package標籤的屬性 name= “包名”

            <package name="com.zhuxu.mapper"></package>
            框架自動掃描配置包下的xml檔案
        -->
        <package name="com.zhuxu.mapper"></package>
        <!--<mapper resource="com/zhuxu/mapper/UserMapper.xml" />-->
    </mappers>

10.MyBatis輸入引數型別

pojo包裝型別,一個pojo類中,包含了另一個pojo類。

public class QueryVo {
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}
public interface UserMapper {
    User queryUserById(Integer id);
    List<User> queryUserByQueryVo(QueryVo queryVo);
}
@Test
public void userMapperQueryVo(){
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    QueryVo queryVo = new QueryVo();
    User user = new User();
    user.setUsername("%王%");
    queryVo.setUser(user);
    List<User> list = mapper.queryUserByQueryVo(queryVo);
    for(User u :list){
        System.out.println(u);
    }
    sqlSession.close();
}
<select id="queryUserByQueryVo" resultType="user" parameterType="queryvo">
   select * from user where username like #{user.username}
</select>

11.MyBatis手動對映

OrdersMapper介面

public interface OrdersMapper {
    /**
     * 查詢訂單的全部資料
     */
    List<Orders> queryOrders();
}

配置檔案

<!--屬性值,必須和介面的全類名一致-->
<mapper namespace="com.zhuxu.mapper.OrdersMapper">

    <!--
        配置查詢所有訂單的SQL
        查詢需要使用自己配置的對映
        select  標籤屬性resultMap,屬性值,請寫手動對映標籤resultMap的id值
    -->
    <select id="queryOrders" resultType="orders" resultMap="ordersResultMap">
        select * from orders
    </select>

    <!--
        手動對映,手動配置pojo物件的屬性名和資料表的列名resultMap
        屬性:id=“” 唯一性
        type 結果型別,pojo物件
    -->
    <resultMap id="ordersResultMap" type="orders">
        <!--配置的就是資料表的列和pojo物件成員變數的對應關係-->

        <!--
            id配置的是主鍵
            columns列名
            property pojo 物件屬性名
        -->
        <id column="id" property="id"></id>
        <!--配置其他列-->
        <result column="user_Id" property="userId"></result>
        <result column="number" property="number"></result>
        <result column="createrime" property="createtime"></result>
        <result column="note" property="note"></result>

    </resultMap>

</mapper>

實現類

/**
     * 動態代理,代理的介面是一個OrdersMapper介面
     */
    @Test
    public void testQueryOrders(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
        List<Orders> ordersList = ordersMapper.queryOrders();
        for (int i = 0; i < ordersList.size(); i++) {
            Orders orders = ordersList.get(i);
            System.out.println(orders);
        }
    }