你的位置:首页 > Java教程

[Java教程]MyBatis学习笔记


一、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.

 1 <??> 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.

1 <??>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.

 1 <??> 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./>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.;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.

 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.

 1 <??> 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.-->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.

1 <??>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.

 1 <??> 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./>18     <!-- <mapper /> -->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.;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.

1 <??>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.selectBlog
at 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.selectBlog
at 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.

1 Blog blog = (Blog) session.selectOne("com.idonotknow.selectBlog", 1);

后,结果能正常显示。

现在来看参考文档的注释就比较容易了,命名空间的作用:将两个名字相同(可能指向不同的SQL语句)的对象区分开。在命名namespace的时候可以随意命名,只要在访问的时候用命名空间(如com.idonotknow)+id(如selectBlog)正确指向唯一的SQL即可。

(2)在写基于接口方式访问数据库时将BlogMapper.

1 <??>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.