随笔 - 1162  文章 - 0  评论 - 16  阅读 - 59万 

一、通用 CRUD

  1、提出问题:

    假设我们已经存在一张 tbl_employee 表,且已经有对应的实体类 Employee,实现 tbl_employee 表的 CRUD 操作需要做什么呢?

  2、实现方式:

    基于 MyBatis:

      ① 需要编写 EmployeeMapper 接口,并手动编写CRUD 方法;

      ② 提供 EmployeeMapper.xml 映射文件,并手动编写每个方法对应的 SQL 语句;

    基于 MP:

      ① 只需要创建 EmployeeMapper 接口,并继承 BaseMapper 接口,这就是使用 MP 需要完成的所有操作,甚至不需要创建  SQL 映射文件。

 

二、创建具体的 Mapper 接口

  创建 Mapper 接口:

复制代码
/**
 * 基于MyBatis:在Mapper接口中编写CRUD相关的方法,提供mapper接口所对应的 SQL映射文件以及方法对应的SQL语句。
 *
 * 基于MP:让 XxxMapper 接口继承 BaseMapper 接口即可。
 *         BaseMapper<T> 泛型指定的就是当前Mapper接口所操作的实体类类型。
 *
 */
public interface EmployeeMapper extends BaseMapper<Employee> {
}
复制代码

 

三、BaseMapper 接口

  BaseMapper 接口中定义了大量关于 CRUD 的方法,所以在具体的 Mapper 接口中不需要我们在定义方法:

  

 

四、insert 系列

  1、insert 方法

    测试代码:

复制代码
    /**
     * 通用插入操作
     *
     * insert 方法在插入时,会根据实体类的每个属性进行非空判断,只有非空的属性对应的字段才会出现到 SQL语句中
     */
    @Test
    public void testCommonInsert() {
        Employee emp = new Employee(null, "Smith", "Smith@126.com", 1, 19);

        int i = employeeMapper.insert(emp);
        System.out.println("i = " + i);
        System.out.println(emp.getId());
    }
复制代码

 

    运行报错了:

 

    这是因为没有为实体类指定 id。

    选择主键策略:

    

     

 

     给id属性这是主键策略。

    修改 JavaBean 的属性:

    

 

     此时再运行:

 

     还是报错了,报错信息为 mybatis_plus.employee 表不存在。

    MP 在运行会根据类名去数据库中对应的表,如果找不到,就会报错。

    我们可以使用 @TableName 注解,来指定数据库对应的表名:

    

 

     再次运行:

 

    可以看到运行成功了,也已经向数据库发送了 SQL 语句,当成功插入后,MP也会将主键值回写到实体类中,可以直接获取到插入后的 id 值。

    支持主键值的数据库插入数据获取主键值:

      MyBatis:需要通过 useGeneratedKeys 以及 keyProperty 来设置;

      MP:自动将主键值回写到实体类中;    

 

  2、insertAllColumn

    测试:

复制代码
    /**
     *  insertAllColumn 方法在插入时,不管属性是否非空,属性所对应的字段都会出现在SQL语句中
     */
    @Test
    public void testInsertAllColumn() {
        Employee emp = new Employee();
        emp.setLastName("Enma");
        Integer r1 = employeeMapper.insertAllColumn(emp);
        System.out.println("r1 = " + r1);
    }
复制代码

 

    运行结果:

    

     只会插入非空的属性值。

 

五、update 系列

  1、update()

    Demo:

复制代码
    /**
     * 通用更新操作
     *  update:更新所有非空属性
     *  SQL 语句:
     *  Preparing: UPDATE tbl_employee SET email=?, age=? WHERE id=?
     *  Parameters: Tom@126.com(String), 23(Integer), 1(Integer)
     */
    @Test
    public void testCommonUpdate() {
        Employee emp = new Employee();
        emp.setId(1);
        emp.setEmail("Tom@126.com");
        emp.setAge(23);

        //更新非空属性
        Integer r1 = employeeMapper.updateById(emp);
        System.out.println("r1 = " + r1);
    }
复制代码

 

  2、updateAllColumnById()

    Demo:

复制代码
    /**
     *  通用更新操作
     *  updateAllColumnById:根据id更新所有的属性
     *  SQL 语句:
     *  Preparing: UPDATE tbl_employee SET last_name=?,email=?,gender=?,age=? WHERE id=?
     *  Parameters: null, Tom@126.com(String), null, null, 11(Integer)
     */
    @Test
    public void testCommonUpdateAllColumnById() {
        Employee emp = new Employee();
        emp.setId(11);
        emp.setEmail("Tom@126.com");

        Integer rs = employeeMapper.updateAllColumnById(emp);
        System.out.println("rs = " + rs);
    }
复制代码

 

六、delete 系列

  1、deleteById()

    Demo:

复制代码
    /**
     * 1.根据id删除
     *  SQL 语句:
     *  Preparing: DELETE FROM tbl_employee WHERE id=?
     *  Parameters: 11(Integer)
     */
    @Test
    public void testDeleteById() {
        Integer r1 = employeeMapper.deleteById(11);
        System.out.println("r1 = " + r1);
    }
复制代码

 

  2、deleteBatchIds()

    Demo:

复制代码
    /**
     * 2.根据id批量删除
     * SQL 语句:
     *  Preparing: DELETE FROM tbl_employee WHERE id IN ( ? , ? )
     *  Parameters: 10(Integer), 9(Integer)
     */
    @Test
    public void testDeleteBatchIds() {
        Integer r1 = employeeMapper.deleteBatchIds(Arrays.asList(10, 9));
        System.out.println("r1 = " + r1);
    }
复制代码

 

  3、DeleteByMap()

    Demo:

复制代码
    /**
     * 3.根据条件进行删除  map的key需要是数据库的列名
     * SQL 语句:
     *  Preparing: DELETE FROM tbl_employee WHERE gender = ? AND last_name = ? AND id = ?
     *  Parameters: 1(Integer), Smith(String), 8(Integer)
     */
    @Test
    public void testDeleteByMap() {
        HashMap<String, Object> columnMap = new HashMap<String, Object>(){{
            put("last_name", "Smith");
            put("gender", 1);
            put("id", 8);
        }};

        Integer r1 = employeeMapper.deleteByMap(columnMap);
        System.out.println("r1 = " + r1);
    }
复制代码

 

七、select 系列

  1、selectById()

    Demo:

复制代码
    /**
     * 1、通过id查询
     * SQL语句:
     *  Preparing: SELECT id AS id,last_name AS lastName,email,gender,age FROM tbl_employee WHERE id=?
     *  Parameters: 1(Integer)
     */
    @Test
    public void testSelectById() {
        Employee emp = employeeMapper.selectById(1);
        System.out.println("emp = " + emp);
    }
复制代码

 

  2、selectOne()

    Demo:

复制代码
    /**
     *  2、通过多个列进行查询 id + lastName  selectOne只能查询一条记录
     *  SQL 语句:
     *  Preparing: SELECT id AS id,last_name AS lastName,email,gender,age FROM tbl_employee WHERE id=? AND last_name=? AND gender=?
     *  Parameters: 8(Integer), Smith(String), 1(Integer)
     */
    @Test
    public void testSelectOne() {
        Employee employee = new Employee();
        employee.setId(8);
        employee.setLastName("Smith");
        employee.setGender(1);

        Employee emp = employeeMapper.selectOne(employee);
        System.out.println("emp = " + emp);
    }
复制代码

 

    注意:使用 selectOne() 方法必须要确保只能查询回来一条数据,如果查询多条就会报错。

 

  3、selectBatchIds()

    Demo:

复制代码
    /**
     * 3.通过多个id进行批量查询
     * SQL 语句:
     *  Preparing: SELECT id AS id,last_name AS lastName,email,gender,age FROM tbl_employee WHERE id IN ( ? , ? , ? )
     *  Parameters: 1(Integer), 2(Integer), 3(Integer)
     */
    @Test
    public void testBatchIds() {
        List<Employee> emps = employeeMapper.selectBatchIds(Arrays.asList(1, 2, 3));
        emps.forEach(System.out::println);
    }
复制代码

 

  4、selectByMap()

    Demo:

复制代码
    /**
     * 4. 通过map封装条件查询,map中的key需要是数据库中的列名而不是JavaBean的属性名
     * SQL 语句:
     *  Preparing: SELECT id AS id,last_name AS lastName,email,gender,age FROM tbl_employee WHERE gender = ? AND last_name = ?
     *  Parameters: 1(Integer), Smith(String
     */
    @Test
    public void testSelectByMap() {
        HashMap<String, Object> columnMap = new HashMap<String, Object>(){{
            put("last_name", "Smith");
            put("gender", 1);
        }};

        List<Employee> emps = employeeMapper.selectByMap(columnMap);
        emps.forEach(System.out::println);
    }
复制代码

 

  5、selectPage()

    Demo:

复制代码
    /**
     * 5. 分页查询
     *
     * SQL语句:
     *  Preparing: SELECT id AS id,last_name AS lastName,email,gender,age FROM tbl_employee
     *  Parameters:   
     * 底层还是使用 RowBounds 实现,使用内存的分页方式
     */
    @Test
    public void testSelectPage() {
        List<Employee> emps = employeeMapper.selectPage(new Page<>(2, 3), null);

        emps.forEach(System.out::println);
    }
复制代码

 

    Page 对象是我们用于设置分页辅助类,第一个参数为当前页码,第二个参数为要显示的行数。

    Page 的继承树:

    

 

     Page 是 RowBounds 的子类,是用于实现分页辅助类。

    构造方法

    

 

八、通用 CRUD 总结

  以上是基本的 CRUD 操作,在声明接口的时候仅仅需要继承一个 BaseMapper 即可实现大部分单表 CRUD 操作。BaseMapper 提供了多大 17个方法供我们使用,可以极其方便的实现单一、批量、分页等操作,极大的减少开发负担。

  现在有一个需求,我们需要分页查询 Employee 表中,年龄在 18-50 之间性别为男且姓名为 xx 的所有用户,这时候该如何实现上述需求呢?》

  MyBatis:需要在 SQL 映射文件中编写带条件查询的 SQL,并基于 PageHelper 插件完成分页,实现以上一个简单的需求,往往需要做很多重复单调工作。普通的 Mapper 能够解决这类痛点吗?

  MP:依旧不用编写 SQL 语句,MP 提供了功能强大的条件构造器 EntityWrapper。

 

posted on   格物致知_Tony  阅读(113)  评论(0编辑  收藏  举报
编辑推荐:
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
历史上的今天:
2019-09-21 单链表 案例
2019-09-21 单链表
点击右上角即可分享
微信分享提示

目录导航