目录
任务描述
本关任务:学习MyBatis
框架的基础使用,通过MyBatis
框架向MySQL
数据库中插入和删除数据。
相关知识
Mybatis 简介
MyBatis
的前身是 Apache 的开源项目iBatis
。iBatis
一词来源于internet
和 abatis
的组合,是一个基于Java
的持久层框架。2010 年这个项目由Apache software foundation
迁移到 Google code
,并更名为MyBatis
。 2013 年 11 月, MyBatis
源代码迁移到GitHub
网站上,目前由GitHub
提供维护。
MyBatis
的优势在于灵活,它几乎可以代替JDBC
,避免了几乎所有的JDBC
代码和手动设置参数以及获取结果集。同时提供了接口编程。目前MyBatis
的数据访问层 DAO
(Data Access Objects))是不需要实现类的,它只需要一个接口和XML
(或者注解)。MyBatis
提供自动映射、动态SQL
、级联、缓存、注解、代码和SQL
分离等特性,使用方便,同时也可以对SQL
进行优化。因为其具有封装少、映射多样化、支持存储过程、可以进行SQL
优化等特点,使得它成为了国内Java
互联网中首选的持久框架。
MyBatis简单使用
MyBatis
作为持久层框架,会涉及数据库。我们首先定义一个数据库表一一角色表(role
),其结构如图示。
图1 角色表
根据这个角色表,我们可以定义一个POJO
(Plan Ordinary Java Object),使它的字段和这张表定义的字段一一对应起来,如下面代码所示。
//对应数据库中表role的Role类
public class Role
{
private Integer id;
private String roleName;
private String remark;
/** setter and getter 方法忽略**/
}
Mybatis
和其他持久层框架都是依靠某种方法,将数据库的表和POJO
映射起来的,这样我们就可以通过操作POJO
来完成相关的数据库操作逻辑,同时我们把POJO
对象和数据库表相互映射的框架称为对象关系映射(Object Relational Mapping,ORM)框架。要将POJO
和数据库映射起来需要给这些框架提供映射规则,所以下一步要提供映射的规则,如下图所示。
图2 映射规则
MyBatis
支持XML
和注解两种方式提供映射规则,这里采用XML
方式。下面的XML
配置文件指定了数据库表role
和POJO
对象Role
对应起来的规则。
<?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="net.educoder.mapper.RoleMapper">
<resultMap id="BaseResultMap" type="net.educoder.pojo.Role">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="roleName" jdbcType="VARCHAR" property="roleName" />
<result column="remark" jdbcType="VARCHAR" property="remark" />
</resultMap>
<!-- 通过select元素声明一个查询语句-->
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
id, roleName, remark
from role
where id = #{id,jdbcType=INTEGER}
</select>
<!-- 通过update元素声明一个更新语句-->
<update id="updateByPrimaryKey" parameterType="net.educoder.pojo.Role">
update role
set roleName = #{roleName,jdbcType=VARCHAR},
remark = #{remark,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
</mapper>
这里resultMap
元素用于定义映射规则,指定POJO
中的属性和数据库表中的对应关系,而增、删、查、改对应着insert
、delete
、select
、update
四个元素。要注意的是,mapper
元素中的namespace
属性要和一个接口的全限定名保持一致,这里的接口是RoleMapper
,而里面SQL
元素的id
要和接口定义的方法名完全保持一致,定义MyBatis
映射文件RoleMapper
,代码如下。
public interface RoleMapper {
Role selectByPrimaryKey(Integer id);
int updateByPrimaryKey(Role record);
}
在selectByPrimaryKey
中,我们传递的参数是Integer
类型的id
,这与 XML 文件中parameterType
的值是对应起来的。把传递给selectByPrimaryKey
的参数赋值给SQL
语句,采用的方式是#{列名,列的数据类型}
,Mybatis
框架会自动完成参数的赋值工作。
我们可以看到,定义的MyBatis
映射文件是一个接口,那要不要创建一个接口的实现类呢?答案是不需要。定义了映射规则(XML
文件)和映射文件(Java
接口),接下来就可以完成对角色类的增、删、改和查,如下代码片段所示。
public class MybatisTest {
public static void main(String[] args) {
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
//mybatis-config.xml里指定所使用的MySQL地址和数据库信息
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
sqlSession = sqlSessionFactory.openSession();
// 上面代码是获取MyBatis操作数据库的session对象
//操作数据库开始
//先获取对应的RoleMapper对象
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
//查询表role中id为1的记录
Role role = roleMapper.selectByPrimaryKey(1);
//输出查询结果
System.out.println(role);
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭session对象,释放数据库连接
if (null != sqlSession) {
sqlSession.commit();
sqlSession.close();
}
}
}
}
可以看到,在获取了表role
对应的RoleMapper
类的对象后,操作数据库就只需要调用RoleMapper
的方法即可。
编程要求
框架的相关依赖已经配置好,请根据提示,在右侧编辑器补充 Begin-End 区间代码,完成通过 MyBatis 对role
表插入和删除功能。
- 在
RoleMapper.java
中声明两个方法,插入数据的方法int insertRole(Role record)
和通过主键id
删除表role
中记录的方法int deleteById(int id)
。 - 在
XML
映射文件中补全insertRole
和deleteById
两个方法对应的映射规则。
测试说明
测试代码首先会调用insertRole
方法插入数据,然后调用selectByPrimaryKey
方法查询插入的数据,最后调用deleteById
方法删除: 预期输出:
Role{id=1001, RoleName='RoleName1001', remark='remark1001'}
测试通过
测试框架主要代码如下:
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
//定义一个role对象
Role insertRole=new Role();
insertRole.setId(1001);
insertRole.setRoleName("RoleName1001");
insertRole.setRemark("remark1001");
//插入role对象
roleMapper.insertRole(insertRole);
//通过id查询,是否插入成功
Role role = roleMapper.selectByPrimaryKey(1001);
System.out.println(role);
//删除操作
roleMapper.deleteById(1001);
//查询是否删除成功
role = roleMapper.selectByPrimaryKey(1001);
if(role==null){
System.out.println("测试通过");
}
参考代码
RoleMapper.java
package net.educoder.mapper;
import net.educoder.pojo.Role;
public interface RoleMapper {
/********** Begin *********/
//插入数据
int insertRole(Role record);
//通过id删除
int deleteById(Integer id);
/********** End *********/
//查询
Role selectByPrimaryKey(Integer id);
//更新
int updateByPrimaryKey(Role record);
}
RoleMapper.xml
<?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="net.educoder.mapper.RoleMapper">
<resultMap id="BaseResultMap" type="net.educoder.pojo.Role">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="roleName" jdbcType="VARCHAR" property="roleName" />
<result column="remark" jdbcType="VARCHAR" property="remark" />
</resultMap>
<!--在Begin和End之间补充代码-->
<!-- ********** Begin ********* -->
<!--删除元素,id对应RoleMapper中的insertRole方法-->
<insert id="insertRole" parameterType="net.educoder.pojo.Role">
insert into role
values (#{id,jdbcType=INTEGER},#{roleName,jdbcType=VARCHAR},#{remark,jdbcType=VARCHAR})
</insert>
<!--删除元素,id对应RoleMapper中的deleteById方法-->
<delete id="deleteById" parameterType="java.lang.Integer">
delete from role where id = #{id, jdbcType=INTEGER}
</delete>
<!-- ********** End ********* -->
<!-- 通过select元素声明一个查询语句-->
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
id, roleName, remark
from role
where id = #{id,jdbcType=INTEGER}
</select>
<!-- 通过update元素声明一个更新语句-->
<update id="updateByPrimaryKey" parameterType="net.educoder.pojo.Role">
update role
set roleName = #{roleName,jdbcType=VARCHAR},
remark = #{remark,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>