当前位置: > > > SpringBoot - MyBatis-Plus使用详解12(使用ActiveRecord模式进行增删改查)

SpringBoot - MyBatis-Plus使用详解12(使用ActiveRecord模式进行增删改查)

十二、使用 ActiveRecord 模式操作数据库

1,ActiveRecord 模式介绍

  • ActiveRecord(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。
  • ActiveRecord 一直广受动态语言( PHP Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅。
  • 不过 MyBatis-Plus 也在 AR 道路上进行了一定的探索,仅仅需要让实体类继承 Model 类且实现主键指定方法,即可开启 AR 之旅。

2,准备工作

(1)假设我们有如下用户信息表 user_info

(2)首先创建对应的实体类 UserInfo
注意:与之前不同的是,实体类需要继承 Model 类,并重写 pkVal 方法。
@Data
public class UserInfo extends Model<UserInfo> {
    private Integer id;
    private String userName;
    private String passWord;
    private Integer age;

    //重写这个方法,return当前类的主键
    @Override
    protected Serializable pkVal() {
        return id;
    }
}

(3)接着同样创建 UserInfoMapper 接口,并继承 BaseMapper 接口。
提示:虽然 AR 模式用不到该接口,但是一定要定义,否则使用 AR 时会报空指针异常。
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

3,新增数据

AR 操作是通过对象本身调用相关方法,比如要 insert 一个 user,那就用这个 user 调用 insert 方法即可。
UserInfo user = new UserInfo();
user.setUserName("hangge");
user.setPassWord("!0001");
user.setAge(100);

//AR插入操作,返回执行是否成功
Boolean success = user.insert();

4,修改数据

(1)使用实体对象的 updateById 方法可以根据主键 ID 更新对应的数据:
UserInfo user = new UserInfo();
user.setId(1);
user.setUserName("hangge");
user.setPassWord("!0001");
user.setAge(100);

//根据id修改数据,返回执行是否成功
Boolean success = user.updateById();

(2)使用实体对象的 update 方法可以通过实体对象封装操作类进行更新操作:
(1)数据更新相关的构造器(UpdateWrapperLambdaUpdateWrapperLambdaUpdateChainWrapper)使用方法类似于查询构造器(QueryWrapperLambdaQueryWrapperLambdaQueryChainWrapper),不同的是它增加了如下两个方法:
  • set:设置数据库字段值
  • setSql:设置 set 部分的 sql
(2)关于查询构造器(QueryWrapperLambdaQueryWrapperLambdaQueryChainWrapper)具体用法,可以查看我之前的文章:
// 查询条件:名字中包含'ha'并且年龄小于40
LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40);
// 将满足条件的记录密码都设置为8888
UserInfo user = new UserInfo();
user.setPassWord("8888");
//修改数据,返回执行是否成功
Boolean success = user.update(updateWrapper);

  • 我们也可以通过 updateWrapper set 方法直接设置字段值,比如下面除了将密码设置为 8888 外,还将年龄设置为 null
// 查询条件:名字中包含'ha'并且年龄小于40
LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40)
        .set(UserInfo::getPassWord, "8888")
        .set(UserInfo::getAge, null);
// 修改数据,返回执行是否成功
Boolean success = new UserInfo().update(updateWrapper);


/*********** 二者可以结合使用的,下面效果等效于上面的 ****************/

// 查询条件:名字中包含'ha'并且年龄小于40
LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40)
        .set(UserInfo::getAge, null);
// 将满足条件的记录密码都设置为8888
UserInfo user = new UserInfo();
user.setPassWord("8888");
// 修改数据,返回执行是否成功
Boolean success = user.update(updateWrapper);

  • 而也通过 updateWrapper setSql 方法可以直接设置 set 部分的 sql,下面的效果同上面是一样的:
// 查询条件:名字中包含'ha'并且年龄小于40
LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40)
        .setSql("pass_word = '8888'")
        .setSql("age = null");
// 修改改据,返回执行是否成功
Boolean success = new UserInfo().update(updateWrapper);

/*********** 二者可以结合使用的,下面效果等效于上面的 ****************/

// 查询条件:名字中包含'ha'并且年龄小于40
LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40)
        .setSql("age = null");
// 将满足条件的记录密码都设置为8888
UserInfo user = new UserInfo();
        user.setPassWord("8888");
// 修改改据,返回执行是否成功
Boolean success = user.update(updateWrapper);

5,新增或修改数据

调用实体对象的 insertOrUpdate 会先判断实体类是否包含主键 ID,如果有的话则执行更新操作,没有的话则执行新增操作:
UserInfo user1 = new UserInfo();
user1.setId(1);
user1.setUserName("hangge");
user1.setAge(100);
// 由于user1设置了主键id,则执行更新操作
user1.insertOrUpdate();

UserInfo user2 = new UserInfo();
user2.setUserName("hangge");
user2.setAge(100);
// 由于user2没有设置主键id,则执行新增操作
user2.insertOrUpdate();

6,删除数据

(1)调用对象的 deleteById 方法可以根据 id 删除一条记录:
UserInfo user = new UserInfo();
user.setId(23);
// 删除数据,返回执行是否成功
Boolean success = user.deleteById();

/****** 下面代码功能等效上面代码 ********/

Boolean success = new UserInfo().deleteById(23);

(2)调用对象的 delete 方法使用查询构造器删除记录:
关于查询条件构造器(QueryWrapperLambdaQueryWrapper)的详细用法可以参考我之前写的文章:
// 查询条件:名字中包含'ha'并且年龄小于40
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40);
// 删除数据,返回执行是否成功
Boolean success = new UserInfo().delete(queryWrapper);

7,查询数据

(1)调用对象的 selectById 方法可以根据主键 id 查询一条记录:
UserInfo user = new UserInfo();
user.setId(1);
// 根据ID查询数据
user = user.selectById();

/****** 下面代码功能等效上面代码 ********/

UserInfo user= new UserInfo().selectById(1);

(2)调用对象的 selectOne 方法可以使用查询构造器查询一条记录:
注意:如果数据库中符合传入条件的记录有多条,这个方法会返回第一条数据,不会报错。
// 查询条件:名字中包含'ha'并且年龄小于40
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","ha").lt("age",40);
// 开始查询
UserInfo user= new UserInfo().selectOne(queryWrapper);

(3)调用对象的 selectAll 方法可以查询所有的记录:
List<UserInfo> users = new UserInfo().selectAll();

(4)调用对象的 selectList 方法可以使用查询构造器查询数据,返回一个 List
// 查询条件:名字中包含'ha'并且年龄小于40
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","ha").lt("age",40);
// 开始查询
List<UserInfo> users = new UserInfo().selectList(queryWrapper);

(5)调用对象的 selectCount 方法可以使用查询构造器,查询总记录数:
// 查询条件:名字中包含'ha'并且年龄小于40
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","ha").lt("age",40);
// 开始查询
Integer count = new UserInfo().selectCount(queryWrapper);

(6)调用对象的 selectPage 方法可以实现分页查询,比如下面我们查询第一页的数据(每页两条记录):
这个分页方法和 BaseMapper 提供的分页一样都是物理分页,使用前需要要进行相关的插件配置,具体配置参考我之前的文章:
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(UserInfo::getPassWord,"123").lt(UserInfo::getAge,40);
// 开始查询
IPage<UserInfo> page = new UserInfo().selectPage(new Page<>(1,2), queryWrapper);
评论0