學習了hibernate這個持久層框架之后,在來學習Mybatis簡直是無壓力,因為Mybatis入門門欄很低,如果學習過了hibernate的話,對於Mybatis的學習很簡單了,如果沒學習過hibernate直接學習Mybatis也沒關系,也很好理解。
寫Mybatis這一章節博客,大致分為這樣一種思路
mybatis入門 --> 全局配置文件和映射文件詳解 --> 高級映射(一對一,一對多,多對多) -->延遲加載機制 -->一級緩存,二級緩存(整合ehcache) --> spring整合mybatis --> 逆向工程
如果你想直接查看mybatis的標准helloworld,那么跳過這章,看第二章。
一、Mybatis的簡介
mybatis封裝了jdbc的持久層框架,前身為ibatis,在配置文件中編寫sql,是不完全orm映射框架。
查看百度百科的介紹
1、支持普通sql查詢
2、高級映射
3、存儲過程
4、消除了幾乎所有jdbc代碼和參數的手工設置以及結果集的檢索,等等特點,都會講解到,今天先認識一下為什么說mybatis消除了所有jdbc代碼和參數的設置,通過普通的jdbc有哪些不足,從而認識到mybatis的好處。
二、分析jdbc的問題

1 //1、注冊驅動,什么是驅動?能夠讓java連接數據庫,也就是實現jdbc接口規范就是驅動 2 Class.forName("com.mysql.jdbc.Driver");//硬編碼 3 /* 4 * 2、通過驅動管理者獲取數據庫連接 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 * 3、獲得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 //4、獲取sql語句執行結果,resultset 23 /* 24 * executeQuery():查詢操作 25 * executeUpdate():增刪改操作 26 */ 27 ResultSet rs= ps.executeQuery(); 28 //5、處理結果 29 while(rs.next()){ 30 System.out.println(rs.getInt(1));;//index代表第幾列,從1開始 31 } 32 33 //6、關閉連接 34 rs.close(); 35 ps.close(); 36 conn.close();
這種方式的缺陷
1、創建連接存在硬編碼
2、執行statement時存在硬編碼
3、頻繁的開閉數據庫連接,會影響數據庫的性能。
現在就對這個所產生的問題與使用mybatis進行對比。
三、初級的mybatis
跟hibernate一樣,也是需要擁有兩個配置文件,
全局配置文件 和 映射文件,在編寫這兩個映射文件之前,必須創建mybatis環境(jar包等)
創建java工程
3.1、jar包
mysql(1)
Mybatis(1個核心包+9個依賴包)
總共11個jar
3.2、初始化數據庫腳本
暫時只需要一張表 id是自增的,為主鍵
3.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
3.4、全局配置文件
建議使用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>
3.5、映射文件和操作
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>
該映射文件是為了解決jdbc中statement的硬編碼的問題,所以,在此映射文件中,只需要指定輸入參數類型,返回結果參數類型,sql語句等就差不多了,也就是將原本jdbc所遇到的硬編碼問題全部是使用xml配置文件來替代,有什么需要就修改配置文件即可,現在來看看該映射文件是如何編寫的。
通過增刪改查這四個操作來講解。
3.6.1、查詢 按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 //根據用戶id進行查詢。findUserById 2 @Test 3 public void test() throws IOException{ 4 //跟hibernate一樣,需要獲取一大堆東西 5 // 1、讀取配置文件 6 String resource = "SqlMapConfig.xml"; 7 InputStream inputStream = Resources.getResourceAsStream(resource); 8 // 2、根據配置文件創建SqlSessionFactory 9 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 10 // 3、SqlSessionFactory創建SqlSession 11 SqlSession sqlSession = sqlSessionFactory.openSession(); 12 // 4、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 //5、關閉sqlsession資源 24 sqlSession.close(); 25 }
3.6.2、查詢, 模糊查詢,對username字段進行模糊查詢
user.xml映射文件
操作
3.6.3、增加User, insert
user.xml,insert操作,對主鍵id有幾種不同的處理方式,具體看下圖的解釋
操作
3.6.4、刪除 delete
映射文件
操作
3.6.5、更新 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操作才能夠生效。
四、開發dao的方式
上面我們就單純測試了使用mybatis對數據庫的增刪改查操作,在開發中,我們都是開發dao接口和dao實現類,那么就在dao實現類中調用sqlsession的方法對數據庫的增刪改差操作即可。
4.1、dao接口
4.2、daoImpl 實現類
4.3、測試
小總結:
這樣開發有一個不好的地方,就是不能夠直接使用dao接口中的方法,而是使用的sqlSession中的方法,這樣讓人不能一目了然,所以我們在開發中都不使用這種方式進行開發,而是使用Mapper代理的方式,什么意思呢?接下來講講。
五、Mapper代理開發的方式
Mapper代理開發方式就是開發mapper接口(相當於dao接口)
1、mapper接口的全限定名要和mapper映射文件的namespace一致
2、mapper接口的方法名稱要和mapper映射文件的statement的id一致
3、mapper接口的方法參數類型要和mapper映射文件的statement的parameterType一致
4、mapper接口的方法返回值類型要和 mapper映射文件的statement的resultType一致
這樣直接看肯定不好理解,所以直接上代碼。
三樣東西,mapper接口,兩個配置文件,一個全局配置文件,一個映射文件,但是這個映射文件就有要求了,除了上面所說的四點之外,另外一點也最好遵循,這里用不到,但是后面會講解為什么會這樣使用,就是mapper接口的名稱要和映射文件的名稱相同,
mapper接口,UserMapper.java
映射文件,UserMapper.xml
全局配置文件。sqlMapConfig.xml
其他都跟上面一樣,重點講一下這個mappers加載映射文件的問題,為什么需要mapper接口和映射文件同名,並且放入同一目錄下
為了方便批量加載映射文件。而使用這種方式,前提條件就是接口和映射文件同名並且放入同一目錄下。
測試
直接調用方法名即可
六、總結
mybatis的基本用法就是這樣,我想大家應該都有點感覺了,就是在映射文件中編寫statement,將輸入參數和輸出結果進行映射,所以說mybatis是不完全映射的框架。懂了基本的用法之后,那么之后就會詳細講解其中的問題,全局配置文件當中的配置,映射文件中的詳細配置(高級映射),延遲加載,一級緩存二級緩存等用法。