这篇笔记主要记录如何使用MyBatis实现简单的增删改查,以及如何编写Mapper接口和XML配置。
这里我们还是使用MySQL数据库进行演示,我们使用的表t_role
如下。
create table netstore.t_role (
role_id bigint auto_increment primary key,
rolename varchar(255) not null
);
上一篇笔记的例子中,我们仅创建了实体类和Mapper的XML配置,这在引用Mapper时不方便。通常情况下,我们都会再创建一个Mapper接口,在接口中定义我们要实现的方法声明,包括方法名、参数和返回值。
Role.java
package com.gacfox.demomb.model;
import lombok.Data;
@Data
public class Role {
private Long roleId;
private String rolename;
}
RoleMapper.java
package com.gacfox.demomb.mapper;
import com.gacfox.demomb.model.Role;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface RoleMapper {
public Role queryRoleById(Long roleId);
public List<Role> queryRoleByRolename(String rolename);
public List<Role> queryAllRole();
public List<Role> queryRoleByPage(@Param("start_index") Integer startIndex, @Param("page_size") Integer pageSize);
public int insertRole(Role role);
public int deleteRole(Long roleId);
public int updateRole(Role role);
}
在Mapper接口中,我们实现了一些用作例子的增删改查方法。
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="com.gacfox.demomb.mapper.RoleMapper">
<!-- 具体的mapper方法实现会在后文介绍 -->
</mapper>
注意:namespace
属性对应接口的类全名。
Main.java
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Main.java
中,我们使用sqlSession.getMapper()
方式获取MyBatis生成的接口实现类,这样我们可以直接调用接口中的方法来执行数据库操作。此外,我们还需要在前一章中用到的mybatis-config.xml
里配置映射文件位置,配置后就可以正常使用了。
接口方法:
public Role queryRoleById(Long roleId);
对应XML配置:
<select id="queryRoleById" resultType="com.gacfox.demomb.model.Role">
select role_id as roleId, rolename
from t_role
where role_id = #{roleId}
</select>
说明以下几点:
select
的id
属性对应接口中的方法名resultType
对应实体类的类全名,这里Role
是该查询方法的返回值role_id as roleId
为查出的一个字段起了别名,这是为了和实体类的属性名对应,只有这两个名相同MyBatis才能自动映射#{}
包裹,里面的参数名需要和方法声明中的参数名对应@param
注解标注(上面就是),多个参数需要用注解标注,后面会给出例子查询一条结果的另一个例子:
public List<Role> queryRoleByRolename(String rolename);
<select id="queryRoleByRolename" resultType="com.gacfox.demomb.model.Role">
select role_id as roleId, rolename
from t_role
where rolename = #{rolename}
</select>
resultMap
手动映射查询结果之前的例子是MyBatis自动映射到Java实体类对象的,其中因为数据库中字段名是role_id
而实体类中对应属性名是roleId
,我们使用了as
指定别名MyBatis才能正常识别,除此之外我们还可以使用resultMap
实现手动进行映射。
<resultMap id="roleMap" type="com.gacfox.demomb.model.Role">
<id property="roleId" column="role_id"/>
<result property="rolename" column="rolename"/>
</resultMap>
<select id="queryRoleById" resultMap="roleMap">
select role_id, rolename
from t_role
where role_id = #{roleId}
</select>
<resultMap>
中:
id
:用于映射主键result
:用于映射普通字段除了上面介绍的用法,在关联查询中resultMap
还有其他的配置,将在后文介绍。
接口方法:
public List<Role> queryAllRole();
对应XML配置:
<select id="queryAllRole" resultType="com.gacfox.demomb.model.Role">
select role_id as roleId, rolename
from t_role
</select>
这里SQL语句返回的可能是一条结果、多条结果或是没有结果。方法的返回值是一个List
,返回结果可能里面有多条、1条、或是0条数据。
注意:
List
接收返回结果接口方法:
public List<Role> queryRoleByPage(@Param("start_index") Integer startIndex, @Param("page_size") Integer pageSize);
对应XML配置:
<select id="queryRoleByPage" resultType="com.gacfox.demomb.model.Role">
select role_id as roleId, rolename
from t_role
limit #{start_index},#{page_size}
</select>
这里传递了多个参数进行查询,注意参数需要用@param
进行标注,这个注解是org.apache.ibatis.annotations.Param
包的,不要和别的弄混。只有一个参数时,@param
可以省略,SQL中的参数名对应方法的参数名。
接口方法:
public int insertRole(Role role);
对应XML配置:
<insert id="insertRole" useGeneratedKeys="true" keyProperty="roleId">
insert into t_role(rolename)
values (#{rolename})
</insert>
由于我们使用了MySQL的自增长主键,因此我们需要在插入后得知该条数据主键值,useGeneratedKeys="true"
表示插入时使用数据库提供的主键自增长功能,keyProperty
是实体类中主键对应的字段名。这里SQL中的参数字段对应实体类中的属性名,实际上这也是传入多个参数的一种方式。
注意:MyBatis中执行插入操作,接口方法的返回值是受影响的列数,主键值在传入的对象中。
获取得到的主键值:
Role role = new Role();
role.setRolename("新角色");
mapper.insertRole(role);
System.out.println("pk=" + role.getRoleId());
接口方法:
public int deleteRole(Long roleId);
对应XML配置:
<delete id="deleteRole">
delete
from t_role
where role_id = #{roleId}
</delete>
接口方法:
public int updateRole(Role role);
对应XML配置:
<update id="updateRole">
update t_role
set rolename = #{rolename}
where role_id = #{roleId}
</update>