MyBatis 教程

👉 所有文章
文章列表 准备工作 回顾 JDBC 数据准备 查找id为1的用户信息 自定义连接池 不用MyBatis配置文件 查询密码为123的所有用户 如果Bean中成员变量和表中字段命名不一致 更多查询用户的方式 对查询结果排序 日志 添加、删除、修改数据 事务 动态SQL 一对一和一对多的实现 一对一和一对多的延迟加载 多对多的实现 分页查询 把SQL写在注解中 自动生成Mapper代码和映射XML mybatis generator 生成 select for update mybatis generator 支持数据版本号

MyBatis: 添加、删除、修改数据


本节示例代码在 mybatis-demo-009

数据准备

数据准备

项目结构

使用 IDEA 创建 gradle 项目,最终结构如下:

添加数据

在 UserMapper 接口中定义方法:

/**
 * 根据 id 查询用户
 */
User findById(Long id);

在 UserMapper.xml 中编写映射:

<!--insertUser-->
<insert id="insertUser" parameterType="bean.User" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO blog_db.user (name, email, password)
    VALUES (#{name}, #{email}, #{password})
</insert>

<insert> 中id为insertUser,和方法对应UserMapper接口中方法一致。parameterType和方法insertUser的参数类型一致。

我们的SQL语句,只插入了User的name、email、password,主键id依靠数据库的自动生成。在官方文档《Mapper XML 文件》中如下介绍useGeneratedKeys和keyProperty属性:

useGeneratedKeys:(仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。

keyProperty: (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

不太明白为什么会对update有用。先不管。

通过设置useGeneratedKeys和keyProperty属性,可以将生成的id注入到user对象的id字段中。

在Main类中编写示例代码:

import java.io.IOException;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import bean.User;
import mapper.UserMapper;
import org.junit.Test;


@Slf4j
public class Main {

    @Test
    public void test_insertUser() throws IOException {
        SqlSession sqlSession = getSqlSession(false);
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setName("xiaowei");
        user.setEmail("xiaowei@111.com");
        user.setPassword("456");

        try {
            int result = userMapper.insertUser(user);
            log.info("result: {}, user: {}", result, user);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }

    private SqlSession getSqlSession(boolean autoCommit) throws IOException {
        SqlSessionFactory sessionFactory;
        sessionFactory = new SqlSessionFactoryBuilder()
                .build(Resources.getResourceAsReader("mybatis-config.xml"));
        return sessionFactory.openSession(autoCommit);
    }

}

创建sqlSession时,我们新增了一个布尔参数 autoCommit。如字面意思,如为true,则开启自动commit,也就是每个insert、update、delete操作都会确确实实的将数据修改写入数据库中。而如果是false,则必须在一系列操作后,加上sqlSession.commit(),才能将数据修改真正写入数据库。

运行 test_insertUser 函数,结果:

 INFO [main] - result: 1, user: User(id=3, name=xiaowei, email=xiaowei@111.com, password=456)

新添加的记录id为3。

查看数据库:

mysql> select * from user;
+----+---------+-----------------+----------+
| id | name    | email           | password |
+----+---------+-----------------+----------+
|  1 | letian  | letian@111.com  | 123      |
|  2 | xiaosi  | xiaosi@111.com  | 123      |
|  3 | xiaowei | xiaowei@111.com | 456      |
+----+---------+-----------------+----------+
3 rows in set (0.00 sec)

根据 id 更新密码

在 UserMapper 接口中定义方法:

/**
 * 根据 id 更新密码
 * @return 影响的行数
 */
int updateUserPasswordById(User user);

在 UserMapper.xml 增加映射:

<update id="updateUserPasswordById" parameterType="bean.User">
    UPDATE blog_db.user
    SET password=#{password}
    WHERE id=#{id}
</update>

updateUserPasswordById 方法的参数是User类,在xml映射中User的变量会被解析出来,所以可以用占位符#{password}#{id}

在Main类中编写示例代码:

@Test
public void test_updateUserPasswordById() throws IOException {
    SqlSession sqlSession = getSqlSession(false);
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = new User();
    user.setId(3L);
    user.setPassword("123456");

    try {
        int result = userMapper.updateUserPasswordById(user);
        log.info("result: {}, user: {}", result, user);
        sqlSession.commit();
    } finally {
        sqlSession.close();
    }
}

运行结果:

 INFO [main] - result: 1, user: User(id=3, name=null, email=null, password=123456)

查看数据库:

mysql> select * from user;
+----+---------+-----------------+----------+
| id | name    | email           | password |
+----+---------+-----------------+----------+
|  1 | letian  | letian@111.com  | 123      |
|  2 | xiaosi  | xiaosi@111.com  | 123      |
|  3 | xiaowei | xiaowei@111.com | 123456   |
+----+---------+-----------------+----------+
3 rows in set (0.00 sec)

可以看到 id为3的记录的密码从456变成了123456。

删除指定 id 的记录

在 UserMapper 接口中定义方法:

/**
 * 删除指定id的记录
 * @return 影响的行数
 */
int deleteById(Long id);

在 UserMapper.xml 增加映射:

<delete id="deleteById" parameterType="Long">
    DELETE FROM blog_db.user WHERE id=#{id}
</delete>

在Main类中编写示例代码,删除id为3的记录:

@Test
public void test_deleteById() throws IOException {
    SqlSession sqlSession = getSqlSession(false);
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    try {
        int result = userMapper.deleteById(3L);
        log.info("result: {}", result);
        sqlSession.commit();
    } finally {
        sqlSession.close();
    }
}

运行结果:

 INFO [main] - result: 1

因为id为3的记录已经被删除了,所以若再运行一次,结果为:

 INFO [main] - result: 0

查看数据库:

mysql> select * from user;
+----+--------+----------------+----------+
| id | name   | email          | password |
+----+--------+----------------+----------+
|  1 | letian | letian@111.com | 123      |
|  2 | xiaosi | xiaosi@111.com | 123      |
+----+--------+----------------+----------+
2 rows in set (0.00 sec)

删除指定 id 范围的记录

在 UserMapper 接口中定义方法:

/**
 * 删除id在 [minId, maxId] 范围内的记录
 * @return 影响的行数
 */
int deleteByIdRange(Long minId, Long maxId);

在 UserMapper.xml 增加映射:

<delete id="deleteByIdRange">
    <![CDATA[
        DELETE FROM blog_db.user WHERE id >= #{param1} and id <= #{param2}
    ]]>
</delete>

在Main类中编写示例代码,删除id为1到2的记录:

@Test
public void test_deleteByIdRange() throws IOException {
    SqlSession sqlSession = getSqlSession(false);
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    try {
        int result = userMapper.deleteByIdRange(1L, 2L);
        log.info("result: {}", result);
        sqlSession.commit();
    } finally {
        sqlSession.close();
    }
}

运行结果:

 INFO [main] - result: 2

查看数据库:

mysql> select * from user;
Empty set (0.00 sec)

没有数据了,符合预期 😆


( 本文完 )

文章目录