MyBatis-Plus 快速上手教程 ~

MyBatis Plus 是一款基于 MyBatis 的国产开源框架,它能够简化 MyBatis 的开发,类似于 Spring Data Jpa,都是全自动化的 ORM 框架,其中封装了单表的 curd 操作。同时,当需要完成多表操作时,也可以使用 MyBatis 去手动实现。最后,通过 Spring Boot + MyBatis-Plus,我们还可以快速生成 eneity、mapper、service、controller 层的代码,十分方便。

  • 以下是 Spring Boot 整合 MyBatis-Plus 快速搭建 Java 后端环境的步骤,适用于快速开发。

一、MyBatis-Plus 环境搭建

1、导入 MyBatis-Plus 依赖

		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.3.2</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

注意点:导入 MyBatis-Plus 的依赖后,也可以直接使用 MyBatis。

2、配置文件

application.yml 如下:

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/curdtest?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  type-aliases-package: com.study.pojo
  mapper-locations: classpath:mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  • type-aliases-package: 指定开启别名映射的包名
  • mapper-locations: 指定 mapper 文件的位置
  • configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl: 在控制台打印 sql 日志

3、实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "user")
public class User {
    @TableId
    private Integer id;
    @TableField(value = "name")
    private String username;
    private Integer age;
    @TableField(select = false)
    private Integer gender;
    @TableField(exist = false)
    private String address;
}

相关注解说明:

注解说明
@TableName映射数据库表名,当实体类名与数据库表名不一致时使用
@TableId必要,设置主键映射,一般需指定 type 为 AUTO 自增
@TableField映射非主键字段,exist = false 表示数据库中无该字段,select = false 表示不查询该字段

4、数据库访问层

创建 Mapper,添加 @Repository@Mapper 注解,并继承 BaseMapper

@Repository
@Mapper
public interface UserMapper extends BaseMapper<User>  {

}

以下是 BaseMapper 的源码,其中封装了大量的单表操作,MyBatis-PlusSpring Data Jpa 都是全自动的 ORM 的框架,我们可以直接使用其中的 CURD 方法而无需手动实现:

public interface BaseMapper<T> extends Mapper<T> {
    int insert(T entity);

    int deleteById(Serializable id);

    int deleteByMap(@Param("cm") Map<String, Object> columnMap);

    int delete(@Param("ew") Wrapper<T> wrapper);

    int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    int updateById(@Param("et") T entity);

    int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

    T selectById(Serializable id);

    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);

    T selectOne(@Param("ew") Wrapper<T> queryWrapper);

    Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);

    List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);

    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);

    List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);

    <E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);

    <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param("ew") Wrapper<T> queryWrapper);
}

二、单表查询(自动实现)

当需要指定查询条件时,一般需通过 QueryWrapper 对象的相应方法。
单表查询所有数据:

userMapper.selectList(null).forEach(System.out::println);

等值查询( eq:name = " 张三" ):

QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("name","张三");
userMapper.selectList(wrapper).forEach(System.out::println);

多个条件时,可以用 Map 进行封装,再传入 QueryWrapper 中,此时使用 allEq :

QueryWrapper wrapper = new QueryWrapper();
Map<String, Object> map = new HashMap<>();
map.put("name", "张三");
map.put("age", "10");
wrapper.allEq(map);
userMapper.selectList(wrapper).forEach(System.out::println);

大于 gt(大于等于 ge):

QueryWrapper wrapper = new QueryWrapper();
wrapper.gt("age",15);
userMapper.selectList(wrapper).forEach(System.out::println);

不等于 ne:

QueryWrapper wrapper = new QueryWrapper();
wrapper.ne("name","张三");
userMapper.selectList(wrapper).forEach(System.out::println);

模糊查询:

QueryWrapper wrapper = new QueryWrapper();
wrapper.like("name","小");
userMapper.selectList(wrapper).forEach(System.out::println);

排序:

QueryWrapper wrapper = new QueryWrapper();
wrapper.orderByDesc("age");
userMapper.selectList(wrapper).forEach(System.out::println);

having:

QueryWrapper wrapper = new QueryWrapper();
wrapper.orderByDesc("age");
wrapper.having("id>2");
userMapper.selectList(wrapper).forEach(System.out::println);

selectById 根据主键查询:

System.out.println(userMapper.selectById(1));

selectBatchIds 查询集合里的所有记录:

userMapper.selectBatchIds(Arrays.asList(1,2,3)).forEach(System.out::println);

selectByMap 使用 Map 做等值判断:

Map<String,Object> map = new HashMap<>();
map.put("name","张三");
userMapper.selectByMap(map).forEach(System.out::println);

selectCount 统计个数:

QueryWrapper wrapper = new QueryWrapper();
wrapper.ge("age",12);
System.out.println(userMapper.selectCount(wrapper));

将查询结果封装到 Map 中:

QueryWrapper wrapper = new QueryWrapper();
wrapper.ge("age",12);
System.out.println(userMapper.selectMaps(wrapper));

分页查询

创建 MyBatisPlus 的配置类:

@Configuration
public class MyBatisPlusConfig {

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        return  paginationInterceptor;
    }
}

必须要配置以上代码,否则无法生效
查询第 1 页,大小为 2 的记录:

Page<User> page = new Page<>(1,2);
Page<User> result = userMapper.selectPage(page, null);
System.out.println(result.getSize());
System.out.println(result.getTotal());
result.getRecords().forEach(System.out::println);

size 表示每页大小,total 表示总记录数
也可以用 Map 封装结果:

Page<Map<String, Object>> page = new Page<>(1, 2);
Page<Map<String, Object>> result = userMapper.selectMapsPage(page, null);
result.getRecords().forEach(System.out::println);

三、多表查询(自定义 sql )

以上操作只适用于单表查询,多表查询还是需要自己实现
新增一个 Article 表,创建对应的实体:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Article {
    @TableId(type = IdType.AUTO)
    private Integer aId;
    private String title;
    private Integer uId;
}

多表查询依旧可以使用 MyBatis,注意需在配置文件中添加 mapper-locations 的配置:

mybatis-plus:
  type-aliases-package: com.study.pojo
  mapper-locations: classpath:mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

在 Mapper 中自定义查询方法,在 xml 中写我们的 sql 即可:

@Repository
@Mapper
public interface UserMapper extends BaseMapper<User>  {
    User queryUserAndArticle(@Param("id") int id);
}
    <select id="queryUserAndArticle" resultMap="userArticle">
        select *
        from user u, article a
        where u.id = a.u_id and u.id = #{id};
    </select>
    <resultMap id="userArticle" type="user">
        <result column="id" property="id"/>
        <result column="name" property="username"/>
        <result column="age" property="age"/>
        <collection property="articles" ofType="article">
            <result column="a_id" property="aId"/>
            <result column="title" property="title"/>
        </collection>
    </resultMap>

上方是一对多的多表查询,通过 resultMap 返回。
多表联合查询的还有一种实现方式是:我们通过 VO(View Object)对两个实体的信息进行组合,通过 sql 将属性映射到 VO 类中:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserArticleVO {
    private Integer id;
    private String name;
    private Integer age;
    private Integer aId;
    private String title;
}
@Repository
@Mapper
public interface UserMapper extends BaseMapper<User>  {
    User queryUserAndArticle(@Param("id") int id);
    List<UserArticleVO> queryVO(@Param("id") int id);
}
    <select id="queryVO" resultType="com.study.vo.UserArticleVO">
        select *
        from user u, article a
        where u.id = a.u_id and u.id = #{id};
    </select>

得到相同的结果:
在这里插入图片描述

四、增、删、改

1、增加

 User user = new User();
 user.setUsername("小明");
 user.setAge(12);
 user.setGender(1);
 userMapper.insert(user);

2、修改

 User user = userMapper.selectById(4);
 QueryWrapper wrapper = new QueryWrapper();
 wrapper.eq("id",4);
 user.setUsername("小明222");
 user.setAge(12);
 user.setGender(1);
 userMapper.update(user,wrapper);

3、删除

根据主键删除:

userMapper.deleteById(4);

批量删除:

userMapper.deleteBatchIds(Arrays.asList(2,3));	// 批量删除

根据指定字段删除:

QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("age",10);
userMapper.delete(wrapper);
// 方式 2
Map<String,Object> map = new HashMap<>();
map.put("age",10);
userMapper.deleteByMap(map);

五、MyBatis-Plus 一键生成(逆向工程)

1、导入如下依赖:

		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-generator</artifactId>
			<version>3.3.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity</artifactId>
			<version>1.7</version>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.3.2</version>
		</dependency>

2、新建一个 Main 类,main 方法代码如下:

public class Main {
    public static void main(String[] args) {
        // 创建 AutoGenerator 对象
        AutoGenerator autoGenerator = new AutoGenerator();
        // 数据源
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/curdtest?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("123456");
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        autoGenerator.setDataSource(dataSourceConfig);
        // 全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
        globalConfig.setOpen(false);
        globalConfig.setAuthor("xxx");
        autoGenerator.setGlobalConfig(globalConfig);
        // 包信息
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.study");
        packageConfig.setController("controller");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        packageConfig.setMapper("mapper");
        packageConfig.setEntity("entity");
        autoGenerator.setPackageInfo(packageConfig);
        // 配置策略
        StrategyConfig strategyConfig = new StrategyConfig();
        // setInclude() 可指定生成部分表
        strategyConfig.setEntityLombokModel(true);
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        autoGenerator.setStrategy(strategyConfig);
        // 一键生成
        autoGenerator.execute();
    }
}

注意数据库配置参数(如用户名与密码)要进行相应修改。
运行上方的 main 方法即可自动生成 entityserviceserviceImplcontroller 的代码,即将数据库中的各个表逆向生成我们的各层代码,如果只需生成部分表,可通过 StrategyConfig.setInclude() 指定。

在这里插入图片描述
其中的 service 层代码也帮我们封装好了,我们可以像调用 mapper 层一样调用 service 层来完成简单的单表操作。
补充 controller 层代码即可:

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author xxx
 * @since 2021-02-26
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserServiceImpl userService;

    public Map<String, Object> resp(Object data) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "success");
        map.put("data", data);
        return map;
    }

    @GetMapping("/")
    public Map<String, Object> index() {
        return resp(userService.list());
    }

    @GetMapping("/{id}")
    public Map<String, Object> queryOne(@PathVariable("id") int id) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("id", id);
        return resp(userService.list(wrapper));
    }

    @PostMapping("/")
    public Map<String, Object> insert(@RequestBody User user) {
        userService.save(user);
        return resp(null);
    }

    @PutMapping("/")
    public Map<String, Object> update(@RequestBody User user) {
        userService.updateById(user);
        return resp(null);
    }

    @DeleteMapping("/{id}")
    public Map<String, Object> deletOne(@PathVariable("id") int id) {
        userService.removeById(id);
        return resp(null);
    }

}

在 Spring Boot 程序入口中开启 mapper 扫描:

@SpringBootApplication
@MapperScan("com.study.mapper")
public class MybatisPlusAutoApplication {

	public static void main(String[] args) {
		SpringApplication.run(MybatisPlusAutoApplication.class, args);
	}

}

启动程序,测试其中的一个接口,基本的项目环境已经搭建完毕:
在这里插入图片描述
可以看到,我们几乎没有做什么,就能很快生成基本的 REST 接口,用起来挺舒服的哈哈哈。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值