1. 程式人生 > >Mybatis - 學習指南一

Mybatis - 學習指南一

網絡 package 執行 節點 nts mat username 地方 事務管理

Mybatis 學習指南1-Hello Mybatis

前言

  • 傳統的 JDBC 代碼存在的問題。

    • 先看看一下傳統 JDBC 開發的代碼

      回顧一下JDBC 開發的步驟:

      1、 加載數據庫驅動

      2、 創建並獲取數據庫鏈接

      3、 創建jdbc statement對象

      4、 設置sql語句

      5、 設置sql語句中的參數(使用preparedStatement)

      6、 通過statement執行sql並獲取結果

      7、 對sql執行結果進行解析處理

      8、 釋放資源(resultSet、preparedstatement、connection)

      // 加載驅動
      Class.forName("com.mysql.jdbc.Driver"); 
      
      // 通過驅動管理類獲取數據庫鏈接
      connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root");
      
      //定義sql語句 ? 表示占位符
      String sql = "select * from user where username = ?";
      //獲取預處理statement
      preparedStatement = connection.prepareStatement(sql);
      //設置參數,第一個參數為sql語句中參數的序號(從1開始),第二個參數為設置的參數值
      preparedStatement.setString(1, "王五");
      
      //向數據庫發出sql執行查詢,查詢出結果集
      resultSet =  preparedStatement.executeQuery();
      
      // 結果集處理代碼。。。
      // 資源釋放代碼。。。
      
      
    • 從上面代碼起碼可以獲得以下結論:

      • 代碼中存在大量的硬編碼,因為Java是編譯型語言,修改代碼之後需要重新編譯,這大大減低可代碼的可維護性。

      • 如果需要多次執行數據操作的話,大量出現數據連接操作,造成資源浪費。

    • 從軟件開發的角度討論上面存在的問題:

      • 代碼的封裝性:上面由於存在大量的硬編碼,導致每一次數據操作都需要編寫上面重復的代碼,大大降低了工作效率
      • 代碼可維護性:當代碼中出現大量硬編碼時,在修改這些硬編碼的時候就導致代碼的維護性和擴展性變得很差。
    • 總結:代碼中應該極力避免出現硬編碼,可以用配置文件或者屬性文件來代替這些硬編碼。

  • Mybatis 如何解決這些問題

    • 使用properties屬性文件和xml配置文件結合

    • 使用接口實現類代理對象(後面講)Mapper

    • 數據連接池datasource

    • 動態sql

    • 結果映射resultType

    上面這些都是我們需要學習的地方,此文針對的是 Mybatis3.2.7版本


Hello Mybatis

開發的步驟

  • 確定需求:查詢所有用戶

  • 導入sql文件 sql文件下載

  • 創建JAVA工程

  • 新建一個Folder,一般名為lib,來存儲Jar包,導入JAR包,JAR包可以在github上面下載: Mybatis下載

    • 主要有 mybatis-3.2.7.jar

    • 和lib目錄下的依賴包

  • 創建Log4j屬性文件,建議放在新建的SourcePackage(和src一樣性質的包,編譯之後會合並在一起)下,名為config

    # log4j.properties
    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout
    # 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
  • 在config包下創建mybatis.xml 文件

    <!-- 
      mybatis.xml
     -->
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- xml 約束
      !DOCTYPE 後面的 configuration 規定了該xml文件的根節點為configuration
     -->
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    
    <configuration>
      <!-- 第一步、導入配置數據源的屬性文件mysql.properties
          resource屬性:指向properties文件的相對路徑
       -->
      <properties resource="mysql.properties" />
    
      <!-- 配置mybatis的環境
          environments 說明可以配置多個environment,最後根據default 屬性指定使用的environment
          default對應的是environment的id屬性
       -->
      <environments default="mysql-env">
          <!-- 
              The content of element type "environment" is incomplete, it must match 
              "(transactionManager,dataSource)".
              從上面的提示中可以看出,enviroment節點下必須有transactionManager 事務管理、
              dataSource 數據源兩個節點
    
           -->
          <environment id="mysql-env">
              <!-- 設置事務管理器  事務有mybatis管理
                  註意:mybatis 默認不會自動提交事務,所以再進行增刪改的時候需要自己提交事務
              -->
              <transactionManager type="JDBC" />
              <!-- 設置數據源
                  type:
                      POOLED :
               -->
              <dataSource type="POOLED">
                  <property name="driver" value="${jdbc.mysql.Driver}"/>
                  <property name="url" value="${jdbc.mysql.Url}"/>
                  <property name="username" value="${jdbc.mysql.Username}"/>
                  <property name="password" value="${jdbc.mysql.Password}"/>
              </dataSource>
          </environment>
      </environments>
    
    </configuration>

    上面設計到數據源屬性文件mysql.properties,同樣位於config包下

    # mysql.properties
    # warn:in the properties file can‘n use block after ‘=‘
    jdbc.mysql.Driver=com.mysql.jdbc.Driver
    jdbc.mysql.Url=jdbc:mysql://127.0.0.1:3306/taobao?characterEncoding=utf8
    jdbc.mysql.Username=root
    jdbc.mysql.Password=root
    
    # 註意=號後面不要跟有空格,上面英文就是這個意思,英文很渣,中式英文 =_=|
  • 創建JavaBean類 com.demo.model.User.java

    package com.demo.model;
    
    import java.io.Serializable;
    /**
     * 
    
    * <p>Title: User</p>  
    
    * <p>Description: User 實體類
    *     實體類是一個JavaBean ,以下是JavaBean的規範:
    * 
    *     <li>1、實現Serializable 接口</li>
    *     <li>2、JavaBean提供一個無參構造器。</li>
    *     <li>3、提供成員變量getter、setter方法</li>
    *     <li>4、必須是一個公共類,將其訪問屬性設置為public</li>
    *     <li>5、所有屬性變量都應該是private的</li>
    *     
    *   為什麽有這樣的規範?
    *     1、為什麽要實現Serializable接口?
    *         簡單可以理解為便於網絡傳輸就行。
    *     2、為什麽要提供無參構造器呢?
    *         個人理解為理由有2點:
    *         a、在反射是創建對象,調用的是無參構造函數,這也是很多框架應用的。
    *         b、在繼承時,JVM創建父類對象也是調用無參構造器來實現的。
    *     3、為了對象的信息的封裝隱藏。
    *         
    * </p>  
    * 
    * @author Hunter_1 
    * @date 2018年7月15日
     */
    public class User implements Serializable{
    
      private Integer userId;
      private String username;
      private int age;
      private String password;
    
        //...getter...
        //...setter...
        //...toString()....
    }
    
  • 創建sql映射文件sql.xml 同樣在config包下

    <?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.demo.model.User">
    
      <!-- 查詢所有用戶 
          註意:id一定要見名知意,後面有用。
              resultType:指明返回類型的類型
      -->
      <select id="getAllUser" resultType="com.demo.model.User">
          select user_id userId, username, age, password from user;
      </select>
    </mapper>
  • 在mybatis.xml 核心配置文件中導入sql映射配置文件

    <!-- 導入映射文件 -->
    <!-- mappers 節點是configuration的子節點 -->
    <mappers>
        <!-- 
      resource:使用相對路徑
      sql.xml 和mybatis.xml 在同一個包下,相對路徑就比較簡單
      -->
        <mapper resource="sql.xml"/>
    </mappers>
  • 測試:編寫測試類 MyTest.java

    package com.demo.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    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.demo.model.User;
    
    public class MyTest {
    
      public static void main(String[] args) throws Exception {
    
    
          //1、加載配置文件
          // Resources,這個類在 org.mybatis.io 包中。Resources 類正 如其名,會幫助你從類路徑下, 文件系統或一個 web URL 加載資源文件。
          // Resources 是一個靜態類,主要用於加載配置文件
          InputStream in = Resources.getResourceAsStream("mybatis.xml");
          //2、構建會話工廠,會話的概念可以簡單的認為相當於JDBC中的Connection 
          // 註意:每個數據庫對應一個 SqlSessionFactory 實例 
          SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    
          //創建回話對象, SqlSession 會話對象在Mybatis中是一個非常強大的類(目前這樣理解就夠)
          SqlSession session = factory.openSession();
    
          //查詢
          List<User> list = session.selectList("getAllUser");
    
          /**
           * log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).
             log4j:WARN Please initialize the log4j system properly.
             log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    
             出現上面的信息說明缺少log4j的配置文件
    
          日誌信息:
          DEBUG [main] - Logging initialized using ‘class org.apache.ibatis.logging.slf4j.Slf4jImpl‘ adapter.
          DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
          DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
          DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
          DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
          打開連接
          DEBUG [main] - Opening JDBC Connection
          創建連接
          DEBUG [main] - Created connection 1551870003.
          自動事務提交 為false,也就是默認事務提交是關閉的
          DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5c7fa833]
          執行sql語句
          DEBUG [main] - ==>  Preparing: select user_id userId, username, age, password from user; 
          沒有參數
          DEBUG [main] - ==> Parameters: 
          查詢結果為3條記錄
          DEBUG [main] - <==      Total: 3
    
          從上面的日誌中,我們可以看出,並沒有讓連接回到連接池的提示信息,那是因為沒有關閉session
           */
    
          //關閉session,註意如果是增刪改操作的話,在這之前還要進行事務手動提交
          session.close();
          /**
           * 關閉session之後
           *  DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5c7fa833]
           *  關閉連接
              DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@5c7fa833]
              讓連接返回連接池
              DEBUG [main] - Returned connection 1551870003 to pool.
           */
    
          for (User user : list) {
              System.out.println(user);
          }
          /** 輸出;
           *  User [userId=1, username=張三豐, age=90, password=111111]
              User [userId=2, username=張無忌, age=30, password=222222]
              User [userId=3, username=張翠山, age=50, password=111111]
           */
      }
    }
    

    推薦閱讀文檔

    Mybatis說明文檔-提取碼26dr

Mybatis - 學習指南一