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>

示例项目

结构图如下:

image-20220419213239184

主要文件介绍

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);
}
}

}

执行结果:

image-20220516182656720

image-20220516182719554

注意事项

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。