MyBatis 框架
MyBatis源自apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
有下列特点:
MyBatis是一个半ORM(对象关系映射)框架,底层封装了JDBC,是程序员在开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。使得程序员可以花更多的精力放到业务开发中。另外,程序员直接编写原生态sql,严格控制sql执行性能,灵活度高。
MyBatis 可以使用简单的 XML文件 或注解方式来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由MyBatis 框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。
运作机制为:
加载配置:配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。
结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。
开发环境搭建
软件 |
版本 |
HGDB |
安全版V4、企业版v5及以上版本 |
JDK |
1.6、1.7、1.8 |
Java IDE |
Eclipse、IntelliJ IDEA |
MyBatis |
3.5.2 |
前提准备
要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于类路径(classpath)中即可。
如果使用 Maven 来构建项目,则需将下面的依赖代码置于 pom.xml 文件中:
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version> </dependency>
|
示例项目
结构图如下:
主要文件介绍:
pom.xml
:导入依赖的jar包
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <!--highgo jdbc--> <dependency> <groupId>com.highgo</groupId> <artifactId>HgdbJdbc</artifactId> <version>6.2.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <!--Spring操作数据库需要一个spring-jdbc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency> </dependencies>
|
mybatis-config.xml
:编写全局配置文件(主要是配置数据源信息)
<?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> <typeAliases> <package name="com.highgo.pojo"/> </typeAliases>
<environments default="development"> <environment id="development"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.highgo.jdbc.Driver"/> <property name="url" value="jdbc:highgo://192.168.2.5:5866/test"/> <property name="username" value="test"/> <property name="password" value="test"/> </dataSource> </environment> </environments>
<mappers> <mapper class="com.highgo.mapper.UserMapper"/> </mappers> </configuration>
|
User.java
:创建一个pojo类
package com.highgo.pojo; import lombok.*;
import java.util.Date;
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @ToString public class User { private int id; private String name; private Date birthday;
}
|
UserMapper.xml
:编写mapper映射文件(编写SQL)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.highgo.mapper.UserMapper"> <select id="selectAll" resultType="User"> select * from test_user; </select>
<insert id="addUser" parameterType="com.highgo.pojo.User"> INSERT INTO test_user (name,birthday) VALUES (#{name},#{birthday}); </insert>
<delete id="deleteUser" parameterType="int"> DELETE FROM test_user WHERE id = #{id}; </delete>
<select id="findByName" parameterType="string" resultType="User"> SELECT * FROM test_user WHERE name like '%${value}%'; </select>
</mapper>
|
UserMapper.java
:创建一个mapper接口
package com.highgo.mapper; import com.highgo.pojo.User; import java.util.List;
public interface UserMapper { public List<User> selectAll();
public int addUser(User user);
public int deleteUser(int id);
List<User> findByName(String value); }
|
MyTest.java
:测试代码
public class MyTest {
private SqlSessionFactory sqlSessionFactory;
@Before public void init() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); }
@Test public void insertTest() { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user=new User(); user.setName("Tomcat"); user.setBirthday(new Date()); mapper.addUser(user); sqlSession.commit(); }
@Test public void findAllTest() { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> userList = mapper.selectAll(); for (User user : userList) { System.out.println(user); } }
@Test public void findByName() { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> userList = mapper.findByName("张"); for (User user : userList) { System.out.println(user); } }
}
|
执行结果:
注意事项
1、mapper接口和mapper.xml之间需要遵循一定规则,才能成功的让MyBatis 将mapper接口和mapper.xml绑定起来
- mapper接口的全限定名,要和mapper.xml的namespace属性一致
- mapper接口中的方法名要和mapper.xml中的SQL标签的id一致
- mapper接口中的方法入参类型,要和mapper.xml中SQL语句的入参类型一致
- mapper接口中的方法出参类型,要和mapper.xml中SQL语句的返回值类型一致
2、Map传值
在 MyBatis 的 mapper.xml 中我们很多时候喜欢使用 Map 传值,如下:
<select id= "getList" resultType= "java.util.Map" parameterType = "java.util.Map" > SELECT user_id, user_name FROM sysuser </select>
|
这里我们使用 Map 作为 resultType 和 parameterType,为提高代码可维护性,建议使用实体类传值,改为如下:
<select id= "getList" resultType= "com.entity.SysUser" parameterType = "com.entity.SysUser"> SELECT user_id, user_name FROM sysuser </select>
|
3、MyBatis 分页
方式一:直接在 mapper.xml 文件中写的分页语法
如下:
<select id= "getList" parameterType= "SysUser" resultMap= "SysUser" > SELECT user_id, user_name FROM sysuser limit #{pageSize} offset #{pageIndex} </select>
|
需要将所有用到分页的地方都修改为 HGDB 支持的语法。因为每个文件都需要替换,因此管理起来还是不方便。
方式二:使用分页插件
在使用 MyBatis 框架时,分页方式可以用拦截器实现。比如Pagehelper分页插件,具体使用请参考Pagehelper。Pagehelper进行 HGDB 分页时,需要将 Pagehelper的 helperDialect配置为“postgresql”,或者修改 Pagehelper的分页 sql 为 HGDB 支持的语法。
在不同版本的 Pagehelper中,有些版本可能本身没有实现“postgresql”这个配置;此时可考虑更换 Pagehelper版本,或者自己去用代码实现“postgresql”配置,或者直接修改 Pagehelper的分页 sql。