一、MyBatis介紹
MyBatis項目主頁:https://github.com/mybatis/mybatis-3。
二、環境搭建
(1)新建項目MyBatisDemo,如下圖所示

(2)導入相關jar包,包括MyBaits和MySQL驅動,導入后的項目結構如下圖所示

(3)創建數據庫和數據庫表
1 create database mybatisdemo character set gbk;2 use mybatisdemo;3 create table blog (id int PRimary key,title varchar(20),author varchar(20));4 insert into blog(id,title,author) values(1,"第一篇博客","cat tom");5 insert into blog(id,title,author) values(2,"第二篇博客","cat");
準備工作已經完成。
三、使用MyBatis完成數據庫查詢
(1)編輯MyBatis的配置文件mybatis-config.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 3 <configuration> 4 <environments default="development"> 5 <environment id="development"> 6 <transactionManager type="JDBC" /> 7 <dataSource type="POOLED"> 8 <property name="driver" value="com.mysql.jdbc.Driver" /> 9 <property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo" />10 <property name="username" value="root" />11 <property name="passWord" value="root" />12 </dataSource>13 </environment>14 </environments>15 </configuration>
(2)定義數據庫表對應的實體類
1 package com.cattom.entity; 2 3 /** 4 * blog表對應的實體類 5 */ 6 public class Blog { 7 8 /* 實體類屬性與表的字段一一對應 */ 9 private int id;10 private String title;11 private String author;12 13 public int getId() {14 return id;15 }16 17 public void setId(int id) {18 this.id = id;19 }20 21 public String getTitle() {22 return title;23 }24 25 public void setTitle(String title) {26 this.title = title;27 }28 29 public String getAuthor() {30 return author;31 }32 33 public void setAuthor(String author) {34 this.author = author;35 }36 37 }(3)定義操作blog表的SQL映射文件BlogMapper.xml
1 <?xml version="1.0" encoding="UTF-8"?>2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">3 <mapper namespace="com.cattom.mapping.BlogMapper">4 <select id="selectBlog" resultType="com.cattom.entity.Blog">5 select * from blog where id=#{id}6 </select>7 </mapper>(4)在mybaits-config.xml中注冊BlogMapper.xml文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 3 <configuration> 4 <environments default="development"> 5 <environment id="development"> 6 <transactionManager type="JDBC" /> 7 <dataSource type="POOLED"> 8 <property name="driver" value="com.mysql.jdbc.Driver" /> 9 <property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo" />10 <property name="username" value="root" />11 <property name="password" value="root" />12 </dataSource>13 </environment>14 </environments>15 16 <mappers>17 <mapper resource="com/cattom/mapping/BlogMapper.xml"/>18 </mappers>19 </configuration>
(5)編寫測試代碼
1 package com.cattom.test; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 6 import org.apache.ibatis.io.Resources; 7 import org.apache.ibatis.session.SqlSession; 8 import org.apache.ibatis.session.SqlSessionFactory; 9 import org.apache.ibatis.session.SqlSessionFactoryBuilder;10 11 import com.cattom.entity.Blog;12 13 public class Test {14 15 public static void main(String[] args) throws IOException {16 String resource = "mybatis-config.xml";17 InputStream inputStream = Resources.getResourceAsStream(resource);18 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);19 SqlSession session = sqlSessionFactory.openSession();20 21 Blog blog = (Blog) session.selectOne("com.cattom.mapping.BlogMapper.selectBlog", 1);22 23 System.out.println("[id=" + blog.getId() + ", title=" + blog.getTitle() + ", author=" + blog.getAuthor() + "]");24 }25 26 }
(6)最終的項目結構圖如下

(7)運行結果

四、基于注解的方式使用MyBatis
(1)新建接口BlogMapper.java,并刪除BlogMapper.xml
1 package com.cattom.mapping; 2 3 import org.apache.ibatis.annotations.Select; 4 5 import com.cattom.entity.Blog; 6 7 public interface BlogMapper { 8 9 @Select("select * from blog where id=#{id}")10 Blog selectBlog(int id);11 12 }(2)在mybatis-config.xml文件中注釋掉<mappers />中相對于類路徑方式的<mapper />,并加入類名方式的<mapper />
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 3 <configuration> 4 <environments default="development"> 5 <environment id="development"> 6 <transactionManager type="JDBC" /> 7 <dataSource type="POOLED"> 8 <property name="driver" value="com.mysql.jdbc.Driver" /> 9 <property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo" />10 <property name="username" value="root" />11 <property name="password" value="root" />12 </dataSource>13 </environment>14 </environments>15 16 <mappers>17 <!-- <mapper resource="com/cattom/mapping/BlogMapper.xml"/> -->18 <mapper class="com.cattom.mapping.BlogMapper" />19 </mappers>20 </configuration>
(3)Test.java類的內容不變,如果將第21行改成如下方式也沒有問題
1 BlogMapper mapper = session.getMapper(BlogMapper.class);2 Blog blog = (Blog) mapper.selectBlog(1);
(4)修改后的項目結構

(5)運行結果

五、基于接口的方式使用MyBatis
(1)刪除BlogMapper.java中的@Select注解
1 package com.cattom.mapping;2 3 import com.cattom.entity.Blog;4 5 public interface BlogMapper {6 7 Blog selectBlog(int id);8 9 }(2)將刪除的BlogMapper.xml文件重新加入項目中
1 <?xml version="1.0" encoding="UTF-8"?>2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">3 <mapper namespace="com.cattom.mapping.BlogMapper">4 <select id="selectBlog" resultType="com.cattom.entity.Blog">5 select * from blog where id=#{id}6 </select>7 </mapper>(3)在mybatis-config.xml文件中注釋掉<mappers />中類名方式的<mapper />,并加入相對于類路徑方式的<mapper />
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 3 <configuration> 4 <environments default="development"> 5 <environment id="development"> 6 <transactionManager type="JDBC" /> 7 <dataSource type="POOLED"> 8 <property name="driver" value="com.mysql.jdbc.Driver" /> 9 <property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo" />10 <property name="username" value="root" />11 <property name="password" value="root" />12 </dataSource>13 </environment>14 </environments>15 16 <mappers>17 <mapper resource="com/cattom/mapping/BlogMapper.xml"/>18 <!-- <mapper class="com.cattom.mapping.BlogMapper" /> -->19 </mappers>20 </configuration>
(4)修改Test.java如下
1 package com.cattom.test; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 6 import org.apache.ibatis.io.Resources; 7 import org.apache.ibatis.session.SqlSession; 8 import org.apache.ibatis.session.SqlSessionFactory; 9 import org.apache.ibatis.session.SqlSessionFactoryBuilder;10 11 import com.cattom.entity.Blog;12 import com.cattom.mapping.BlogMapper;13 14 public class Test {15 16 public static void main(String[] args) throws IOException {17 String resource = "mybatis-config.xml";18 InputStream inputStream = Resources.getResourceAsStream(resource);19 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);20 SqlSession session = sqlSessionFactory.openSession();21 22 // Blog blog = (Blog) session.selectOne("com.cattom.mapping.BlogMapper.selectBlog", 1);23 BlogMapper mapper = session.getMapper(BlogMapper.class);24 Blog blog = (Blog) mapper.selectBlog(1);25 26 System.out.println("[id=" + blog.getId() + ", title=" + blog.getTitle() + ", author=" + blog.getAuthor() + "]");27 }28 29 }(5)此時的項目結構如下

(6)運行結果

六、命名空間(namespaces)的一點說明(踩過的坑)
(0)在MyBatis參考文檔中關于命名空間有如下的注釋
命名空間(Namespaces)在之前版本的 MyBatis 中是可選的,容易引起混淆因此是沒有益處的。現在的命名空間則是必須的,目的是希望能比只是簡單的使用更長的完全限定名來區分語句更進一步。
命名空間使得你所見到的接口綁定成為可能,盡管你覺得這些東西未必用得上,你還是應該遵循這里的規定以防哪天你改變了主意。出于長遠考慮,使用命名空間,并將它置于合適的 Java 包命名空間之下,你將擁有一份更加整潔的代碼并提高了 MyBatis 的可用性。
命名解析:為了減少輸入量,MyBatis 對所有的命名配置元素(包括語句,結果映射,緩存等)使用了如下的命名解析規則。
- 完全限定名(比如“com.mypackage.MyMapper.selectAllThings”)將被直接查找并且找到即用。
- 短名稱(比如“selectAllThings”)如果全局唯一也可以作為一個單獨的引用。如果不唯一,有兩個或兩個以上的相同名稱(比如“com.foo.selectAllThings ”和“com.bar.selectAllThings”),那么使用時就會收到錯誤報告說短名稱是不唯一的,這種情況下就必須使用完全限定名。
鏈接地址:http://mybatis.github.io/mybatis-3/zh/getting-started.html
(1)在寫第三節“使用MyBatis完成數據庫查詢”的時候,將BlogMapper.xml中namespace改為com.idonotkonw,
1 <?xml version="1.0" encoding="UTF-8"?>2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">3 <mapper namespace="com.idonotknow">4 <select id="selectBlog" resultType="com.cattom.entity.Blog">5 select * from blog where id=#{id}6 </select>7 </mapper>報告了如下異常:
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.cattom.mapping.BlogMapper.selectBlog### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.cattom.mapping.BlogMapper.selectBlogat org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:107)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:98)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:62)at com.cattom.test.Test.main(Test.java:21)Caused by: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.cattom.mapping.BlogMapper.selectBlogat org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:775)at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:615)at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:608)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:103)... 3 more
在Test.java的第21行訪問數據庫是的代碼為
1 Blog blog = (Blog) session.selectOne("com.cattom.mapping.BlogMapper.selectBlog", 1);selectOne方法的第一個參數為com.cattom.mapping.BogMapper.selectBlog,與BlogMapper.xml中的namespace不匹配,將代碼改為
1 Blog blog = (Blog) session.selectOne("com.idonotknow.selectBlog", 1);后,結果能正常顯示。
現在來看參考文檔的注釋就比較容易了,命名空間的作用:將兩個名字相同(可能指向不同的SQL語句)的對象區分開。在命名namespace的時候可以隨意命名,只要在訪問的時候用命名空間(如com.idonotknow)+id(如selectBlog)正確指向唯一的SQL即可。
(2)在寫基于接口方式訪問數據庫時將BlogMapper.xml中的namespace改為com.idonotkonw,
1 <?xml version="1.0" encoding="UTF-8"?>2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">3 <mapper namespace="com.idonotknow">4 <select id="selectBlog" resultType="com.cattom.entity.Blog">5 select * from blog where id=#{id}6 </select>7 </mapper>報如下異常
Exception in thread "main" org.apache.ibatis.binding.BindingException:Type interface com.cattom.mapping.BlogMapper is not known to the MapperRegistry.at org.apache.ibatis.binding.MapperRegistry.getMapper(MapperRegistry.java:42)at org.apache.ibatis.session.Configuration.getMapper(Configuration.java:639)at org.apache.ibatis.session.defaults.DefaultSqlSession.getMapper(DefaultSqlSession.java:218)at com.cattom.test.Test.main(Test.java:23)
這也是由namespace引起的問題。在Test.java中
1 BlogMapper mapper = session.getMapper(BlogMapper.class);2 Blog blog = (Blog) mapper.selectBlog(1);
我的猜測:第一行代碼將BlogMapper.java接口(包名+接口名)與BlogMapper.xml(namespace)對應起來((包名+接口名)=(namespace)),第二行代碼將BlogMapper.java接口的selectBlog方法與BlogMapper.xml中id為selectBlog的SQL語句對應起來。由于namespace="com.idonotknow"與猜測不符合,所以報告了異常,改回正確格式即可正確顯示結果。
新聞熱點
疑難解答