1. 程式人生 > 實用技巧 >myBatis 入門學習

myBatis 入門學習

myBatis 入門學習

0. 相關概念

0.1 框架和工具類

  • 工具類

    • 對程式中一小段程式碼的封裝。專案中大多數程式碼還是需要我們寫。

  • 框架

    • 通俗理解框架

    • 可以看做一個半成品的軟體/專案。使用框架開發專案,專案中半數以上程式碼就不需要 我們編寫了。

    • 我們一般需要配置(大多數框架都是重配置輕編碼的)+少量編碼,就可完成專案中的需求。

    • 框架的目的 就是為了簡化編碼eg:Mybatis我們在學習完Mybatis之後,dao層會更簡單。你只需要寫一個dao介面,然後寫一個SQL語句,dao層就已經寫完了。

  • 學習步驟

    • 這個框架能幹什麼?

    • 導包+配置

    • 框架少量的API

      ,少量編碼

0.2ORM

  • Object Relational Mapping物件關係對映的思想

  • 物件 - Java中的物件 關係-關係型資料庫中表的記錄 對映 - 一對一關聯起來

  • java專案中的每一個實體類,對應資料庫中的一個java類中的屬性,對應資料庫表中的欄位java類中的一個實體物件,對應一個數據表中的一條記錄

  • 全自動ORM框架:hibernate

    通過操作實體物件,就可以完成對資料庫表中記錄的操作。複雜業務效能低下,不可定製,學習成本高。

  • 半自動的ORM框架:Mybatis,ibatis

    基於ORM,但是SQL語句需要我們自己編寫。自己優化SQL,可定製性強,效率高。

0.3Mybatis&原生JDBC

  • 原生jdbc

    • 註冊驅動,設定連線引數

    • 獲取連線

    • 獲取執行物件

    • 設定SQL引數並執行SQL語句

    • 封裝結果集並封裝成實體物件

    • 釋放資源

    相同的內容已經抽取到工具類中(上述刪除線標識的步驟)

    模板化(步驟不變,部分步驟相同,上述加粗的內容)的操作,也是可以抽取封裝的。

    但是相同的步驟中又有不同的地方,不同的地方如果也要實現解耦,需要通過配置來實現

  • Mybatis解決方案

    • 連線複用:使用資料庫連線池初始化並管理連線

    • 解耦:將SQL語句和設定到SQL中的引數抽取到xml配置檔案中

    • 自動封裝:通過反射內省等技術,實現查詢結果集欄位

      實體屬性自動對映並賦值

  • Mybatis框架抽取後的樣子

  • Mybatis簡介

    • 是一個數據持久層(DAO)框架,封裝共性內容讓使用者只關注SQL本身。結合了ORM思想,是一個ORM半自動的框架。

    • 使用Mybatis之後,我們只需要定義一個Dao層介面+儲存SQL的配置檔案(Mybatis對映配置檔案),就可以完成Dao層內容。

1.Mybatis快速入門

1.1Mybatis快速入門步驟

  • 匯入Jar包

    • mybatis-3.5.3.jar

    • mysql-connector-java-5.1.37-bin.jar

    • log4j-1.2.17.jar

  • 編寫Mybatis核心配置檔案:mybatis-config.xml

    • 連線資料庫四要素

    • <mapper>標籤中對映檔案路徑不是./建議複製,不要手敲

  • 編寫對映檔案:StudentDao.xml

  • 編寫POJO類和Dao層介面,初始化資料庫表及資料

  • SQL

  • 實體類

  • 介面

  • 測試

  • 小經驗

    • 直接生成mybatis的兩類xml檔案

    • Mybatis對映配置檔案和介面之間相互跳轉

核心配置檔案



 1 <?xml version="1.0" encoding="UTF-8" ?>
 2  <!DOCTYPE configuration
 3          PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4          "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5  <configuration>
 6      <environments default="development">
 7          <environment id="development">
 8              <transactionManager type="JDBC"/>
 9              <dataSource type="POOLED">
10                  <!-- 連線資料庫四要素 -->
11                  <property name="driver" value="com.mysql.jdbc.Driver"/>
12                  <property name="url" value="jdbc:mysql:///web17_mybatis01"/>
13                  <property name="username" value="root"/>
14                  <property name="password" value="root"/>
15              </dataSource>
16          </environment>
17      </environments>
18  ​
19  ​
20      <!-- 載入對映配置檔案 -->
21      <mappers>
22          <mapper resource="com/itheima/dao/StudentDao.xml"/>
23      </mappers>
24  </configuration>

對映配置檔案



 1 <?xml version="1.0" encoding="UTF-8" ?>
 2  <!--
 3      xml文件第一行是文件宣告,必須在首行
 4      接下來是:名稱空間。作用如下:
 5          1. 引入dtd檔案
 6          2. 對文件中標籤及其屬性進行約束
 7   -->
 8  <!DOCTYPE mapper
 9          PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
10          "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
11  ​
12  <!-- 把當前這個xml配置檔案當做對應介面的實現類
13          通過namespace屬性指向要被實現的介面,介面代理的方式必須這樣寫
14  ​
15   -->
16  <mapper namespace="com.itheima.dao.StudentDao">
17      <!--
18          標籤名:select  表示查詢
19              id屬性   id唯一標識,要配置被實現的介面中的方法
20              resultType屬性    方法的結果(集合中泛型)的型別,全限定類名,不能省略
21              parameterType屬性,方法發引數的型別,全限定類名,可以省略
22              標籤體中書寫SQL語句
23          整個標籤被稱之為:statement
24  ​
25       -->
26          <select id="findById" resultType="com.itheima.domain.Student">
27              select * from student where  id = 1;
28          </select>
29  </mapper>

介面StudentDao.java



1 public interface StudentDao {
2      Student findById();
3  }

測試類MybatisTest.java

View Code

2. API

2.1Resources

讀取配置的檔案的工具類

InputStream getResourceAsStream("配置檔案相對於類路徑的相對路徑");

2.2SqlSessionFactoryBuilder

獲取SqlSessionFactory工廠物件的功能類。

// 通過構建的方式構建了一個SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//xxxBuilder.build()

2.3SqlSessionFactory

org.apache.ibatis.session.SqlSessionFactory:獲取SqlSessi物件的工廠介面。

SqlSession openSession()獲取SqlSession物件,並開啟手動提交事務

SqlSession openSession(boolean autoCommit)獲取SqlSession物件,true表示自動提交

2.4SqlSession

org.apache.ibatis.session.SqlSession:sql會話物件介面。用於執行SQL管理事務介面代理

void commit() 提交事務
void rollback() 回滾事務
T getMapper(Class cls) 獲取指定介面的代理實現類物件
void close() 釋放資源

3. 對映配置檔案

編碼完成如下需求:



1 // 需求1:查詢id為1的學生(強制要求)
2 // 需求2:建立一個Student物件並儲存到資料庫(引數和成員變數名保持一致)(成功了嗎?)
3 // 需求3:根據學生姓名和年齡查詢使用者,傳兩個引數(多個引數怎麼辦?)
4 // 需求4:完成需求3,傳一個引數。

對映配置檔案StudentDao.xml保證這個檔案的名字和介面名完全一致,且在同一個包下。

View Code

核心配置檔案

1  <!-- 載入對映配置檔案  這裡使用的是/ -->
2  <mappers>
3      <mapper resource="com/itheima/dao/StudentDao.xml"/>
4  </mappers>

Dao層介面StudentDao

 1 public interface StudentDao {
 2     @Select("select * from student where  id = 1")
 3     Student findById();
 4 
 5     // 需求1:查詢id為1的學生(強制要求)
 6     Student findById2(@Param("id") Integer id);
 7 
 8     // 需求2:建立一個Student物件並儲存到資料庫
 9     void save(Student stu);
10 
11     // 需求3:根據學生姓名和年齡查詢使用者,傳兩個引數(多個引數怎麼辦?)
12     List<Student> findByNameAndAge(@Param("name") String name, @Param("agex") Integer age);
13 
14     // 需求4:完成需求3,傳一個引數。
15     // 4.1 把兩個引數封裝成一個實體物件
16     // 如果把多個引數封裝到一個實體物件中,引數型別有侷限性,不能是兩個一樣的條件做範圍查詢
17     List<Student> findByStudent(Student stu);
18 
19     // 4.2 把兩個引數封裝到Map集合中
20     List<Student> findByMap(Map<String,Object> map);
21 }

測試類

 1 /**
 2  * @Author sonyan
 3  * @Date 2020/8/7 11:19
 4  * @Description: 測試類
 5  */
 6 public class MybatisDemo {
 7     public static void main(String[] args) throws Exception {
 8 
 9         // 指定核心配置檔案
10         String resource = "mybatis-config.xml";
11         // 把核心配置檔案載入成流  Resources為我們提供的方便讀取配置檔案的工具類
12         InputStream inputStream = Resources.getResourceAsStream(resource);
13 
14         // 通過構建的方式構建了一個SqlSessionFactory
15         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
16 
17         // SqlSession 就相當於我們之前的 Connection
18         // JDK7新特性  try-with-resource
19         // 需要釋放資源的動作,自動釋放在try()中開啟的一些流、會話......
20         try (SqlSession session = sqlSessionFactory.openSession(true)) {
21 
22             // getMapper  getDao   獲取一個指定介面的實現類物件
23             // 底層是動態代理
24             // 動態代理可以增強有介面的類、介面(增強介面,就是現實介面)
25             // 就相當於我們自己new StudentDaoImpl();
26             // 這個StudentDaoImpl是Mybatis通過動態代理幫我們自動生成並且賦值給了studentDao
27             StudentDao studentDao = session.getMapper(StudentDao.class);
28 
29             /*List<Student> students = studentDao.findAll();
30             System.out.println("students = " + students);*/
31 
32 
33             // 測試根據id查詢
34             /*Student student = studentDao.findById(1);
35             System.out.println("student = " + student);*/
36 
37             // 測試新增學生
38             //studentDao.saveStudent(new Student(null,"鳳姐",20));
39 
40             // 根據名稱和年齡查詢使用者,引數是兩個基本型別
41             //List<Student> students = studentDao.findByNameAndAge("美女", 20);
42             //System.out.println("students = " + students);
43 
44             // 根據名稱和年齡查詢使用者,引數是一個student物件
45             //List<Student> students = studentDao.findByUser(new Student(null, "鳳姐", 20));
46             //System.out.println("students = " + students);
47 
48             // 根據名稱和年齡查詢使用者,引數是一個map集合
49 
50             HashMap<String, Object> map = new HashMap<>();
51             map.put("name", "王二蛋");
52             map.put("age", 20);
53 
54             System.out.println("studentDao.findByMap(map) = " + studentDao.findByMap(map));
55 
56 
57             // 手動提交
58             //session.commit();
59 
60             // session.close();
61         }
62 
63     }
64 }

4. 核心配置檔案

4.1 properties(重要)

引入外部的properties檔案,一般用作引入資料庫連結引數的配置。

核心配置檔案

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <!-- 這是一個mybatis的核心配置檔案,名字任意-->
 6 <configuration>
 7     <!-- -->
 8     <properties resource="jdbc.properties"/>
 9 
10     <environments default="development">
11         <environment id="development">
12             <transactionManager type="JDBC"/>
13             <dataSource type="POOLED">
14                 <property name="driver" value="${jdbc.driver}"/>
15                 <property name="url" value="${jdbc.url}"/>
16                 <property name="username" value="${jdbc.username}"/>
17                 <property name="password" value="${jdbc.password}"/>
18             </dataSource>
19         </environment>
20     </environments>
21 
22     <!-- 載入對映配置檔案 -->
23     <mappers>
24         <mapper resource="com/itheima/dao/StudentDao.xml"/>
25     </mappers>
26 </configuration>

jdbc.properties

1 jdbc.driver=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://192.168.115.130:3306/db1
3 jdbc.username=root
4 jdbc.password=root

4.2Settings(重要)

 1 <!-- 極為重要的設定 -->
 2 <settings>
 3     <!--
 4         指定 MyBatis 所用日誌的具體實現,未指定時將自動查詢。
 5         LOG4J  要求:1. 匯入log4j的jar包  2. 有一個log4j.properties檔案
 6         建議顯式的配置上。可配可不配的,建議配上。
 7      -->
 8     <setting name="logImpl" value="LOG4J"/>
 9 
10 
11     <!--
12         mapUnderscoreToCamelCase
13         是否開啟駝峰命名自動對映,即從經典資料庫列名 A_COLUMN 對映到經典 Java 屬性名 aColumn。
14 
15         Java中多個單詞的屬性名  使用駝峰命名   lastName
16         MySQL不缺分大小寫      底槓命名       last_name
17 
18 
19         Mybatis可以幫我們自動完成結果集和實體的自動轉換封裝,原因是結果集的欄位名和實體屬性名一致。
20 
21     -->
22     <!--<setting name="mapUnderscoreToCamelCase" value="true"/>-->
23 </settings>

4.3TypeAliases(瞭解)

 1 <!-- 起別名 -->
 2 <typeAliases>
 3     <!--
 4         type 全限定類名
 5         alias 別名
 6         別名不區分大小寫
 7      -->
 8     <!--<typeAlias type="com.itheima.domain.Student" alias="student"/>-->
 9 
10     <!-- 為包下所有的實體類起別名,不區分大小寫 -->
11     <!--<package name="com.itheima.domain"/>-->
12 
13 </typeAliases>

起別名後,在對映配置檔案中可以直接使用別名

1 <select id="findByMap" resultType="Student">
2        select * from student where first_username=#{name}
3        and
4        age=#{age}
5 </select>
6  

系統為常見的型別起好了別名

4.4Environments(瞭解)

 1 <environments default="dev">
 2     <environment id="dev">
 3         <transactionManager type="JDBC"/>
 4         <dataSource type="POOLED">
 5             <!-- 連線資料庫四要素 -->
 6             <property name="driver" value="${jdbc.driver}"/>
 7             <property name="url" value="${jdbc.url}"/>
 8             <property name="username" value="${jdbc.username}"/>
 9             <property name="password" value="${jdbc.password}"/>
10         </dataSource>
11     </environment>
12     <environment id="test">
13         <transactionManager type="JDBC"/>
14         <dataSource type="POOLED">
15             <!-- 連線資料庫四要素 -->
16             <property name="driver" value="${jdbc.driver}"/>
17             <property name="url" value="${jdbc.url}"/>
18             <property name="username" value="${jdbc.username}"/>
19             <property name="password" value="${jdbc.password}"/>
20         </dataSource>
21     </environment>
22 </environments>

4.5Mappers(重點)

 1 <!-- 載入對映配置檔案 -->
 2 <mappers>
 3     <!--
 4         使用相對於類路徑的資源引用 可以用
 5         每個標籤引入一個Mapper的XML檔案
 6      -->
 7     <!--<mapper resource="com/itheima/dao/StudentDao.xml"/>-->
 8     <!--<mapper resource="com/itheima/dao/CourseDao.xml"/>-->
 9     <!--<mapper resource="com/itheima/dao/OrderDao.xml"/>-->
10 
11     <!--
12         使用完全限定資源定位符(URL) 不推薦使用
13         http://   file://
14      -->
15     <!--<mapper url="file:///var/mappers/AuthorMapper.xml"/>-->
16 
17     <!--
18         載入指定某個的介面,識別介面中的註解 可以用
19      -->
20     <!--<mapper class="com.itheima.dao.StudentDao"/>-->
21     <!--<mapper class="com.itheima.dao.StudentDao"/>-->
22     <!--<mapper class="com.itheima.dao.StudentDao"/>-->
23 
24     <!--
25         把包下所有的對映配置檔案和介面全部載入進來  最推薦使用
26      -->
27     <package name="com.itheima.dao"/>
28 </mappers>
29  

5. 經驗分享

5.1 生成Mybatis配置檔案

本質是新建了一個檔案模板,按照下面的方式新建兩個模板即可(Mybatis-configMybatis-Mapper

5.2介面對映配置檔案跳轉

使用一個外掛free-idea-mybatis

這個外掛是個zip包,不要解壓,直接安裝即可。

已知bug:

多個模組之間有相同內容會提示/跳轉錯誤,解除安裝其他模組即可。

5.3 ${}和#{}區別(面試題)

##{} MyBatis 會建立PreparedStatement引數佔位符,並通過佔位符安全地設定引數(就像使用 ? 一樣)。 這樣做更安全,更迅速,通常也是首選做法

${} 會做字串的拼接,將{}中直接拼直接在 SQL 語句中,可能會有SQL注入的風險,效率更低。但是,如果你需要在SQL語句中直接插入一個不轉義的字串,可以使用這種方式。一般情況下會把表名或者欄位名通過這方方式傳遞到SQL語句中,比方說 ORDER BY後面的列名。

5.4 MybatisUtils工具類抽取

 1 public class MybatisUtills {
 2 
 3     // 獲取工廠物件SQLSessionFactory,這個物件一個就可
 4     private static SqlSessionFactory ssf = null;
 5 
 6     // 靜態程式碼塊中初始化該物件
 7     static {
 8         InputStream is = null;
 9         try {
10             is = Resources.getResourceAsStream("MyBatisConfig.xml");
11         } catch (IOException e) {
12             e.printStackTrace();
13         }
14         ssf = new SqlSessionFactoryBuilder().build(is);
15     }
16 
17     public static SqlSessionFactory getFactory() {
18         return ssf;
19     }
20 
21 
22     // 獲取SQLSession物件,這個連線物件可以有多個
23     public static SqlSession getSqlSession() {
24         return ssf.openSession(true);
25     }
26 
27 
28     // 獲取Mapper物件
29     public static <T> T getMapper(Class<T> tClass) {
30         return ssf.openSession(true).getMapper(tClass);
31     }
32 
33 }