學習了hibernate這個持久層框架以後,在來學習Mybatis簡直是無壓力,由於Mybatis入門門欄很低,若是學習過了hibernate的話,對於Mybatis的學習很簡單了,若是沒學習過hibernate直接學習Mybatis也不要緊,也很好理解。html
寫Mybatis這一章節博客,大體分爲這樣一種思路 java
mybatis入門 --> 全局配置文件和映射文件詳解 --> 高級映射(一對一,一對多,多對多) -->延遲加載機制 -->一級緩存,二級緩存(整合ehcache) --> spring整合mybatis --> 逆向工程mysql
若是你想直接查看mybatis的標準helloworld,那麼跳過這章,看第二章。spring
1、Mybatis的簡介sql
mybatis封裝了jdbc的持久層框架,前身爲ibatis,在配置文件中編寫sql,是不徹底orm映射框架。數據庫
查看百度百科的介紹apache
一、支持普通sql查詢緩存
二、高級映射session
三、存儲過程mybatis
四、消除了幾乎全部jdbc代碼和參數的手工設置以及結果集的檢索,等等特色,都會講解到,今天先認識一下爲何說mybatis消除了全部jdbc代碼和參數的設置,經過普通的jdbc有哪些不足,從而認識到mybatis的好處。
2、分析jdbc的問題
1 //一、註冊驅動,什麼是驅動?可以讓java鏈接數據庫,也就是實現jdbc接口規範就是驅動 2 Class.forName("com.mysql.jdbc.Driver");//硬編碼 3 /* 4 * 二、經過驅動管理者獲取數據庫鏈接 5 * DriverManager是驅動實現類的管理者。 6 * url:鏈接數據庫的位置,端口號,數據庫名 7 * jdbc:mysql://localhost:3306/test_01 8 */ 9 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test_1", "root", "root");//(硬編碼) 10 /* 11 * 三、得到sql語句執行者 12 * statement:執行sql語句對象 13 * sql語句必須是完整的。 14 * preparedStatement:預處理(經常使用) 15 * sql語句能夠不是完整的,能夠將參數用?替代,而後在預編譯後加入未知參數 16 * 17 */ 18 //定義sql語句,?表示佔位符 19 String sql = "select * from user where id = ?"; //硬編碼 20 PreparedStatement ps = conn.prepareStatement(sql); 21 ps.setInt(1, 1); //硬編碼 22 //四、獲取sql語句執行結果,resultset 23 /* 24 * executeQuery():查詢操做 25 * executeUpdate():增刪改操做 26 */ 27 ResultSet rs= ps.executeQuery(); 28 //五、處理結果 29 while(rs.next()){ 30 System.out.println(rs.getInt(1));;//index表明第幾列,從1開始 31 } 32 33 //六、關閉鏈接 34 rs.close(); 35 ps.close(); 36 conn.close();
1 //一、註冊驅動,什麼是驅動?可以讓java鏈接數據庫,也就是實現jdbc接口規範就是驅動 2 Class.forName("com.mysql.jdbc.Driver");//硬編碼 3 /* 4 * 二、經過驅動管理者獲取數據庫鏈接 5 * DriverManager是驅動實現類的管理者。 6 * url:鏈接數據庫的位置,端口號,數據庫名 7 * jdbc:mysql://localhost:3306/test_01 8 */ 9 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test_1", "root", "root");//(硬編碼) 10 /* 11 * 三、得到sql語句執行者 12 * statement:執行sql語句對象 13 * sql語句必須是完整的。 14 * preparedStatement:預處理(經常使用) 15 * sql語句能夠不是完整的,能夠將參數用?替代,而後在預編譯後加入未知參數 16 * 17 */ 18 //定義sql語句,?表示佔位符 19 String sql = "select * from user where id = ?"; //硬編碼 20 PreparedStatement ps = conn.prepareStatement(sql); 21 ps.setInt(1, 1); //硬編碼 22 //四、獲取sql語句執行結果,resultset 23 /* 24 * executeQuery():查詢操做 25 * executeUpdate():增刪改操做 26 */ 27 ResultSet rs= ps.executeQuery(); 28 //五、處理結果 29 while(rs.next()){ 30 System.out.println(rs.getInt(1));;//index表明第幾列,從1開始 31 } 32 33 //六、關閉鏈接 34 rs.close(); 35 ps.close(); 36 conn.close();
這種方式的缺陷
一、建立鏈接存在硬編碼
二、執行statement時存在硬編碼
三、頻繁的開閉數據庫鏈接,會影響數據庫的性能。
如今就對這個所產生的問題與使用mybatis進行對比。
3、初級的mybatis
跟hibernate同樣,也是須要擁有兩個配置文件,
全局配置文件 和 映射文件,在編寫這兩個映射文件以前,必須建立mybatis環境(jar包等)
建立java工程
3.一、jar包
mysql(1)
Mybatis(1個核心包+9個依賴包)
總共11個jar
3.二、初始化數據庫腳本
暫時只須要一張表 id是自增的,爲主鍵
3.三、添加log4j.properties
該內容能夠在mybatis的jar包中找到
1 # Global logging configuration 2 log4j.rootLogger=DEBUG, stdout 3 # MyBatis logging configuration... 4 log4j.logger.org.mybatis.example.BlogMapper=TRACE 5 # Console output... 6 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 7 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
1 # Global logging configuration 2 log4j.rootLogger=DEBUG, stdout 3 # MyBatis logging configuration... 4 log4j.logger.org.mybatis.example.BlogMapper=TRACE 5 # Console output... 6 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 7 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
3.四、全局配置文件
建議使用sqlMapConfig.xml,內容以下
這次的配置
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 <!-- 7 屬性 8 <properties></properties> 9 全局參數設置 10 <settings></settings> 11 類型別名 12 <typeAliases></typeAliases> 13 類型處理器 14 <typeHandles></typeHandles> 15 對象工廠 16 <objectFactory></objectFactory> 17 插件 18 <plugins></plugins> 19 以上屬性在後邊會詳細講解到,如今咱們就只須要關注一下下面的配置便可 20 以下所配置的就是使用這點東西。 21 environments(環境信息集合) 22 environment(單個環境信息) 23 transactionManager(事物) 24 dataSource(數據源) 25 environment 26 environments 27 mappers(映射器) 28 --> 29 30 31 <!-- 配置mybatis的環境信息 --> 32 <environments default="development"> 33 <environment id="development"> 34 <!-- 配置JDBC事務控制,由mybatis進行管理 --> 35 <transactionManager type="JDBC"></transactionManager> 36 <!-- 配置數據源,採用dbcp鏈接池 --> 37 <dataSource type="POOLED"> 38 <property name="driver" value="com.mysql.jdbc.Driver"/> 39 <property name="url" value="jdbc:mysql://localhost:3306/test_1?useUnicode=true&characterEncoding=utf8"/> 40 <property name="username" value="root"/> 41 <property name="password" value="root"/> 42 </dataSource> 43 </environment> 44 </environments> 45 <!-- 加載mapper映射文件 --> 46 <mappers> 47 <mapper resource="sqlmap/User.xml"/> 48 </mappers> 49 </configuration>
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 <!-- 7 屬性 8 <properties></properties> 9 全局參數設置 10 <settings></settings> 11 類型別名 12 <typeAliases></typeAliases> 13 類型處理器 14 <typeHandles></typeHandles> 15 對象工廠 16 <objectFactory></objectFactory> 17 插件 18 <plugins></plugins> 19 以上屬性在後邊會詳細講解到,如今咱們就只須要關注一下下面的配置便可 20 以下所配置的就是使用這點東西。 21 environments(環境信息集合) 22 environment(單個環境信息) 23 transactionManager(事物) 24 dataSource(數據源) 25 environment 26 environments 27 mappers(映射器) 28 --> 29 30 31 <!-- 配置mybatis的環境信息 --> 32 <environments default="development"> 33 <environment id="development"> 34 <!-- 配置JDBC事務控制,由mybatis進行管理 --> 35 <transactionManager type="JDBC"></transactionManager> 36 <!-- 配置數據源,採用dbcp鏈接池 --> 37 <dataSource type="POOLED"> 38 <property name="driver" value="com.mysql.jdbc.Driver"/> 39 <property name="url" value="jdbc:mysql://localhost:3306/test_1?useUnicode=true&characterEncoding=utf8"/> 40 <property name="username" value="root"/> 41 <property name="password" value="root"/> 42 </dataSource> 43 </environment> 44 </environments> 45 <!-- 加載mapper映射文件 --> 46 <mappers> 47 <mapper resource="sqlmap/User.xml"/> 48 </mappers> 49 </configuration>
3.五、映射文件和操做
User.xml 暫時這樣取。
<?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"> <!-- namespace:命名空間,對sql進行一個分類管理 --> <!-- 注意:namespace在mapper代理時,具備重要且特殊的做用 --> <mapper namespace="test"> //編寫映射條件,也就是下面的 </mapper>
<?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"> <!-- namespace:命名空間,對sql進行一個分類管理 --> <!-- 注意:namespace在mapper代理時,具備重要且特殊的做用 --> <mapper namespace="test"> //編寫映射條件,也就是下面的 </mapper>
該映射文件是爲了解決jdbc中statement的硬編碼的問題,因此,在此映射文件中,只須要指定輸入參數類型,返回結果參數類型,sql語句等就差很少了,也就是將本來jdbc所遇到的硬編碼問題所有是使用xml配置文件來替代,有什麼須要就修改配置文件便可,如今來看看該映射文件是如何編寫的。
經過增刪改查這四個操做來說解。
3.6.一、查詢 按id查詢出user對象 注意看下面的註釋
1 <!-- 2 使用id進行查詢 3 查詢,使用select來表示一個查詢的statement,至關於statement.executeQuery 4 id:表示該statement惟一標識 5 parameterType:輸入參數類型 6 resultType:輸出參數類型,使用的是User類,則會將查詢出來的記錄封裝到該類中 7 #{id}:使用#{}接收輸入的參數,其中的"id"屬性名任意,能夠爲uid,也能夠爲別的。 8 --> 9 <select id="findUserById" parameterType="java.lang.Integer" resultType="com.wuhao.mybatis.domain.User"> 10 SELECT * FROM user WHERE id= #{id} 11 </select> 12
1 <!-- 2 使用id進行查詢 3 查詢,使用select來表示一個查詢的statement,至關於statement.executeQuery 4 id:表示該statement惟一標識 5 parameterType:輸入參數類型 6 resultType:輸出參數類型,使用的是User類,則會將查詢出來的記錄封裝到該類中 7 #{id}:使用#{}接收輸入的參數,其中的"id"屬性名任意,能夠爲uid,也能夠爲別的。 8 --> 9 <select id="findUserById" parameterType="java.lang.Integer" resultType="com.wuhao.mybatis.domain.User"> 10 SELECT * FROM user WHERE id= #{id} 11 </select> 12
操做
1 //根據用戶id進行查詢。findUserById 2 @Test 3 public void test() throws IOException{ 4 //跟hibernate同樣,須要獲取一大堆東西 5 // 一、讀取配置文件 6 String resource = "SqlMapConfig.xml"; 7 InputStream inputStream = Resources.getResourceAsStream(resource); 8 // 二、根據配置文件建立SqlSessionFactory 9 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 10 // 三、SqlSessionFactory建立SqlSession 11 SqlSession sqlSession = sqlSessionFactory.openSession(); 12 // 四、SqlSession執行statement,並返回映射結果 13 14 /* 15 * test.findUserById:在映射配置文件中,mapper的namespace爲test, 16 * 其中有一個select,也就表明查詢的statement。 17 * 1:輸入參數爲1 18 * 返回的結果類型爲User 19 */ 20 User user = sqlSession.selectOne("test.findUserById", 1); 21 System.out.println(user); 22 23 //五、關閉sqlsession資源 24 sqlSession.close(); 25 }
1 //根據用戶id進行查詢。findUserById 2 @Test 3 public void test() throws IOException{ 4 //跟hibernate同樣,須要獲取一大堆東西 5 // 一、讀取配置文件 6 String resource = "SqlMapConfig.xml"; 7 InputStream inputStream = Resources.getResourceAsStream(resource); 8 // 二、根據配置文件建立SqlSessionFactory 9 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 10 // 三、SqlSessionFactory建立SqlSession 11 SqlSession sqlSession = sqlSessionFactory.openSession(); 12 // 四、SqlSession執行statement,並返回映射結果 13 14 /* 15 * test.findUserById:在映射配置文件中,mapper的namespace爲test, 16 * 其中有一個select,也就表明查詢的statement。 17 * 1:輸入參數爲1 18 * 返回的結果類型爲User 19 */ 20 User user = sqlSession.selectOne("test.findUserById", 1); 21 System.out.println(user); 22 23 //五、關閉sqlsession資源 24 sqlSession.close(); 25 }
3.6.二、查詢, 模糊查詢,對username字段進行模糊查詢
user.xml映射文件
操做
3.6.三、增長User, insert
user.xml,insert操做,對主鍵id有幾種不一樣的處理方式,具體看下圖的解釋
操做
3.6.四、刪除 delete
映射文件
操做
3.6.五、更新 update
映射文件
操做
小總結:編寫了最基礎的全局配置文件和映射文件。
全局配置文件:鏈接數據庫所須要的賬號密碼等屬性,事務等操做
映射文件:經過對比原始jdbc鏈接數據庫,其實mybatis中的映射文件就是對statement的硬編碼進行改進,咱們配置的都市statement須要的東西
sql語句、輸入參數類型代替sql語句中的佔位符,輸出參數類型表示輸出結果,均可以對應着statement的操做
parameterType:指定輸入參數的java類型,能夠填寫別名或Java類的全限定名。別名的用法在詳細講解全局配置文件的時候會講解到,在那邊能夠配置
resultType:指定輸出結果的java類型,能夠填寫別名或Java類的全限定名。
#{}和${}的用法
#{}:至關於預處理中的佔位符?
#{}裏面的參數表示接收java輸入參數的名稱
#{}能夠接受HashMap、簡單類型、POJO類型的參數
簡單類型:#{}裏面能夠是value,能夠是任意值
POJO類型的參數:必須是POJO中的屬性名
hashmap:key值名
${}:至關於拼接SQL串,對傳入的值不作任何解釋的原樣輸出。
${}會引發SQL注入,因此要謹慎使用。
${}能夠接受HashMap、簡單類型、POJO類型的參數。
當接受簡單類型的參數時,${}裏面只能是value。
sqlSession操做時selectOne和selectList
selectOne:只能查詢0或1條記錄,大於1條記錄的話,會報錯
selectList:能夠查詢0或N條記錄
對於增刪改操做,切記須要commmit操做纔可以生效。
4、開發dao的方式
上面咱們就單純測試了使用mybatis對數據庫的增刪改查操做,在開發中,咱們都是開發dao接口和dao實現類,那麼就在dao實現類中調用sqlsession的方法對數據庫的增刪改差操做便可。
4.一、dao接口
4.二、daoImpl 實現類
4.三、測試
小總結:
這樣開發有一個很差的地方,就是不可以直接使用dao接口中的方法,而是使用的sqlSession中的方法,這樣讓人不能一目瞭然,因此咱們在開發中都不使用這種方式進行開發,而是使用Mapper代理的方式,什麼意思呢?接下來說講。
5、Mapper代理開發的方式
Mapper代理開發方式就是開發mapper接口(至關於dao接口)
一、mapper接口的全限定名要和mapper映射文件的namespace一致
二、mapper接口的方法名稱要和mapper映射文件的statement的id一致
三、mapper接口的方法參數類型要和mapper映射文件的statement的parameterType一致
四、mapper接口的方法返回值類型要和 mapper映射文件的statement的resultType一致
這樣直接看確定很差理解,因此直接上代碼。
三樣東西,mapper接口,兩個配置文件,一個全局配置文件,一個映射文件,可是這個映射文件就有要求了,除了上面所說的四點以外,另一點也最好遵循,這裏用不到,可是後面會講解爲何會這樣使用,就是mapper接口的名稱要和映射文件的名稱相同,
mapper接口,UserMapper.java
映射文件,UserMapper.xml
全局配置文件。sqlMapConfig.xml
其餘都跟上面同樣,重點講一下這個mappers加載映射文件的問題,爲何須要mapper接口和映射文件同名,而且放入同一目錄下
爲了方便批量加載映射文件。而使用這種方式,前提條件就是接口和映射文件同名而且放入同一目錄下。
測試
直接調用方法名便可
6、總結
mybatis的基本用法就是這樣,我想你們應該都有點感受了,就是在映射文件中編寫statement,將輸入參數和輸出結果進行映射,因此說mybatis是不徹底映射的框架。懂了基本的用法以後,那麼以後就會詳細講解其中的問題,全局配置文件當中的配置,映射文件中的詳細配置(高級映射),延遲加載,一級緩存二級緩存等用法。
原文出處:https://www.cnblogs.com/surfcater/p/10225738.html