ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringBoot MybatisPlus教程 简洁没有废话!

2021-06-28 22:30:51  阅读:185  来源: 互联网

标签:教程 MybatisPlus SpringBoot userinfoMapper private 查询 userinfo public Userinfo


如果有不懂的或意见建议 欢迎评论!

文章目录 / 点个赞 点个关注吧


1. MybatisPlus 简介

MybatisPlus是基于Mybatis的封装, Mybatis的加强版, 加强了什么呢? 内部使用动态代理 自动生成增删改查操作

如果使用Mybaits 就得需要手动实现 增删改查sql, 效率低还容易出错!

MybaitPlus可以和Mybatis同时使用, 对于复杂sql, 可用继续写xml。且对于调用者来说用法都是统一的!

下面直接看看怎么用

2. 环境配置

在SpringBoot2下使用

  1. 引入依赖

    <dependency>
    	<groupId>com.baomidou</groupId>
    	<artifactId>mybatis-plus-boot-starter</artifactId>
    	<version>3.1.1</version>
    </dependency>
    
  2. 与SpringBoot集成

    在application.yml 或 application.properties文件中 加入以下配置

    mybatis-plus:
      # 指定mapper.xml文件地址
      mapper-locations: classpath:mapper/*/*Mapper.xml
      # 指定实体类包
      type-aliases-package: cn.wkpower.common.entity
      configuration:
        # 自动将下划线模式 转为 驼峰模式
        map-underscore-to-camel-case: true
    

    在启动类或其他配置类中加入

    import org.mybatis.spring.annotation.MapperScan;
    
    // 指定mapper接口的包
    @MapperScan("cn.wkpower.common.mapper")
    
  3. orm 字段映射

    请先读完这段代码

    import lombok.Data;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    
    
    @Data
    public class UserFeedback {
    
        @TableId(type = IdType.AUTO)
        private Long id;
        
        /**
         * 反馈用户的id
         */
        private Long userId;
    
        /**
         * 图片
         */
        private String img;
        /**
         * 反馈的内容
         */
        private String content;
    
        @TableField(fill = FieldFill.INSERT)
        private LocalDateTime gmtCreate;
    
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private LocalDateTime gmtModified;
    
        // ================= 补充字段区 ===================
        
        @TableField(exist = false)
        private List<String> imgList;
    
    }
    

    是的, 这段代码就完成了ORM数据库映射,Mybaits需要手动写一大串

    注解讲解

    @TableId 指定主键, 参数type为主键值类型, AUTO代表自增, 具体可直接看源码 com.baomidou.mybatisplus.annotation.IdType

类型含义备注
AUTO数据库ID自增需要数据库设置为自增
ID_WORKER全局唯一ID (idWorker)为空时, 框架自动填入
UUID全局唯一ID (UUID)为空时, 框架自动填入
ID_WORKER_STR字符串全局唯一ID (idWorker 的字符串表示)为空时, 框架自动填入

@TableField 指定普通映射字段

字段含义备注
value数据库中表的字段名可省略, 会自动取Java字段名
fill字段自动填充策略可选值 INSERT插入时填充字段,UPDATE更新时填充字段,INSERT_UPDATE插入和更新时填充字段, 具体填充什么内容呢?见后续
  1. 继承Mapper接口

    泛型为model对象。 BaseMapper这个接口可用点进源码看一看, 定义了很多可用直接用的方法, 在运行时, 这些方法会自动被实现,我们不用管

    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import cn.wkpower.common.entity.userinfo.UserFeedback;
    
    public interface UserFeedbackMapper extends BaseMapper<UserFeedback> {
    
    }
    
    
  2. 控制台打印sql 加入以下配置

        /**
         * sql性能分析插件,输出sql语句及所需时间
         */
        @Bean
        public PerformanceInterceptor performanceInterceptor() {
            return new PerformanceInterceptor();
        }
    
    

3. 查询操作

3.1 根据id查询数据

@Autowired
private UserFeedbackMapper userFeedbackMapper;

public void testSelectById(){
    UserFeedback userFeedback = userFeedbackMapper.selectById(1);
    
}

3.2 查询全部数据

@Autowired
private UserFeedbackMapper userFeedbackMapper;

public void testSelectList(){
    List<UserFeedback> userFeedbacks = userFeedbackMapper.selectList(null);
}

3.3 根据一些条件查询

    @Autowired
    private UserinfoMapper userinfoMapper;

    public void testSelectOne() {
        // 查询单个对象 selectOne返回一个对象, selectList返回一个list, 他们的插叙参数都是一样的写法
        Userinfo selectOne = userinfoMapper.selectOne(
                // 构建查询条件
                new QueryWrapper<Userinfo>().lambda()
                        // age大于等于18 sql为 age >= 18    其他: ge大于等于,gt大于,lt小于,le小于等于
                        .ge(Userinfo::getAge, 18)
                        // username的模糊搜索 sql为 %SUN%  其他: rightLike右模糊 leftLike左模糊
                        .like(Userinfo::getUsername, "SUN")
                        // sex的精确查询  sql为 sex = 1    其他: ne不等于
                        .eq(Userinfo::getSex, 1)
            			// 其他方法可以按提示键自己查看
        );

    }

3.4 根据对象查询

有时候 我们不想构建查询条件, 太麻烦了, 前端接口直接传来了对象,我们可用直接使用该进行查询, 但是每个查询条件都是精确查询 就是 =

    @Autowired
    private UserinfoMapper userinfoMapper;

    public void testSelectObjs() {
        Userinfo userinfo = new Userinfo();
        userinfo.setSex(1);
        userinfo.setAddress("西安");

        // 需强转  sql为 sex = 1 and address = '西安'
        List<Object> objects = userinfoMapper.selectObjs(new QueryWrapper<>(userinfo));
    }

3.5 自定义sql复杂查询

有时sql实在太长太复杂了, 用Java代码写会不易于维护, 必须得写SQL了, 方式如下

  1. 在mapper接口定义方法

     List<UserRelationTypeResponse> listExistRelation(@Param("deviceType")Integer deviceType, @Param("userId") Long userId);
    
  2. 在mapper.xml定义sql

        <select id="listExistRelation" resultType="cn.wkpower.common.vo.userinfo.UserRelationTypeResponse">
            SELECT
                user_relation_type
            FROM
                 <if test="deviceType == 1">
                     bpinfo
                 </if>
                <if test="deviceType == 2">
                    gluinfo
                </if>
    
            GROUP BY userid,user_relation_type
            HAVING userid = #{userId}
    
            UNION
            /* 一定存在本人的记录 */
            SELECT 1
        </select>
    
  3. 使用方式

    @Autowired
    private UserinfoMapper userinfoMapper;

    public void testCustomSql() {
        List<UserRelationTypeResponse> userRelationTypeResponses = userinfoMapper.listExistRelation(1, 1L);
    }

发现了没有, 这完全就是Mybatis啊 !

3.6 分页查询

分页功能需新加配置如下

    /**
     * 分页插件: 配置后就可用使用分页功能了
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

代码

    @Autowired
    private UserinfoMapper userinfoMapper;

    public void testPage() {
        // 查询第1页 每页20条数据, 查询条件为空
        IPage<Userinfo> userinfoIPage = userinfoMapper.selectPage(new Page<>(1, 20), new QueryWrapper<>());
        // 查询第2页 每页20条数据, 查询条件为 id倒叙
        IPage<Userinfo> userinfoIPage2 = userinfoMapper.selectPage(new Page<>(2, 20), new QueryWrapper<Userinfo>().lambda().orderByDesc(Userinfo::getUserid));

        // 获取返回结果
        List<Userinfo> records = userinfoIPage2.getRecords();
        // 获取总记录数
        long total = userinfoIPage2.getTotal();
    }

自定义的sql加入分页功能

  1. 在mapper接口的改动如下

    import com.baomidou.mybatisplus.core.metadata.IPage;
    
    
        /**
         * 第一个参数 加入分页对象
         * 返回参数 使用分页对象进行包装
         */
        IPage<BindUserListVO> unBindUserList(IPage<BindUserListVO> page, @Param("medicalId") Long medicalId, @Param("identity") Integer identity);
    
  2. 对结果的取值与上面的方式一样

    // 获取返回结果
    List<Userinfo> records = userinfoIPage.getRecords();
    // 获取总记录数
    long total = userinfoIPage.getTotal();
    

4. 保存操作 ( 增加 / 更新 )

4.1 插入一条数据

@Autowired
private UserinfoMapper userinfoMapper;

public void testInsert() {
    Userinfo userinfo = new Userinfo();
    userinfo.setAge(1);
    userinfo.setUsername("SUN");
    userinfoMapper.insert(userinfo);
}

4.2 插入数据时自动填充创建时间/更新时间

增加填充策略 配置

/**
 * 自动赋值配置
 */
@Bean
public MetaObjectHandler metaObjectHandlerConfig(){
	return new MetaObjectHandler() {
		// 添加时的策略
		@Override
		public void insertFill(MetaObject metaObject) {              
			// 设置创建时间为当前时间, gmtCreate为我的字段名 如果你写的是别的填写的
			setFieldValByName("gmtCreate", LocalDateTime.now(), metaObject); 
			// 设置修改时间为当前时间, gmtModified为我的字段名 如果你写的是别的填写的
			setFieldValByName("gmtModified", LocalDateTime.now(), metaObject);
		}
        // 更新时的策略
		@Override
		public void updateFill(MetaObject metaObject) {
			// 将修改时间设置为当前
			setFieldValByName("gmtModified",  LocalDateTime.now(), metaObject);
		}
	};
}

model类的更改

// INSERT 会走入 上面配置的insertFill方法
@TableField(fill = FieldFill.INSERT)
private LocalDateTime gmtCreate;

// INSERT_UPDATE 会走入 上面配置的insertFill方法和updateFill方法
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime gmtModified;

使用方式

// 无变化
userInfoMapper.insert(userinfo)

4.3 根据id更新数据

    @Autowired
    private UserinfoMapper userinfoMapper;

    public void testUpdateById() {
        Userinfo userinfo = new Userinfo();
        userinfo.setAge(1);
        userinfo.setUsername("SUN2");
        userinfoMapper.updateById(userinfo);
    }

4.4 更新部分字段

@Autowired
private UserinfoMapper userinfoMapper;

public void testUpdate() {
	Userinfo userinfo = new Userinfo();
	userinfo.setAge(1);
	userinfo.setUsername("SUN2");
        
	// 写法一: 第一个参数传更新的值 , 第二个参数为查询条件 
	// 最终的sql为 set age = 1, username = SUN2 WHERE address = "西安"
	userinfoMapper.update(userinfo,new QueryWrapper<Userinfo>().lambda().eq(Userinfo::getAddress,"西安"));
        
	// 写法二: 第一个参数不穿, 第二个参数为更新规则
	// 最终sql为 set age = 18, username=SUN3 WHERE age = 6
	userinfoMapper.update(null,new UpdateWrapper<Userinfo>().lambda().set(Userinfo::getAge,18).set(Userinfo::getUsername,"SUN3").eq(Userinfo::getAge,6));
    }

5. 删除操作

5.1 根据id删除数据

@Autowired
private UserinfoMapper userinfoMapper;

public void testDeleteById() {
    userinfoMapper.deleteById(1);
}

5.2 根据指定查询规则删除数据

@Autowired
private UserinfoMapper userinfoMapper;

public void testDelete() {
    // 构建一个查询条件, 凡是查出来的都会被删除 , 这个写法会删除 age = 18的数据
    userinfoMapper.delete(new QueryWrapper<Userinfo>().lambda().eq(Userinfo::getAge,18));
}

5.3 逻辑删除

逻辑删除即不删除真实数据, 而使用一个字段来表示此条记录是否被删除,常见的实现方式为手动维护 比如 select xxx where isdel = 1 / update xx set isdel = 1

但是MybatisPlus已经支持了此功能, 来看看最优雅的写法!

  1. 首先是Model类的改动

    import com.baomidou.mybatisplus.annotation.TableLogic;
    
    /**
     * 是否删除 1是 0否
     */
    @TableLogic(value = "0", delval = "1")
    private Integer isdel;
    

    字段上加了@TableLogic 注解 value表示没有被删除的值,delval表示被删除的值

  2. 删除数据的写法

    @Autowired
    private UserinfoMapper userinfoMapper;
    
    public void testDelete() {
        userinfoMapper.deleteById(1);
    }
    

    可以看见, 写法没有发生任何改变!

    实际上, 在执行以上代码时, 真正的sql将变为 UPDATE userinfo SET isdel = 1 WHERE id = 1 , 删除操作变为了对isdel字段的更新操作

    还有一个好处是:普通的查询, 例如以下代码 会自动加上 isdel = 0 查出未删除的数据!

    userinfoMapper.selectList(null);
    

标签:教程,MybatisPlus,SpringBoot,userinfoMapper,private,查询,userinfo,public,Userinfo
来源: https://blog.csdn.net/weixin_42195284/article/details/118313534

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有