myBatis 入門學習
0. 相關概念
0.1 框架和工具類
-
工具類
-
對程式中一小段代碼的封裝,專案中大多數代碼還是需要我們寫,
-
-
框架
-
通俗理解框架
-
可以看做一個半成品的軟體/專案,使用框架開發專案,專案中半數以上代碼就不需要 我們撰寫了,
-
我們一般需要配置(大多數框架都是重配置輕編碼的)+少量編碼,就可完成專案中的需求,
-
框架的目的 就是為了簡化編碼:
eg:Mybatis, 我們在學習完Mybatis之后,dao層會更簡單,你只需要寫一個dao介面,然后寫一個SQL陳述句,dao層就已經寫完了,
-
-
學習步驟
-
這個框架能干什么?
-
導包+配置
-
框架少量的
API,少量編碼
-
0.2 ORM
-
Object Relational Mapping物件關系映射的思想 -
物件 - Java中的物件 關系-關系型資料庫中表的記錄 映射 - 一對一關聯起來
-
java專案中的每一個物體類,對應資料庫中的一個表;java類中的屬性,對應資料庫表中的欄位,java類中的一個物體物件,對應一個資料表中的一條記錄 -
全自動
ORM框架:hibernate,通過操作物體物件,就可以完成對資料庫表中記錄的操作,復雜業務性能低下,不可定制,學習成本高,
-
半自動的
ORM框架:Mybatis,ibatis基于
ORM,但是SQL陳述句需要我們自己撰寫,自己優化SQL,可定制性強,效率高,
0.3 Mybatis&原生JDBC
-
原生jdbc
-
注冊驅動,設定連接引數 -
獲取連接 -
獲取執行物件
-
設定
SQL引數并執行SQL陳述句 -
封裝結果集并封裝成物體物件
-
釋放資源
相同的內容已經抽取到工具類中(上述洗掉線標識的步驟)
模板化(步驟不變,部分步驟相同,上述加粗的內容)的操作,也是可以抽取封裝的,
但是相同的步驟中又有不同的地方,不同的地方如果也要實作解耦,需要通過配置來實作
-
-
Mybatis解決方案-
連接復用:使用資料庫連接池初始化并管理連接
-
解耦:將
SQL陳述句和設定到SQL中的引數抽取到xml組態檔中 -
自動封裝:通過反射內省等技術,實作查詢結果集欄位與物體屬性自動映射并賦值
-
-
Mybatis框架抽取后的樣子

-
Mybatis簡介-
是一個資料持久層(
DAO)框架,封裝共性內容讓使用者只關注SQL本身,結合了ORM思想,是一個ORM半自動的框架, -
使用
Mybatis之后,我們只需要定義一個Dao層介面+存盤SQL的組態檔(Mybatis映射組態檔),就可以完成Dao層內容,
-
1. Mybatis快速入門
1.1 Mybatis快速入門步驟
-
匯入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="https://www.cnblogs.com/sonyan/p/com.mysql.jdbc.Driver"/>
12 <property name="url" value="https://www.cnblogs.com/sonyan/p/jdbc:mysql:///web17_mybatis01"/>
13 <property name="username" value="https://www.cnblogs.com/sonyan/p/root"/>
14 <property name="password" value="https://www.cnblogs.com/sonyan/p/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.1 Resources
讀取配置的檔案的工具類
InputStream getResourceAsStream("組態檔相對于類路徑的相對路徑");
2.2 SqlSessionFactoryBuilder
獲取SqlSessionFactory工廠物件的功能類,
// 通過構建的方式構建了一個SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
?
//xxxBuilder.build()
2.3 SqlSessionFactory
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="https://www.cnblogs.com/sonyan/p/${jdbc.driver}"/>
15 <property name="url" value="https://www.cnblogs.com/sonyan/p/${jdbc.url}"/>
16 <property name="username" value="https://www.cnblogs.com/sonyan/p/${jdbc.username}"/>
17 <property name="password" value="https://www.cnblogs.com/sonyan/p/${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.2 Settings(重要)
1 <!-- 極為重要的設定 --> 2 <settings> 3 <!-- 4 指定 MyBatis 所用日志的具體實作,未指定時將自動查找, 5 LOG4J 要求:1. 匯入log4j的jar包 2. 有一個log4j.properties檔案 6 建議顯式的配置上,可配可不配的,建議配上, 7 --> 8 <setting name="logImpl" value="https://www.cnblogs.com/sonyan/p/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="https://www.cnblogs.com/sonyan/p/true"/>--> 23 </settings>
4.3 TypeAliases(了解)
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.4 Environments(了解)
1 <environments default="dev">
2 <environment id="dev">
3 <transactionManager type="JDBC"/>
4 <dataSource type="POOLED">
5 <!-- 連接資料庫四要素 -->
6 <property name="driver" value="https://www.cnblogs.com/sonyan/p/${jdbc.driver}"/>
7 <property name="url" value="https://www.cnblogs.com/sonyan/p/${jdbc.url}"/>
8 <property name="username" value="https://www.cnblogs.com/sonyan/p/${jdbc.username}"/>
9 <property name="password" value="https://www.cnblogs.com/sonyan/p/${jdbc.password}"/>
10 </dataSource>
11 </environment>
12 <environment id="test">
13 <transactionManager type="JDBC"/>
14 <dataSource type="POOLED">
15 <!-- 連接資料庫四要素 -->
16 <property name="driver" value="https://www.cnblogs.com/sonyan/p/${jdbc.driver}"/>
17 <property name="url" value="https://www.cnblogs.com/sonyan/p/${jdbc.url}"/>
18 <property name="username" value="https://www.cnblogs.com/sonyan/p/${jdbc.username}"/>
19 <property name="password" value="https://www.cnblogs.com/sonyan/p/${jdbc.password}"/>
20 </dataSource>
21 </environment>
22 </environments>
4.5 Mappers(重點)
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 />--> 21 <!--<mapper />--> 22 <!--<mapper />--> 23 24 <!-- 25 把包下所有的映射組態檔和介面全部加載進來 最推薦使用 26 --> 27 <package name="com.itheima.dao"/> 28 </mappers> 29
5. 經驗分享
5.1 生成Mybatis組態檔
本質是新建了一個檔案模板,按照下面的方式新建兩個模板即可(Mybatis-config、Mybatis-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 }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/166756.html
標籤:Java
上一篇:mybatis_8使用注解開發
