MyBatis-Plus 使用

MyBatis-Plus

MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
官方文档地址:https://mybatis.plus/guide/

环境介绍

环境要素 版本
maven 3.3.3
jdk 1.8.0_1.81
编译 idea
springboot 2.1.7.RELEASE
系统 win10

快速开始

添加依赖

pom.xml中引入以下的包



    com.baomidou
    mybatis-plus-boot-starter
    3.2.0



    mysql
    mysql-connector-java
    8.0.17
    runtime



    org.projectlombok
    lombok
    1.18.8



    org.springframework.boot
    spring-boot-starter
    2.1.7.RELEASE



    org.springframework.boot
    spring-boot-starter-test
    2.1.7.RELEASE
    test

配置

在application.properties中添加数据库配置

spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/db_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username = root
spring.datasource.password = 123456

在数据库造点东西

CREATE TABLE `tb_sys_role`  (
  `id` bigint(1) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
  `name` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `description` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `id`(`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_sys_role
-- ----------------------------
INSERT INTO `tb_sys_role` VALUES (1, '管理员', '一切皆可管');

在springboot项目启动类DemoApplication中,添加 @MapperScan 注解,扫描 Mapper 文件夹:

@SpringBootApplication(scanBasePackages = "com.smart.demo.*")
@MapperScan("com.smart.demo.dao.mapper")
public class SmartStreetApplication {
    public static void main(String[] args) {
        SpringApplication.run(SmartStreetApplication.class, args);
    }
}

编码

编写一个实体类TbSysRole(使用lombok简化代码)

@Data
public class TbSysRole {
    private Long id;
    private String name;
    private String description;
}

编写一个Mapper类,在上面的com.smart.demo.dao.mapper包下

public interface SysRoleMapper extends BaseMapper {
}

开始使用

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SmartDemoApplication.class)
public class SampleTest {
    @Resource
    private SysRoleMapper roleMapper;

    @Test
    public void testRole() {
        System.out.println(("----- selectAll method test ------"));
        List list = roleMapper.selectList(null);
        Assert.assertEquals(1, list.size());
    }
}

小结

通过以上几个简单的步骤,我们就实现了 User 表的 CRUD 功能。
从以上步骤中,我们可以看到集成 MyBatis-Plus 非常的简单,只需要引入 starter 工程,并配置 mapper 扫描路径即可。

我那个擦,都不用xml 了,像JPA的调用一样丝滑。

下面介绍MP的具体使用方式

Mapper CRUD 接口

MP 封装通用的CRUD的接口BaseMapper;启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入到容器

使用实例

定义Mapper接口继承BaseMapper

public interface SysRoleMapper extends BaseMapper {
}

定义实体类

@Data
public class TbSysRole {
    private Long id;
    private String name;
    private String description;
}

测试用例

@Test
public void testMapper() {
    TbSysRole r = new TbSysRole();
    r.setName("aa");
    roleMapper.insert(r);

    QueryWrapper query = Wrappers.query();
    query.eq("name","aa");
    TbSysRole role= roleMapper.selectOne(query);

    Map map=new HashMap<>();
    map.put("name",role.getName());
    roleMapper.deleteByMap(map);

    roleMapper.insert(r);
    roleMapper.delete(query);
    List ids=new ArrayList<>();
    ids.add(2L);
    ids.add(3L);
    roleMapper.deleteBatchIds(ids);
}

测试用例

@Resource
private SysRoleMapper roleMapper;

@Test
public void testRole() {
    System.out.println(("----- selectAll method test ------"));
    List list = roleMapper.selectList(null);
    Assert.assertEquals(1, list.size());
}

庐山面目

实体类的Mapper 继承BaseMapper 。其中泛型 T 为实体类;Wrapper 条件构造器

public interface BaseMapper extends Mapper {
    //插入一条记录
    int insert(T entity);
    //删除
    int deleteById(Serializable id);
    int deleteByMap(@Param("cm") Map columnMap);
    int delete(@Param("ew") Wrapper wrapper);
    int deleteBatchIds(@Param("coll") Collection idList);
    //更新
    int updateById(@Param("et") T entity);
    int update(@Param("et") T entity, @Param("ew") Wrapper updateWrapper);
    //查询
    T selectById(Serializable id);
    List selectBatchIds(@Param("coll") Collection idList);
    List selectByMap(@Param("cm") Map columnMap);
    T selectOne(@Param("ew") Wrapper queryWrapper);
    Integer selectCount(@Param("ew") Wrapper queryWrapper);
    List selectList(@Param("ew") Wrapper queryWrapper);
    List> selectMaps(@Param("ew") Wrapper queryWrapper);
    List selectObjs(@Param("ew") Wrapper queryWrapper);
    //分页
    IPage selectPage(IPage page, @Param("ew") Wrapper queryWrapper);
    IPage> selectMapsPage(IPage page, @Param("ew") Wrapper queryWrapper);
}

Service CRUD接口

mybatis-plus 进一步封装了CRUD方法, 封装的接口为IService,实现类为ServiceImpl,当然为了避免和Mapper层的混淆,方法的命名有些改变。

命名区别

Mapper Service
insert save/saveBatch/saveOrUpdateBatch
delete remove
update 一样/updateBatchById
select get
selectPage page
selectList listBy

庐山面目

public interface IService {
    boolean save(T entity);
    @Transactional(
        rollbackFor = {Exception.class}
    )
    default boolean saveBatch(Collection entityList) {
        return this.saveBatch(entityList, 1000);
    }
    boolean saveBatch(Collection entityList, int batchSize);
    @Transactional(
        rollbackFor = {Exception.class}
    )
    default boolean saveOrUpdateBatch(Collection entityList) {
        return this.saveOrUpdateBatch(entityList, 1000);
    }
    boolean saveOrUpdateBatch(Collection entityList, int batchSize);

    boolean removeById(Serializable id);
    boolean removeByMap(Map columnMap);
    boolean remove(Wrapper queryWrapper);
    boolean removeByIds(Collection idList);
    
    boolean updateById(T entity);
    boolean update(T entity, Wrapper updateWrapper);
    default boolean update(Wrapper updateWrapper) {
        return this.update((Object)null, updateWrapper);
    }
    @Transactional(
        rollbackFor = {Exception.class}
    )
    default boolean updateBatchById(Collection entityList) {
        return this.updateBatchById(entityList, 1000);
    }
    boolean updateBatchById(Collection entityList, int batchSize);
    boolean saveOrUpdate(T entity);

    T getById(Serializable id);
    Collection listByIds(Collection idList);
    Collection listByMap(Map columnMap);
    default T getOne(Wrapper queryWrapper) {
        return this.getOne(queryWrapper, true);
    }

    T getOne(Wrapper queryWrapper, boolean throwEx);
    Map getMap(Wrapper queryWrapper);
     V getObj(Wrapper queryWrapper, Function mapper);
    int count(Wrapper queryWrapper);
    default int count() {
        return this.count(Wrappers.emptyWrapper());
    }
    List list(Wrapper queryWrapper);
    default List list() {
        return this.list(Wrappers.emptyWrapper());
    }
    IPage page(IPage page, Wrapper queryWrapper);
    default IPage page(IPage page) {
        return this.page(page, Wrappers.emptyWrapper());
    }
    List> listMaps(Wrapper queryWrapper);
    default List> listMaps() {
        return this.listMaps(Wrappers.emptyWrapper());
    }
    default List listObjs() {
        return this.listObjs(Function.identity());
    }
    default  List listObjs(Function mapper) {
        return this.listObjs(Wrappers.emptyWrapper(), mapper);
    }
    default List listObjs(Wrapper queryWrapper) {
        return this.listObjs(queryWrapper, Function.identity());
    }
     List listObjs(Wrapper queryWrapper, Function mapper);
    
    IPage> pageMaps(IPage page, Wrapper queryWrapper);
    default IPage> pageMaps(IPage page) {
        return this.pageMaps(page, Wrappers.emptyWrapper());
    }
    BaseMapper getBaseMapper();
    default QueryChainWrapper query() {
        return new QueryChainWrapper(this.getBaseMapper());
    }
    default LambdaQueryChainWrapper lambdaQuery() {
        return new LambdaQueryChainWrapper(this.getBaseMapper());
    }
    default UpdateChainWrapper update() {
        return new UpdateChainWrapper(this.getBaseMapper());
    }
    default LambdaUpdateChainWrapper lambdaUpdate() {
        return new LambdaUpdateChainWrapper(this.getBaseMapper());
    }
    default boolean saveOrUpdate(T entity, Wrapper updateWrapper) {
        return this.update(entity, updateWrapper) || this.saveOrUpdate(entity);
    }
}

使用实例

定义mapper

public interface SysUserMapper extends BaseMapper {
}

业务Service

public interface ISysUserService {
    List queryUser();
    List queryUser(Long userId);
}

业务Service实现

@Service
public class SysUserServiceImpl extends ServiceImpl implements ISysUserService {
    @Resource
    private SysUserMapper userMapper;

    @Override
    public List queryUser() {
        List userList = userMapper.selectList(null);
        return userList;
    }

    @Override
    public TbSysUser queryUserById(Long userId) {
        return getById(userId);
    }

}

测试用例

@Autowired
private ISysUserService sysUserService;

@Test
public void test(){
    TbSysUser user=sysUserService.queryUserById(1L);
    System.out.println(user);
}

条件构造器

前面你肯定已经看到到一些以前没见过的东西 ,例如下面。这就是要说的条件构造器

QueryWrapper query = Wrappers.query();

条件构造器的父类是AbstractWrapper,它有两个实现类:QueryWrapper和UpdateWrapper 。它的主要作用是用于生成 sql 的 where 条件。

下面这些方法都是2个实现类公用的。

allEq 多条件
  • 方法
allEq(Map params) = allEq(true, map, true)
allEq(Map params, boolean null2IsNull) = allEq(true,map,null2IsNull)
allEq(boolean condition, Map params, boolean null2IsNull)

params : key为数据库字段名,value为字段值
null2IsNull :默认true,为true则在map的value为null时调用 isNull 方法,为false时则忽略value为null的条件
condition:是否执行条件,默认true

  • 示例

    模拟数据有:

    id name description
    1 管理员 一切皆可管
    2 Null 测试
    3 aaa AAAA
    /**
     * query.allEq(map);多参数查询
     *  allEq({name:null,description:"一切皆可管"})--->where name is null and description="一切皆可管"
     */
    @Test
    public void testWrapper() {
        QueryWrapper query = Wrappers.query();
        Map map = new HashMap<>();
        map.put("name","管理员");
        map.put("description","一切皆可管");
        query.allEq(map);
        List list= roleMapper.selectList(query);
        Assert.assertEquals(1,list.size());
    }
    /**
     * query.allEq(map,true)相当于allEq(map) ;默认值就是true
     * 生成的相当于 name is null,查询属性值为null的记录
     * allEq({id:1,name:null})--->where id = 1 and name is null
     */
    @Test
    public void testWrapper2() {
        QueryWrapper query = Wrappers.query();
        Map map = new HashMap<>();
        map.put("name",null);
        query.allEq(map,true);
        List list2= roleMapper.selectList(query);
        Assert.assertEquals(1,list2.size());
    }
    /**
     * query.allEq(map,false);忽略value=null的条件
     * 相当于不要这个为null的条件
     * allEq({id:1,name:null})--->where id = 1 
     */
    @Test
    public void testWrapper3() {
        QueryWrapper query = Wrappers.query();
        Map map = new HashMap<>();
        map.put("name",null);
        query.allEq(map,false);
        List list3= roleMapper.selectList(query);
        Assert.assertEquals(3,list3.size());
    }
    /**
     * allEq(false,map,null2IsNull)
     * 第一个参数代表是否执行这些条件,false相当于没传条件
     */
     @Test
     public void testWrapper4() {
         QueryWrapper query = Wrappers.query();
         Map map = new HashMap<>();
         map.put("name","管理员");
         map.put("description","一切皆可管");
         query.allEq(false,map,true);
         List list= roleMapper.selectList(query);
         Assert.assertEquals(3,list.size());
     }
    
  • 方法

    allEq(BiPredicate filter, Map params) = allEq(true, filter, params, null2IsNull);
    allEq(BiPredicate filter, Map params, boolean null2IsNull)
    allEq(boolean condition, BiPredicate filter, Map params, boolean null2IsNull) 
    
  • 示例

    /**
     * allEq(filter, map);
     * 相当于只传入满足过滤器的条件,其他条件都跳过
     */
    @Test
    public void testWrapper4() {
        QueryWrapper query = Wrappers.query();
        Map map = new HashMap<>();
        map.put("name","管理员");
        query.allEq((k,v) -> v.toString().indexOf("员") >= 0,map);
        List list3= roleMapper.selectList(query);
        Assert.assertEquals(1,list3.size());
    }
    
eq 等于
  • 方法
eq(R column, Object val)
eq(boolean condition, R column, Object val)

相当于“=”
column :列名
val:值
condition:是否执行条件

  • 示例

    /*
     * eq(R column, Object val);
     * Eq({name:"管理员"})--->where name "管理员"
     */
    @Test
    public void testWrapper6() {
        QueryWrapper query = Wrappers.query();
        query.eq("name","管理员");
        List list3= roleMapper.selectList(query);
        Assert.assertEquals(1,list3.size());
    }
    /*
     * eq(condition,column,val);
     * 相当于没有传递任何条件
     */
    @Test
    public void testWrapper7() {
        QueryWrapper query = Wrappers.query();
        query.eq(false,"name","管理员");
        List list3= roleMapper.selectList(query);
        Assert.assertEquals(3,list3.size());
    }
    
ne 不等于
  • 方法
ne(R column, Object val) = ne(true, column,val)
ne(boolean condition, R column, Object val)

相当于不等于<>
column :列名
val:值
condition:是否执行条件

  • 代码

    /**
     * ne("name","1");查询name不等于1,(mysql默认会排除name=null的数据)
     * 相当于where name <>'1'
     */
    @Test
    public void testWrapper8() {
        QueryWrapper query = Wrappers.query();
        query.ne("name","1");
        List list3= roleMapper.selectList(query);
        Assert.assertEquals(2,list3.size());
    }
    /**
     *  ne(true,"name","1")相当于query.ne("name","1"),默认值就是true 
     *  查询name不等于1,(mysql默认会排除name=null的数据)
     *  相当于where name <>'1'
     */
    @Test
    public void testWrapper9() {
        QueryWrapper query = Wrappers.query();
        query.ne(true,"name","1");
        List list3= roleMapper.selectList(query);
        Assert.assertEquals(2,list3.size());
    }
    /**
     *  ne("name","1");查询name不等于1,(mysql默认会排除name=null的数据)
     *  相当于 没有where 
     */
    @Test
    public void testWrapper10() {
        QueryWrapper query = Wrappers.query();
        query.ne(false,"name","1");
        List list3= roleMapper.selectList(query);
        Assert.assertEquals(3,list3.size());
    }
    
gt 大于
  • 方法

    gt(R column, Object val)
    gt(boolean condition, R column, Object val)
    
  • 例子

    ge("age", 18)--->age > 18

ge 大于等于
  • 方法

    ge(R column, Object val)
    ge(boolean condition, R column, Object val)
    
  • 例子

    lt("age", 18)--->age >= 18

lt 小于
  • 方法

    lt(R column, Object val)
    lt(boolean condition, R column, Object val)
    
  • 例子

    lt("age", 18)--->age < 18

le 小于等于
  • 方法

    le(R column, Object val)
    le(boolean condition, R column, Object val)
    
  • 例子

    lt("age", 18)--->age <= 18

between
  • 方法

    between(R column, Object val1, Object val2)
    between(boolean condition, R column, Object val1, Object val2)
    
  • 例子

    between("age", 18, 30)--->age between 18 and 30

notBetween
  • 方法
notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)
  • 例子

    notBetween("age", 18, 30)--->age not between 18 and 30

notBetween
  • 方法
notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)
  • 例子

    notBetween("age", 18, 30)--->age not between 18 and 30

like
  • 方法
like(R column, Object val)
like(boolean condition, R column, Object val)
  • 例子

    like("name", "王")--->name like '%王%'

notLike
  • 方法
notLike(R column, Object val)
notLike(boolean condition, R column, Object val)
  • 例子

    notLike("name", "王")--->name not like '%王%'

其他
方法名 方法 实例
likeLeft likeLeft(R column, Object val) likeLeft(boolean condition, R column, Object val) likeLeft("name", "王")--->name like '%王'
likeRight likeRight(R column, Object val) likeRight(boolean condition, R column, Object val) likeRight("name", "王")--->name like '王%'
isNull isNull(R column) isNull(boolean condition, R column) isNull("name")--->name is null
isNotNull isNotNull(R column) isNotNull(boolean condition, R column) isNotNull("name")--->name is not null
in in(R column, Collection value) in(boolean condition, R column, Collection value) in("age",{1,2,3})--->age in (1,2,3)
notIn notIn(R column, Collection value) notIn(boolean condition, R column, Collection value) notIn("age",{1,2,3})--->age not in (1,2,3)

还有很多,可以去看官网

QueryWrapper

select
  • 方法

    select(String... sqlSelect)
    select(Predicate predicate)
    select(Class entityClass, Predicate predicate)
    
  • 代码

    /**
    * 查询id=1, 且返回集中只有id,name
    **/
    @Test
    public void testWrapper12() {
        QueryWrapper query = Wrappers.query();
        query.select("id","name");
        query.eq("id",1);
        List list3= roleMapper.selectList(query);
        Assert.assertEquals(1,list3.size());
    }
    

UpdateWrapper

set
  • 方法
set(String column, Object val)
set(boolean condition, String column, Object val)
  • 代码

    @Test
    public void testWrapper13() {
        UpdateWrapper updateWrapper=Wrappers.update();
        updateWrapper.eq("id",3);
        updateWrapper.set("name","AA1A");
        roleMapper.update(null,updateWrapper);
    }
    
setSql
  • 方法
setSql(String sql)
  • 代码

    @Test
    public void testWrapper15() {
        UpdateWrapper updateWrapper=Wrappers.update();
        updateWrapper.eq("id",3);
        updateWrapper.setSql("name='小妹妹'");
        roleMapper.update(null,updateWrapper);
    }
    

自定义sql

注解方式
public interface SysRoleMapper extends BaseMapper {
    /**
     * 第一种方法:注解方式,不使用MP的Wrapper条件构造器
     *和Mybatis使用方法一致
     * @param id
     * @return
     */
    @Select("select * from tb_sys_role where id= #{id}")
    TbSysRole findOneRole(Long id);

    /**
     * 第一种方法:注解方式,如果自定义的方法还希望能够使用MP提供的Wrapper条件构造器,则需要如下写法
     *
     * @param roleWrapper
     * @return
     */
    @Select("SELECT * FROM tb_sys_role ${ew.customSqlSegment}")
    TbSysRole selectByMyWrapper(@Param(Constants.WRAPPER) Wrapper roleWrapper);
}
@Test
public void testWrapper16() {
    TbSysRole R= roleMapper.findOneRole(1L);
    System.out.println(R.getName());
}
@Test
public void testWrapper17() {
    QueryWrapper query = Wrappers.query();
    query.eq("id",1);
    TbSysRole r=roleMapper.selectByMyWrapper(query);
    System.out.println(r.getName());
}
xml 方式

Mapper接口

package com.smart.street.dao.mapper;

public interface SysUserMapper extends BaseMapper {
    /**
     * 和Mybatis使用方法一致
     *
     * @param id
     * @return
     */
    TbSysUser findOneUser(Long id);

    /**
     * 如果自定义的方法还希望能够使用MP提供的Wrapper条件构造器,则需要如下写法
     *
     * @param userWrapper
     * @return
     */
    TbSysUser selectByMyWrapper(@Param(Constants.WRAPPER) Wrapper userWrapper);
}

xml 放在resources下的com.smart.street.dao.mapper目录中,一定要和上面的Mapper接口目录结构一致且文件名和Mapper名字一致





    

    


配置文件application.properties中添加

mybatis-plus.mapper-locations= classpath:com.smart.street.dao.mapper/*.xml

测试用例

@Test
public void testWrapper18() {
    TbSysUser u= userMapper.findOneUser(1L);
    System.out.println(u.getUserName());
}
@Test
public void testWrapper19() {
    QueryWrapper query = Wrappers.query();
    query.eq("id",1);
    TbSysUser u= userMapper.selectByMyWrapper(query);
    System.out.println(u.getUserName());
}

你可能感兴趣的:(MyBatis-Plus 使用)