栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot集成Mybatis-Plus框架

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot集成Mybatis-Plus框架

SpringBoot集成Mybatis-Plus框架

MyBatis-Plus(简称 MP)是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。


具体可以参考MyBatis-Plus官网:MyBatis-Plus官网


目录
  • SpringBoot集成Mybatis-Plus框架
    • 环境
    • 数据库表
    • Java实体类 UserInfo
    • application.yml 主配置
    • 编写mapper
    • 主启动类
    • Mapper CRUD操作
      • 新增
      • 查询
      • 分页查询
        • 分页插件配置
        • 分页查询 测试结果
      • 删除
      • 更新
    • Service CRUD操作


环境
  • Java1.8
  • maven
  • spring boot 2.2.4.RELEASE
  • mybatis-plus-boot-starte 3.3.2
  • mysql

maven xml 配置文件


    org.springframework.boot
    spring-boot-starter-parent
    2.2.4.RELEASE






    com.baomidou
    mybatis-plus-boot-starter
    3.3.2

		



	mysql
	mysql-connector-java



数据库表

用户基本信息表

-- 建表语句

CREATE TABLE `user_info` (
  `user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID主键',
  `user_name` varchar(100) NOT NULL COMMENT '用户姓名',
  `user_idcard` varchar(20) DEFAULT NULL COMMENT '身份证',
  `age` int(5) DEFAULT NULL COMMENT '年龄',
  `home_address` varchar(500) DEFAULT NULL COMMENT '家庭地址',
  `height` int(5) DEFAULT NULL COMMENT '身高',
  `birth_day` date DEFAULT NULL COMMENT '出生日期',
  `sex` varchar(5) DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;


Java实体类 UserInfo
@Data
@Builder
@TableName("user_info")
public class UserInfo {
	
	// 用户ID
    // @TableId 标注为表主键ID,若是没有标注,则 updateById会报错
	@TableId
	private long userId ;
	
	// 用户姓名
	@TableField
	private String userName ;
	
	// 用户身份证
	private String userIdcard ;
	
	// 家庭地址
	private String homeAddress ;
	
	// 年龄
	private int age ;
	
	// 身高CM
	private int height ;
	
	// 性别
	private String sex ;
	
	// 出生日期
	// JSON 输出格式化
    @JSONField(format = "yyyy年MM月dd日")
	private Date birthDay ;

}


注意:@TableId 标注为表主键ID,若是没有标注,则 updateById会报错,具体报错,参考下面的:CRUD操作/更新


其他字段若是跟数据库保持一致或者数据库是以下划线分割,Java类属性是以驼峰命名的,则可以不用添加 @TableField,mybatis-plus框架会自动匹配


数据库字段值, 不需要配置该值的情况:

当 com.baomidou.mybatisplus.core.MybatisConfiguration.mapUnderscoreToCamelCase 为 true 时, (mp下默认是true,mybatis默认是false), 数据库字段值.replace("_","").toUpperCase() == 实体属性名.toUpperCase()

当 com.baomidou.mybatisplus.core.MybatisConfiguration.mapUnderscoreToCamelCase 为 false 时, 数据库字段值.toUpperCase() == 实体属性名.toUpperCase()


若是JavaBean中某些属性不是数据库表字段的,则可以添加 @TableField(exist = false) 来避免自动生成的SQL字段不存在问题



application.yml 主配置

配置数据源

server:
  port: 8080
  servlet:
    context-path: /
    
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: mysql


编写mapper

集成mybatis-plus mapper接口继承 baseMapper 即可,然后对单表的CRUD的操作就可以不用编写xml文件了,类似JPA框架,非常方便

@Repository
public interface IUserInfoMapper extends baseMapper{

}


baseMapper 对单表的常用方法:


主启动类
@SpringBootApplication
@MapperScan("com.tianya.springboot.mybatis.plus.mapper")
public class LearnMybatisPlusApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(LearnMybatisPlusApplication.class, args);
	}

}


Mapper CRUD操作

mapper接口 继承 baseMapper 接口,就可以实现对单表的 CRUD快捷API操作


来实际测试一下 mybatis-plus便捷之处

此处使用了一个自动随机生成测试数据的工具jar


	com.github.javafaker
	javafaker
	1.0.2


这个工具可以随机生成测试数据,避免自己制造测试数据头痛


新增
// 插入对象
int insert(T entity);


测试新增用户基本信息:

@Test
public void insert() {
	
	Faker faker = new Faker(Locale.SIMPLIFIED_CHINESE);
	
	// 测试 新增 10 个用户
	for (int i = 0; i < 10; i++) {
		
		// 用户信息
		UserInfo userInfo = UserInfo.builder()
				.userName(faker.name().fullName())
				.userIdcard(faker.idNumber().invalid())
				.homeAddress(faker.address().fullAddress())
				.birthDay(faker.date().birthday())
				.age(faker.number().numberBetween(1, 120))
				.height(faker.number().numberBetween(50, 200))
				.sex(SEX_MAP.get(faker.number().numberBetween(0, 2)))
				.build();
        
        // 新增
		userInfoMapper.insert(userInfo);
	}
	
}


结果如下:

[
	{
		"age":75,
		"birthDay":"1974年10月28日",
		"height":94,
		"homeAddress":"余巷",
		"sex":"女",
		"userId":11,
		"userIdcard":"000-98-3709",
		"userName":"林烨霖"
	},
	{
		"age":87,
		"birthDay":"1977年09月05日",
		"height":118,
		"homeAddress":"Suite 078 袁桥36104号, 金华, 浙 723135",
		"sex":"女",
		"userId":27,
		"userIdcard":"114-00-3888",
		"userName":"邹雨泽"
	},
	{
		"age":12,
		"birthDay":"1965年09月05日",
		"height":150,
		"homeAddress":"Suite 118 谢中心0798号, 衢州, 桂 350938",
		"sex":"男",
		"userId":28,
		"userIdcard":"435-25-0000",
		"userName":"范金鑫"
	},
	{
		"age":30,
		"birthDay":"1996年07月04日",
		"height":84,
		"homeAddress":"阎中心50号, 海口, 湘 888025",
		"sex":"女",
		"userId":29,
		"userIdcard":"162-11-0000",
		"userName":"程炫明"
	},
	{
		"age":84,
		"birthDay":"1972年06月14日",
		"height":144,
		"homeAddress":"刘街3928号, 平顶山, 豫 904305",
		"sex":"男",
		"userId":30,
		"userIdcard":"638-77-0000",
		"userName":"汪鑫鹏"
	}
]

查询
// 根据 entity 条件,查询全部记录 封装 实体对象
List selectList( Wrapper queryWrapper);

// 根据 Wrapper 条件,查询全部记录
List> selectMaps( Wrapper queryWrapper);

// 根据 Wrapper 条件 查询总记录数
Integer selectCount( Wrapper queryWrapper);

// 查询单条记录
T selectOne( Wrapper queryWrapper);

// 根据主键ID查询
T selectById(Serializable id);


查询所有

@Test
public void getList() {
	// 查询所有
	List selectList = userInfoMapper.selectList(null);
	System.out.println("所有的用户基本信息:");
	System.out.println(JSON.toJSONString(selectList, true));
}

分页查询

分页查询 mapper中 对应的 API 操作是:

// 根据 entity 条件,查询全部记录(并翻页)
> E selectPage(E page, Wrapper queryWrapper);

// 根据 Wrapper 条件,查询全部记录(并翻页)
>> E selectMapsPage(E page, Wrapper queryWrapper);

但是此 API操作,需要搭配 mybatis-plus中的分页插件才有效果,否则查询的 全部,没有分页限制


分页插件配置
@Configuration
public class MybatisPlusConfig {
	
	@Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }

}

配置完分页插件后,可以使用mybatis-plus提供的分页API进行分页查询,也可以自定义XML文件编写查询语句


分页查询 测试结果
@Test
public void getQueryList() {
	
	// 查询条件(查询身高在1米-2米之间的 以年龄倒序排序,查询第一页3个 TOP3)
	LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(UserInfo.class)
			.orderByDesc(UserInfo::getAge)
			.between(UserInfo::getHeight, 100, 200);
	
	Page page = new Page(1, 3);
	page.setSearchCount(true);
	
	// 若是没有配置 分页插件,则 selectPage 分页API 不生效
	page = userInfoMapper.selectPage(page, queryWrapper);
	
	System.out.println("分页查询:");
	System.out.println("总记录数:" + page.getTotal());
	System.out.println(JSON.toJSONString(page, true));
}

结果如下:

{
	"current":1,
	"hitCount":false,
	"optimizeCountSql":true,
	"orders":[],
	"pages":5,
	"records":[
		{
			"age":93,
			"birthDay":"1970年07月23日",
			"height":157,
			"homeAddress":"段路7号, 北京, 宁 451930",
			"sex":"男",
			"userId":25,
			"userIdcard":"666-37-8505",
			"userName":"朱鹤轩"
		},
		{
			"age":84,
			"birthDay":"1972年06月14日",
			"height":144,
			"homeAddress":"刘街3928号, 平顶山, 豫 904305",
			"sex":"男",
			"userId":30,
			"userIdcard":"638-77-0000",
			"userName":"汪鑫鹏"
		},
		{
			"age":79,
			"birthDay":"1984年01月17日",
			"height":113,
			"homeAddress":"赵街",
			"sex":"男",
			"userId":14,
			"userIdcard":"666-95-6869",
			"userName":"阎俊驰"
		}
	],
	"searchCount":true,
	"size":3,
	"total":14
}

删除
// 根据ID删除
int deleteById(Serializable id);

// 根据 columnMap 条件,删除记录
int deleteByMap(Map columnMap);

// 根据 entity 条件,删除记录
int delete(Wrapper wrapper);

// 删除(根据ID 批量删除)
int deleteBatchIds(Collection idList);


根据ID删除

@Test
public void delete() {
	
	// 删除
	userInfoMapper.deleteById(20);
	
}


更新
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);

// 根据 whereEntity 条件,更新记录
int update( T entity,  Wrapper updateWrapper);


更加ID进行修改

@Test
public void update() {
	
	// 查询单个
	UserInfo userInfo = userInfoMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class)
			.eq(UserInfo::getUserId, 27));
	
	System.out.println("修改前:");
	System.out.println(JSON.toJSONString(userInfo, true));
	
	// 修改值
	userInfo.setAge(70);
	userInfo.setSex(SEX_MAP.get(1));
	userInfo.setHeight(178);
	
	// 更新
	userInfoMapper.updateById(userInfo);
	
	System.out.println("修改后:");
	System.out.println(JSON.toJSONString(userInfo, true));
}


若是出现以下错误,则说明 实体类没有添加 表ID主键注解:@TableId


org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'null' in 'class com.tianya.springboot.mybatis.plus.entity.UserInfo'
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
	at com.sun.proxy.$Proxy83.update(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:287)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:65)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:96)
	at com.sun.proxy.$Proxy104.updateById(Unknown Source)
	
	... 82 more



结果:

## 修改前:
{
	"age":67,
	"birthDay":"1977年09月05日",
	"height":118,
	"homeAddress":"Suite 078 袁桥36104号, 金华, 浙 723135",
	"sex":"女",
	"userId":27,
	"userIdcard":"114-00-3888",
	"userName":"邹雨泽"
}

## 修改后:
{
	"age":70,
	"birthDay":"1977年09月05日",
	"height":178,
	"homeAddress":"Suite 078 袁桥36104号, 金华, 浙 723135",
	"sex":"男",
	"userId":27,
	"userIdcard":"114-00-3888",
	"userName":"邹雨泽"
}

Service CRUD操作

mybatis-plus框架 提供了 针对 服务层service的一个基类接口,提供更加丰富的 CRUD API 操作

com.baomidou.mybatisplus.extension.service.IService

只需要 实现 IService 即可


提供的一系列操作API:

    
    int DEFAULT_BATCH_SIZE = 1000;

    
    default boolean save(T entity) {
        return SqlHelper.retBool(getbaseMapper().insert(entity));
    }

    
    @Transactional(rollbackFor = Exception.class)
    default boolean saveBatch(Collection entityList) {
        return saveBatch(entityList, DEFAULT_BATCH_SIZE);
    }

    
    boolean saveBatch(Collection entityList, int batchSize);

    
    @Transactional(rollbackFor = Exception.class)
    default boolean saveOrUpdateBatch(Collection entityList) {
        return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);
    }

    
    boolean saveOrUpdateBatch(Collection entityList, int batchSize);

    
    default boolean removeById(Serializable id) {
        return SqlHelper.retBool(getbaseMapper().deleteById(id));
    }

    
    default boolean removeByMap(Map columnMap) {
        Assert.notEmpty(columnMap, "error: columnMap must not be empty");
        return SqlHelper.retBool(getbaseMapper().deleteByMap(columnMap));
    }

    
    default boolean remove(Wrapper queryWrapper) {
        return SqlHelper.retBool(getbaseMapper().delete(queryWrapper));
    }

    
    default boolean removeByIds(Collection idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return false;
        }
        return SqlHelper.retBool(getbaseMapper().deleteBatchIds(idList));
    }

    
    default boolean updateById(T entity) {
        return SqlHelper.retBool(getbaseMapper().updateById(entity));
    }

    
    default boolean update(Wrapper updateWrapper) {
        return update(null, updateWrapper);
    }

    
    default boolean update(T entity, Wrapper updateWrapper) {
        return SqlHelper.retBool(getbaseMapper().update(entity, updateWrapper));
    }

    
    @Transactional(rollbackFor = Exception.class)
    default boolean updateBatchById(Collection entityList) {
        return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
    }

    
    boolean updateBatchById(Collection entityList, int batchSize);

    
    boolean saveOrUpdate(T entity);

    
    default T getById(Serializable id) {
        return getbaseMapper().selectById(id);
    }

    
    default List listByIds(Collection idList) {
        return getbaseMapper().selectBatchIds(idList);
    }

    
    default List listByMap(Map columnMap) {
        return getbaseMapper().selectByMap(columnMap);
    }

    
    default T getOne(Wrapper queryWrapper) {
        return getOne(queryWrapper, true);
    }

    
    T getOne(Wrapper queryWrapper, boolean throwEx);

    
    Map getMap(Wrapper queryWrapper);

    
     V getObj(Wrapper queryWrapper, Function mapper);

    
    default int count() {
        return count(Wrappers.emptyWrapper());
    }

    
    default int count(Wrapper queryWrapper) {
        return SqlHelper.retCount(getbaseMapper().selectCount(queryWrapper));
    }

    
    default List list(Wrapper queryWrapper) {
        return getbaseMapper().selectList(queryWrapper);
    }

    
    default List list() {
        return list(Wrappers.emptyWrapper());
    }

    
    default > E page(E page, Wrapper queryWrapper) {
        return getbaseMapper().selectPage(page, queryWrapper);
    }

    
    default > E page(E page) {
        return page(page, Wrappers.emptyWrapper());
    }

    
    default List> listMaps(Wrapper queryWrapper) {
        return getbaseMapper().selectMaps(queryWrapper);
    }

    
    default List> listMaps() {
        return listMaps(Wrappers.emptyWrapper());
    }

    
    default List listObjs() {
        return listObjs(Function.identity());
    }

    
    default  List listObjs(Function mapper) {
        return listObjs(Wrappers.emptyWrapper(), mapper);
    }

    
    default List listObjs(Wrapper queryWrapper) {
        return listObjs(queryWrapper, Function.identity());
    }

    
    default  List listObjs(Wrapper queryWrapper, Function mapper) {
        return getbaseMapper().selectObjs(queryWrapper).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());
    }

    
    default >> E pageMaps(E page, Wrapper queryWrapper) {
        return getbaseMapper().selectMapsPage(page, queryWrapper);
    }

    
    default >> E pageMaps(E page) {
        return pageMaps(page, Wrappers.emptyWrapper());
    }

    
    baseMapper getbaseMapper();

    

    
    default QueryChainWrapper query() {
        return ChainWrappers.queryChain(getbaseMapper());
    }

    
    default LambdaQueryChainWrapper lambdaQuery() {
        return ChainWrappers.lambdaQueryChain(getbaseMapper());
    }

    
    default UpdateChainWrapper update() {
        return ChainWrappers.updateChain(getbaseMapper());
    }

    
    default LambdaUpdateChainWrapper lambdaUpdate() {
        return ChainWrappers.lambdaUpdateChain(getbaseMapper());
    }

    
    default boolean saveOrUpdate(T entity, Wrapper updateWrapper) {
        return update(entity, updateWrapper) || saveOrUpdate(entity);
    }

 


转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号