增删改查

这篇笔记主要记录如何使用MyBatis框架实现简单的单表增删改查,以及如何编写Mapper接口和XML映射配置。

环境准备

这里我们还是使用MySQL数据库进行演示,我们使用的表t_role如下。

create table t_role (
    role_id  bigint auto_increment primary key,
    rolename varchar(255) not null
);

数据表对应的实体类如下。

Role.java

package com.gacfox.demomb.model;

import lombok.Data;

@Data
public class Role {
    private Long roleId;
    private String rolename;
}

我们这里现创建一个空的映射XML配置,后续介绍的XML配置都是基于该例子配置文件的。

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属性对应接口的类全名。

查询

查询单条结果

查询单条结果我们的Mapper接口方法就要返回单个实体类对象,接口方法如下。

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>

该Mapper方法将查询单条记录,如果查询无结果返回null,如果返回多条将抛出异常。如果我们不能保证SQL返回的结果是单条数据记录就应该使用查询多条的写法,即返回类型为List<Role>

这里我们注意以下几点:

  1. selectid属性对应接口中的方法名
  2. resultType对应实体类的类全名,这里Role是该查询方法的返回值
  3. SQL语句中,role_id as roleId为查出的一个字段起了别名,这是为了和实体类的属性名对应,只有这两个名相同MyBatis才能自动映射(这是一种比较投机取巧的写法, 更好的方式是使用resultMap映射配置,我们将在后文介绍)
  4. 方法声明中的参数在XML中的SQL语句里需要用#{}包裹,里面的参数名需要和方法声明中的参数名对应
  5. 当Mapper方法只有一个参数时我们可以不用@param注解标注(上面就是这样),如果有多个参数就必须用注解标注,我们将在后文介绍

使用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还有级联查询相关的配置,我们将在后文介绍。

查询多条结果

查询多条结果需要返回列表类型,Mapper接口方法定义例子如下。

public List<Role> queryAllRole();

Mapper对应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接收返回结果(列表中仅有一条数据),然而如果不使用列表接收但返回了多条结果将抛出异常。

传递多个参数进行查询

前面我们提到过,如果Mapper方法参数有多个,就必须用@Param注解对参数起名。

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中的参数名是对应方法的参数名,当然,如果你有强迫症,那么所有Mapper方法参数都标注@param也是完全可以的。

插入

对于插入语句,我们需要传入包含数据的实体类对象,然后在Mapper映射XML中拼接INSERT插入语句。

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

删除

删除和插入类似,我们需要传入参数并拼接DELETE语句。

public int deleteRole(Long roleId);

对应XML配置如下。

<delete id="deleteRole">
    delete
    from t_role
    where role_id = #{roleId}
</delete>

对于插入方法,Mapper接口返回值也是受影响的行数。

修改

修改方法和插入、删除类似,我们需要传入参数拼接UPDATE语句。

public int updateRole(Role role);

对应XML配置如下。

<update id="updateRole">
    update t_role
    set rolename = #{rolename}
    where role_id = #{roleId}
</update>

和之前一样,Mapper接口返回值也是受影响的行数。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap