一篇文章读懂mybatis-plus原理和CRUD接口
创始人
2024-05-13 14:20:35
0

Myabtis-Plus配置

MybatisPlus官网

官方文档上有详细的spring boot配置mybatis-plus的教程,此处就不在详细赘述。

mybatis-plus是基于spring完成的只能再spring相关应用上实现。

  1. 引入父工程

在这里插入图片描述
注意mybatis-plus和spring boot的版本匹配不然会出现
在这里插入图片描述

推荐版本

  org.springframework.bootspring-boot-starter-parent2.1.6.RELEASE 
        com.baomidoumybatis-plus-boot-starter3.1.0

参考pom依赖

  org.springframework.bootspring-boot-starter-weborg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtestcom.baomidoumybatis-plus-boot-starter3.1.0mysqlmysql-connector-java8.0.17

配置并连接数据库

  • 创建数据库表

在这里插入图片描述

  • 添加若干数据

在这里插入图片描述

  • application.properties中配置datasource

datasource是连接数据库必须的配置,数据库驱动包通过反射来加载这些信息

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://139.9.209.93/task?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
  • ORM映射

将数据库表映射到java的对象中,实现信息交换。

@Data
@TableName("bt_04")
public class BT_04 {@TableId(value = "opt_id")private Integer id;@TableField("drag_start_lat")private Double DragStartLat;@TableField("drag_start_lon")private Double DragStartLon;@TableField("drag_end_lat")private Double DragEndLat;@TableField("drag_end_lon")private Double DragEndLon;
}

注意@TableName@TableField相辅相成共同完成ORM映射。后者辅助前者。

名称作用备注
@TableName完成数据库表到对象的映射位于bean的开头参数为数据库表名
@TableField完成字段到属性的映射mp默认下划线命名到驼峰命名转换,遵守规则可以省去该注解,参数为对象属性
@TableId完成主键的映射参数可以设置自增等条件

car_name[下环线命名]
carName[驼峰命名]
mybatis-plus默认前者转后者。

mp作为myabtis的升级版延续了前身的注解,也扩展了许多新的注解

在这里插入图片描述
具体请参考官网 MyBatis-Plus

之前已经通过@TableFieId注解将数据库表实现映射了,而关系的桥梁就是sql,那么如何应用sql呢?
通过mybatis的mapper接口和mapper映射文件关联即可。但是mp有更好的方法就是BaseMapper
一个BaseMapper管理一个映射关系。

myabtis

public interface BTfourMapper {    //extends BaseMapper@Select("select * from bt_04")List query();
}

mybatis-plus

public interface BTfourMapper extends BaseMapper{ }

通过BaseMapper的泛型映射后无需编写sql语句更方便。

可以看到BaseMapper中定义了很多接口来满足常规需求

在这里插入图片描述

因此只要集成该接口就可以调用方法,由于泛型的绑定实现了表的唯一性。

BaseMapper的CRUD接口

public interface BTfourMapper extends BaseMapper{}

任意接口继承BaseMapper就可以使用其方法,在通过泛型绑定变成相关表的专属mapper,例如

//mybatispublic interface UserMapper{/***相关CURD操作*/List queryAll();...//每个查询返回结果使用泛型接收,所以mapper下的有需要的都要写
}//mybatis-plus
public interface UserMapper extends BaseMapper{
} //在接口处使用泛型,后续直接使用

BaseMapper的具体方法及使用参考官网

mapper实例:

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class BTtest {@AutowiredBTfourMapper bTfourMapper;@Testpublic void method(){List bt_04s = bTfourMapper.selectList(null);System.out.println(bt_04s);}
}

在该单元测试中自动装配的mapper为一个只集成BaseMapper的接口,selectList为接口super的方法,参数为一个Wraper(查询条件包装),没有填null。

在这里插入图片描述

BaseMapper中包含了基本的CURD操作,其实就是对mapper做了一个包装,因为每个mapper无外乎都是CURD操纵,具有统一型,面向不同的对象又具有多样性,包装后的mapper具有通用性。---- 感谢开发团队 😮

下面是BaseMapper的源码:

public interface BaseMapper {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);
}
 

需要注意的是使用BaseMapper一定要加上泛型。

Model的CRUD接口

细心的朋友可能就发现使用mapper时都有相应的xml的文件映射呀,或者相应的注解绑定着sql语句呀?

是的,上面的实例并未出现sql语句,是如何实现了的呢?对于CURD操作也是具有相似性的,例如

// 表a查询select username,password,status from user//查询表2select code,name,status from sys_dict

同理只要将表的字段与对应sql的条件对应上也就具通用性,如下所示:

package com.baomidou.mybatisplus.core.enums;public enum SqlMethod {INSERT_ONE("insert", "插入一条数据(选择字段插入)", ""),DELETE_BY_ID("deleteById", "根据ID 删除一条数据", ""),DELETE_BY_MAP("deleteByMap", "根据columnMap 条件删除记录", ""),DELETE("delete", "根据 entity 条件删除记录", ""),DELETE_BATCH_BY_IDS("deleteBatchIds", "根据ID集合,批量删除数据", ""),LOGIC_DELETE_BY_ID("deleteById", "根据ID 逻辑删除一条数据", ""),LOGIC_DELETE_BY_MAP("deleteByMap", "根据columnMap 条件逻辑删除记录", ""),LOGIC_DELETE("delete", "根据 entity 条件逻辑删除记录", ""),LOGIC_DELETE_BATCH_BY_IDS("deleteBatchIds", "根据ID集合,批量逻辑删除数据", ""),UPDATE_BY_ID("updateById", "根据ID 选择修改数据", ""),UPDATE("update", "根据 whereEntity 条件,更新记录", ""),LOGIC_UPDATE_BY_ID("updateById", "根据ID 修改数据", ""),LOGIC_UPDATE_ALL_COLUMN_BY_ID("updateAllColumnById", "根据ID 选择修改数据", ""),SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s}"),SELECT_BY_MAP("selectByMap", "根据columnMap 查询一条数据", ""),SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", ""),SELECT_ONE("selectOne", "查询满足条件一条数据", ""),SELECT_COUNT("selectCount", "查询满足条件总记录数", ""),SELECT_LIST("selectList", "查询满足条件所有数据", ""),SELECT_PAGE("selectPage", "查询满足条件所有数据(并翻页)", ""),SELECT_MAPS("selectMaps", "查询满足条件所有数据", ""),SELECT_MAPS_PAGE("selectMapsPage", "查询满足条件所有数据(并翻页)", ""),SELECT_OBJS("selectObjs", "查询满足条件所有数据", ""),LOGIC_SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s} %s"),LOGIC_SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "");private final String method;private final String desc;private final String sql;private SqlMethod(String method, String desc, String sql) {this.method = method;this.desc = desc;this.sql = sql;}public String getMethod() {return this.method;}public String getDesc() {return this.desc;}public String getSql() {return this.sql;}
}

SqlMethod是mybatis封装sql的类,位于com.baomidou.mybatisplus.core.enums包下该类的返回值是一个集合。通过SqlMethod.获取需要的sql语句。

SqlMethod不是泛型没有通用性,还需要包装类对其解析封装并具有泛型,这个类就是Model

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.baomidou.mybatisplus.extension.activerecord;import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionUtils;public abstract class Model implements Serializable {private static final long serialVersionUID = 1L;public Model() {}public boolean insert() {SqlSession sqlSession = this.sqlSession();boolean var2;try {var2 = SqlHelper.retBool(sqlSession.insert(this.sqlStatement(SqlMethod.INSERT_ONE), this));} finally {this.closeSqlSession(sqlSession);}return var2;}public boolean insertOrUpdate() {return !StringUtils.checkValNull(this.pkVal()) && !Objects.isNull(this.selectById(this.pkVal())) ? this.updateById() : this.insert();}public boolean deleteById(Serializable id) {SqlSession sqlSession = this.sqlSession();boolean var3;try {var3 = SqlHelper.delBool(sqlSession.delete(this.sqlStatement(SqlMethod.DELETE_BY_ID), id));} finally {this.closeSqlSession(sqlSession);}return var3;}public boolean deleteById() {Assert.isFalse(StringUtils.checkValNull(this.pkVal()), "deleteById primaryKey is null.", new Object[0]);return this.deleteById(this.pkVal());}public boolean delete(Wrapper queryWrapper) {Map map = new HashMap(1);map.put("ew", queryWrapper);SqlSession sqlSession = this.sqlSession();boolean var4;try {var4 = SqlHelper.delBool(sqlSession.delete(this.sqlStatement(SqlMethod.DELETE), map));} finally {this.closeSqlSession(sqlSession);}return var4;}public boolean updateById() {Assert.isFalse(StringUtils.checkValNull(this.pkVal()), "updateById primaryKey is null.", new Object[0]);Map map = new HashMap(1);map.put("et", this);SqlSession sqlSession = this.sqlSession();boolean var3;try {var3 = SqlHelper.retBool(sqlSession.update(this.sqlStatement(SqlMethod.UPDATE_BY_ID), map));} finally {this.closeSqlSession(sqlSession);}return var3;}public boolean update(Wrapper updateWrapper) {Map map = new HashMap(2);map.put("et", this);map.put("ew", updateWrapper);SqlSession sqlSession = this.sqlSession();boolean var4;try {var4 = SqlHelper.retBool(sqlSession.update(this.sqlStatement(SqlMethod.UPDATE), map));} finally {this.closeSqlSession(sqlSession);}return var4;}public List selectAll() {SqlSession sqlSession = this.sqlSession();List var2;try {var2 = sqlSession.selectList(this.sqlStatement(SqlMethod.SELECT_LIST));} finally {this.closeSqlSession(sqlSession);}return var2;}public T selectById(Serializable id) {SqlSession sqlSession = this.sqlSession();Model var3;try {var3 = (Model)sqlSession.selectOne(this.sqlStatement(SqlMethod.SELECT_BY_ID), id);} finally {this.closeSqlSession(sqlSession);}return var3;}public T selectById() {Assert.isFalse(StringUtils.checkValNull(this.pkVal()), "selectById primaryKey is null.", new Object[0]);return this.selectById(this.pkVal());}public List selectList(Wrapper queryWrapper) {Map map = new HashMap(1);map.put("ew", queryWrapper);SqlSession sqlSession = this.sqlSession();List var4;try {var4 = sqlSession.selectList(this.sqlStatement(SqlMethod.SELECT_LIST), map);} finally {this.closeSqlSession(sqlSession);}return var4;}public T selectOne(Wrapper queryWrapper) {return (Model)SqlHelper.getObject(this.selectList(queryWrapper));}public IPage selectPage(IPage page, Wrapper queryWrapper) {Map map = new HashMap(2);map.put("ew", queryWrapper);map.put("page", page);SqlSession sqlSession = this.sqlSession();try {page.setRecords(sqlSession.selectList(this.sqlStatement(SqlMethod.SELECT_PAGE), map));} finally {this.closeSqlSession(sqlSession);}return page;}public Integer selectCount(Wrapper queryWrapper) {Map map = new HashMap(1);map.put("ew", queryWrapper);SqlSession sqlSession = this.sqlSession();Integer var4;try {var4 = SqlHelper.retCount((Integer)sqlSession.selectOne(this.sqlStatement(SqlMethod.SELECT_COUNT), map));} finally {this.closeSqlSession(sqlSession);}return var4;}public SqlRunner sql() {return new SqlRunner(this.getClass());}protected SqlSession sqlSession() {return SqlHelper.sqlSession(this.getClass());}protected String sqlStatement(SqlMethod sqlMethod) {return this.sqlStatement(sqlMethod.getMethod());}protected String sqlStatement(String sqlMethod) {return SqlHelper.table(this.getClass()).getSqlStatement(sqlMethod);}protected Serializable pkVal() {return (Serializable)ReflectionKit.getMethodValue(this, TableInfoHelper.getTableInfo(this.getClass()).getKeyProperty());}protected void closeSqlSession(SqlSession sqlSession) {SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(this.getClass()));}
}

有了Model后,直接使用该类可以进行CRUD,但是必须存在对应的mapper继承BaseMapper。基本步骤就是实体类继承Model添加泛型,对应Mapper继承BaseMapper,然后实体类对象也可以进行CRUD操作。

实例:

//实体类继承Model添加泛型
@TableName("user")
public class User extends Model {@TableIdprivate int id;@TableField("username")private String username;@TableField("password")private String password;
}
//对应接口继承BaseMapper
public interface UserMapper extends BaseMapper{
}
//实体类直接调用方法
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class UserMapperTest {//@Autowired User user;@Testpublic void one(){User user = new User();List users = user.selectList(null);System.out.println(users);}
}

Model调用CRUD的接口的限制是需要接收到实体类参数。

IService的CRUD接口

service调用方法基本方法比mapper层调用多了service层

//实体类
@TableName("user_address")
public class UserAddress {private int id;private int address_id;private String detail_address;private int user_id;private Date create_time;private Date update_time;private String name;private String phone;
}
//mapper层
public interface UserAddressMapper extends BaseMapper {
}

mapper没有@MapperScan注解的话需要加@Component

service接口继承Iservice,并且service接口的实现类要继承ServiceImpl

//service层//接口
public interface UserAddressService extends IService {
}//接口实现类
@Service
public class UserAddressServiceImpl extends ServiceImplimplements UserAddressService{
}

在这里插入图片描述

具体需要在那层调用要根据实际需求。

//测试
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class UserAddressTest {@AutowiredUserAddressService userAddressService;@Testpublic void methodOne(){UserAddress one = userAddressService.getById(1);System.out.println(one);}
}

在这里插入图片描述

总结:

1、Model:使用映射类pojo继承model,直接使用该类可以进行CRUD,但是必须存在对应的mapper继承BaseMapper;

2、BaseMapper和Iservice
BaseMapper是使用dao层数据进行CRUD,只需要进行使用dao层接口继承BaseMapper即可;
Iservice是使用service层进行CRUD,需要使用service接口继承Iservice,并且service接口的实现类要继承ServiceImpl;

BaseMapper和Iservice里面提供的方法都差不多,只是Iservice提供了批量操作的实现,比如: 批量添加、批量修改。

相关内容

热门资讯

公司员工大会主持稿 公司员工大会主持稿  在现在的社会生活中,需要使用主持稿的情况越来越多,主持稿一般是由主持人根据场景...
开业的致辞 开业的致辞15篇  在日常的学习、工作、生活中,大家都对致辞很是熟悉吧,致辞是指在举行会议或某种仪式...
毕业聚餐主持词 毕业聚餐主持词  主持词是主持人在节目进行过程中用于串联节目的串联词。在当今中国社会,主持人在活动中...
女娲传说之灵珠经典台词 女娲传说之灵珠经典台词15句  你们根本不懂爱,你们的爱太过自私,不择手段。——仙乐  你放心,我不...
青春演讲比赛主持词 青春演讲比赛主持词  主持:  男——李勇  女——张雨  女:我与祖国共奋进男:我为崛起献青春。 ...
年会赞助商致辞 年会赞助商致辞(精选5篇)  在日常的学习、工作、生活中,要用到致辞的情况还是蛮多的,致辞具有很强的...
培训会主持词 培训会主持词(精选10篇)  在日常中,大家总免不了要培训及会议吧,那么你知道主持词怎么写吗?下面是...
电影《三少爷的剑》经典台词 电影《三少爷的剑》经典台词精选  1. 冷风如刀,大地荒漠,苍天无情。  2. 这世上永远有两种人,...
《十六个夏天》的经典台词 《十六个夏天》的经典台词大全  1.就说我不是他的收藏品,乱说什么啊!  2.说话冲的人,心里都是软...
80岁生日宴会致辞 80岁生日宴会致辞(精选11篇)  在学习、工作或生活中,大家都不可避免地会接触到致辞吧,致辞具有有...
婚宴长辈证婚人致辞 婚宴长辈证婚人致辞  在平日的学习、工作和生活里,大家总少不了要接触或使用致辞吧,致辞受场合、事件的...
元旦舞会主持词 元旦舞会主持词(精选7篇)  主持词要尽量增加文化内涵、寓教于乐,不断提高观众的文化知识和素养。在人...
圣诞联欢会主持词 圣诞联欢会主持词  活动对象的不同,主持词的写作风格也会大不一样。时代不断在进步,主持成为很多活动不...
美好童年—庆“六一”大型活动... 美好童年—庆“六一”大型活动主持词  利用在中国拥有几千年文化的诗词能够有效提高主持词的感染力。随着...
毕业晚会主持词串词 毕业晚会主持词串词  毕业,是人生的一个转折点,愿你们能展开双翼,飞得更高、看得更远。下面是小编给大...
运动会致辞 运动会致辞(精选5篇)  无论在学习、工作或是生活中,大家或多或少都用到过致辞吧,致辞要求风格的雅、...
六一儿童节的主持稿 六一儿童节的主持稿(精选8篇)  随着社会一步步向前发展,我们都不可避免地要接触到主持稿,主持稿是主...
元旦文艺汇演主持稿 元旦文艺汇演主持稿范文(通用5篇)  在当下社会,很多情况下我们需要用到主持稿,主持稿起到承上启下的...
颁奖主持词 颁奖主持词三篇  主持人在一场活动中是十分重要的,一个好的主持人是一直带动着活动过程中的气氛,让大家...
婚宴答谢宴简短主持词 婚宴答谢宴简短主持词  主持词要根据活动对象的不同去设置不同的主持词。在人们积极参与各种活动的今天,...