寫文章 MyBatis筆記一:GettingStart

1.MyBatis優勢


bb49753d36ac6766e45f6b93f1fc7544.jpeg


咱們的工具和各類框架的做用就是爲了咱們操做數據庫簡潔,對於一些數據庫的工具能幫咱們少寫一些處理異常等等的代碼,可是他們並非自動化的,不少的操做仍是須要咱們本身進行,因此咱們的框架就幫咱們把中間黑色的部分封裝起來了,減小咱們的負擔,可是SQL也是重中之重,咱們須要把這些東西本身來控制就有 MyBatis 這個半自動框架,以及咱們須要學習更多的關於 HQL 的內容。<!--more-->java

相對於Hibernate 他的優勢就是能夠進行SQL 的定製化,能讓咱們的SQL更加優化,雖然 Hibernate 也能夠這麼作可是有一點就是咱們須要在原來的框架的基礎上學習更多的 HQL 相關的東西,加劇學習負擔。mysql

2.Getting Start

1.引入依賴

首先咱們須要創建一個新的工程,第一步就是進入 MyBatis 的依賴,固然也少不了數據庫的依賴,這裏咱們爲了方便實體類的編寫咱們還加上了 Lombok ,以及log4j :spring

  <dependencies>
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.4.5</version>
      </dependency>
      
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.35</version>
      </dependency>
  
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.16.20</version>
          <scope>provided</scope>
      </dependency>
      <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
      </dependency>
  </dependencies>

2.編寫配置文件

須要在類路徑下編寫配置文件:sql

  <?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>
      <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:///spring_data"/>
                  <property name="username" value="root"/>
                  <property name="password" value=""/>
              </dataSource>
          </environment>
      </environments>
  </configuration>


2.log4j配置文件

  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
  
  <log4j:configuration>
  
      <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
          <layout class="org.apache.log4j.PatternLayout">
              <param name="ConversionPattern"
                     value="[%d{dd HH:mm:ss,SSS\} %-5p] [%t] %c{2\} - %m%n" />
          </layout>
          <!--過濾器設置輸出的級別-->
          <filter class="org.apache.log4j.varia.LevelRangeFilter">
              <param name="levelMin" value="debug" />
              <param name="levelMax" value="warn" />
              <param name="AcceptOnMatch" value="true" />
          </filter>
      </appender>
  
      <appender name="myFile" class="org.apache.log4j.RollingFileAppender">
          <param name="File" value="D:/output.log" /><!-- 設置日誌輸出文件名 -->
          <!-- 設置是否在從新啓動服務時,在原有日誌的基礎添加新日誌 -->
          <param name="Append" value="true" />
          <param name="MaxBackupIndex" value="10" />
          <layout class="org.apache.log4j.PatternLayout">
              <param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
          </layout>
      </appender>
  
      <appender name="activexAppender" class="org.apache.log4j.DailyRollingFileAppender">
          <param name="File" value="E:/activex.log" />
          <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
          <layout class="org.apache.log4j.PatternLayout">
              <param name="ConversionPattern"
                     value="[%d{MMdd HH:mm:ss SSS\} %-5p] [%t] %c{3\} - %m%n" />
          </layout>
      </appender>
  
      <!-- 指定logger的設置,additivity指示是否遵循缺省的繼承機制-->
      <logger name="com.runway.bssp.activeXdemo" additivity="false">
          <appender-ref ref="activexAppender" />
      </logger>
  
      <!-- 根logger的設置-->
      <root>
          <priority value ="debug"/>
          <appender-ref ref="myConsole"/>
          <appender-ref ref="myFile"/>
      </root>
  </log4j:configuration>

3.編寫實體類

  package lwen.entries;
  
  import lombok.AllArgsConstructor;
  import lombok.Data;
  import lombok.NoArgsConstructor;
  import lombok.experimental.Accessors;
  
  @Data
  @NoArgsConstructor
  @AllArgsConstructor
  @Accessors(chain = true)
  public class Employee {
      private int id;
      private String name;
      private int age;
  }

4.編寫測試類

  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.Test;
  
  import java.io.IOException;
  import java.io.InputStream;
  
  public class GettingStart {
      @Test
      public void sessionFactoryTest() throws IOException {
          String resource = "mybatis.xml";
          InputStream stream = Resources.getResourceAsStream(resource);
          SqlSession sqlSession = null;
         try {
             //獲取sql工廠             SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);
             //獲取sql session             sqlSession = sessionFactory.openSession();
  
             // 1.sql標識 2.綁定的參數             Object employee = sqlSession.selectOne("selectOneEmployee", 3);
             System.out.println(employee);
         }finally {
             if (sqlSession != null) {
                 sqlSession.close();
             }
         }
  
      }
  }

5.編寫mapper文件

  <?xml version="1.0" encoding="UTF-8" ?>
  <!DOCTYPE mapper          PUBLIC " -//mybatis.org//DTD Mapper 3.e//EN"          "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
  <mapper namespace="org.mybatis.example.BlogMapper">
      <select id="selectOneEmployee" resultType="lwen.entries.Employee">
        select * from employee where id=#{id}      </select>
  </mapper>

注意這裏其實咱們的mapper和測試類裏的參數必須是須要匹配的才行。好比咱們的 id 就是咱們的測試類中的 select 方法須要傳的參數,而後咱們的 resultType 就是一個實體類的具體路徑。數據庫

6.總結基本套路

  1. 根據xml配置文件(全局配置文件)建立一個Sq1SessionFactory對象,xml是用來配置數據源一些運行環境信息
  2. sql映射文件:配置了每個sql,以及sql的封裝規則等。
  3. 將sq1映射文件註冊在全局配置文件中
  4. 寫Java代碼:
    1)、根據全局置文件獲得Sq1SessionFactory;2)、使用sqlSession工廠,獲取到sqlSession對象使用他來執行增改查,一個sqlSession就是表明和數據庫的一次會話,用完關閉3)、使用sql的惟一標誌來告訴MyBatis執行哪一個sql,語句都是保存在Sql映射文件中的。

上面咱們使用的方式是之前比較老的方式,如今再也不使用那種方式了,咱們如今都是面向的接口編程的,因此咱們使用Mapper 類來完成數據庫訪問。apache

3.面向接口編程

1.編寫接口Mapper

建立一個mapper接口,而後裏面寫方法便可:編程

  package lwen.dao;
  
  import lwen.entries.Employee;
  
  public interface EmployeeMapper {
      public Employee getEmployeeById(Integer id);
  }

能夠看到就是這麼簡單,可是咱們一開始是經過方法的參數和咱們的 xml 的查詢語句連接起來的,這裏咱們又怎麼作這個映射關係呢?其實就是須要在咱們的 xml 中配置咱們的 這個Mapper 的路徑,以及咱們的方法做爲查詢語句的 id 屬性,還有返回值類型,等等。接下來就來看這些配置。安全

2.配置Mapper.xml

接下來就是配置咱們的 mapper 的xml了,讓他和咱們的接口掛鉤。session

  <?xml version="1.0" encoding="UTF-8" ?>
  <!DOCTYPE mapper          PUBLIC " -//mybatis.org//DTD Mapper 3.e//EN"          "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
  <mapper namespace="lwen.dao.EmployeeMapper">
      <select id="getEmployeeById" resultType="lwen.entries.Employee">
        select * from employee where id=#{id}      </select>
  </mapper>

注意事項:mybatis

  1. 第一點就是咱們的 namespace 之前事隨便寫,可是這個地方就是須要咱們和Mapper 接口綁定,也就是咱們的接口的全類名。
  2. 而後就是咱們的id屬性,就是咱們的Mapper的方法名。
  3. 還有一點疑問就是咱們的參數,咱們都沒傳,其實這裏他作了默認綁定,參數名和這裏的sql模板參數名一致就行。

3.測試類

  @Test
  public void InterfaceMapperTest() throws IOException {
      String resource = "mybatis.xml";
      InputStream stream = Resources.getResourceAsStream(resource);
      SqlSession sqlSession = null;
     try {
         //獲取sql工廠         SqlSessionFactory sessionFactory = getSessionFactory("mybatis.xml");
         //獲取sql session         sqlSession = sessionFactory.openSession();
  
         // 獲取 mapper 接口的實例對象         EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
         //直接調用的 mapper 裏的方法         System.out.println(employeeMapper.getEmployeeById(3));
  
     }finally {
         if (sqlSession != null) {
             sqlSession.close();
         }
     }
  
  }

4.一個神奇的點

這裏咱們會發現咱們根本沒有寫接口的實現類,咱們怎麼獲取到咱們的 Mapper 的對象,而且還能夠調用他的方法呢?實際上咱們去打印一下咱們使用sqlSession.getMapper(EmployeeMapper.class) 這句話獲取到咱們的對象,而且能執行相應的操做呢?

咱們打印出來這個對象咱們就會發現,獲取到的對象其實是一個代理對象,那麼也就是說咱們 Mybatis 底層採用的代理方式作的具體的功能。

其實咱們經過SqlSession.getMapper(XXXMapper.class) 方法,MyBatis 會根據相應的接口聲明的方法信息,經過動態代理機制生成一個Mapper 實例,咱們使用Mapper 接口的某一個方法時,MyBatis 會根據這個方法的方法名和參數類型,肯定Statement Id,底層仍是經過SqlSession.select("statementId",parameterObject);或者SqlSession.update("statementId",parameterObject); 等等來實現對數據庫的操做,(至於這裏的動態機制是怎樣實現的,我想專門用一篇文章來討論)

MyBatis 引用 Mapper 接口這種調用方式,純粹是爲了知足面向接口編程的須要。(其實還有一個緣由是在於,面向接口的編程,使得用戶在接口上可使用註解來配置SQL語句,這樣就能夠脫離XML配置文件,實現「0配置」)。 由於面向接口編程其實有很是多的好處。由於如今咱們的 dao 代碼就是咱們的 mapper 接口了,可是若是有一天咱們但願不採用 MyBatis 來作數據訪問了,咱們在底層就能夠直接寫對應的實現類使用 Hibernate 等等其餘框架來頂替,也是一件很容易的事。

4.總結

  1. SqlSession表明和數據庫的一次會話:用完必須關閉,這也是一個資源,因此咱們用完了必須進行關閉操做,避免數據庫沒必要要的問題。
  2. SqlSession和connection同樣都是非線程安全,每次使用都應該去獲取新的對象,不能夠看成一個成員變量 ,否則天然會致使紊亂,也就是咱們須要把他放在一個局部方法中,用完關閉。其實說清楚點他的底層就是 connection。
  3. mapper接口沒有實現類,可是mybatis會爲這個接口生成一個代理對象。(將接口和xml進行綁定)
  4. 兩個重要的配置文件:
    1. mybatis的全局配置文件:包含數據庫鏈接池信息,事務管理器信息等。。。系統運行環境信息
    2. sql映射文件:保存了每個sq1語句的映射信息:將sql抽取出來。


編輯於 2018-06-01

相關文章
相關標籤/搜索