主要内容
mybatis是什么
mybatis的前身是ibatis,被apache组织接管之后更名mybatis,是用于java程序的orm框架,据说,它比hibernate更轻量、更灵活、执行速度更快。
环境搭建
mybatis轻量的其中一个体现就是,相比其他框架,它对其他库的依赖性基本为零:mybatis只有一个库文件,导入这个库就可以开始工作。当然,mybatis需要连接数据库,否则就没有意义,所以,理所当然地,我们必须导入的库还有数据库的驱动程序(连接器)。下面是简单的项目结构:
第一个mybatis程序
如果使用原始的jdbc操作数据库,通常需要四个步骤:
- 注册驱动程序:Class.forName(“com.mysql.jdbc.Driver”);
- 建立数据库连接:DriverManager.getConnection();
- 使用Statement执行sql语句:statement.executeQuery();
- 使用ResultSet获取数据:resultSet.next
在mybatis中,这些步骤被SqlSession对象和配置文件取代。SqlSession是mybatis的核心,执行sql语句的方法都在SqlSession中定义,或者可以通过SqlSesson对象取得这些方法(自定义接口)。下面是一个简单的mybatis程序,对这两种情况进行简单演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class Main { public static void main(String[] args) throws IOException { //配置文件名称 String resource = "mybatis-config.xml"; //读取配置文件 InputStream resourceAsStream = Resources.getResourceAsStream(resource); //创建sqlSessionFactory SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream); //创建SqlSession对象 SqlSession sqlSession = build.openSession(); //方法一:通过sqlSession中定义的方法执行sql查询 User user = sqlSession.selectOne("cn.sharpcode.mapper.UserMapper.selectUser", 1); System.out.println(user.getUsername()); //方法二:通过自定义接口查询数据库 UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user1 = mapper.selectUser(1); System.out.println(user1.getUsername()); sqlSession.close(); } } |
SqlSession对象是最终需要的对象,创建它之前需要先获得SqlsessionFactory对象,而SqlSessionFactory必须通过SqlSessionFactoryBuilder对象获取。它们的基本关系是:
SqlSessionFactoryBuilder -> SqlSessionFactory -> SqlSession
UserMapper接口内容
1 2 3 4 5 6 7 8 |
package cn.sharpcode.mapper; import cn.sharpcode.po.User; public interface UserMapper { public User selectUser(Integer id); } |
UserMapper接口里面定义的是方法签名,当然方法签名并不是随意起的,它必须和映射器配置文件中的定义匹配。
User类的内容
User类只是一个简单的java bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package cn.sharpcode.po; public class User { private Integer id; private String username; private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } |
mybatis工作原理简介
从配置文件说起
如果使用jdbc的话,传递给executeXXX()方法的字符串通常是一个合法的sql语句;但是从上面的代码观察,selectOne的方法参数更像一个方法名称;实际上,该参数是一个标识符,它可以是任何形式的字符串,但必须具有唯一性。在程序执行的时候,mybatis通过该标识找到应该执行的sql语句。
而通过自定义接口方式执行sql,接口中的方法最终会以代理的方式被实现。
主配置文件
mybatis中的配置文件有两种,它们是主配置文件和映射器配置文件。
上面代码中的mybatis-config.xml
就是主配置文件,先了解它的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///shiro?useSSL=true"/> <property name="username" value="root"/> <property name="password" value=""/> </dataSource> </environment> </environments> <mappers> <mapper resource="cn/sharpcode/mapper/UserMapper.xml"/> </mappers> </configuration> |
除了mysql的连接设置外,我们主要了解的是mappers中的东西。mappers元素中定义的就是映射器,无论采用哪一种方法查询数据库,映射器都是必须的,因为映射器里面定义的就是查询数据库的方法。映射器配置文件内容如下:
1 2 3 4 5 6 7 8 9 |
<?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"> <mapper namespace="cn.sharpcode.mapper.UserMapper"> <select id="selectUser" resultType="cn.sharpcode.po.User"> SELECT * FROM user WHERE id = #{id} </select> </mapper> |
namespace是必须的,当多个映射器配置文件中出现相同的id的时候,通过namespace就可以把它们区分开来。<select>元素是真正的价值所在,id属性定义的就是一个方法名称,resultType属性说明它的返回值是User对象,<select>元素中的文本内容就是它的方法体,#{id}是一个参数占位符,有多少个占位符表示该方法有多少个参数。也就是说,最终映射器会解析成下面的方法:
1 2 3 |
public User selectUser(Integer id){ select * from user where id = id; } |
使用properties元素
properties元素可以在主配置文件中使用,用来定义key/value类型的变量,定义后的变量可以在整个配置文件中被引用。例如上面文件中的数据库连接属性,它们中的值就可以利用properties元素抽取成变量,然后通过${key_name}
引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<configuration> <properties> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql:///shiro?useSSL=true" /> <property name="username" value="root" /> <property name="password" value="" /> </properties> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!-- 此处省略部分配置--> </configuration> |
mybatis执行流程
先说第一种方法(sqlSession.selectOne)的执行流程(不考虑错误):
- 第一步,调用sqlSession.selectOne()方法,
- 第二步,selectOne方法会根据传入的参数查找对应的映射器,然后解析里面定义的方法
- 第三步,执行解析的方法
然后是第二种方法(自定义接口)的执行流程:
这个方法需要我们创建一个接口,接口的内容上面已经贴出来,不再展示。它的执行流程如下:
- 第一步,调用sqlSession.getMapper()方法,目的是获取方法签名
- 第二步,通过上一步中返回的接口名称,解析同目录下同名的映射器文件,目的是解析接口方法的方法体
- 第三步,调用接口中定义的方法,返回结果
同样,上面的步骤考虑的是没有错误的情况。
简单总结
可见,两种方法的执行流程都大同小异,不同的是,第二种方法多了一个接口,好处是它没有硬编码的字符串,重构更加简单,因此,更推荐使用第二种方法操作数据库。
转载请注明:Pure nonsense » mybatis概述和环境搭建