一篇文章读懂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提供了批量操作的实现,比如: 批量添加、批量修改。

相关内容

热门资讯

追梦少年作文850字(精简3... 追梦少年作文850字 篇一追梦少年追梦少年是指那些积极向上、勇敢追求梦想的年轻人。他们充满激情和动力...
二年级作文我喜欢狮子(优秀6... 二年级作文我喜欢狮子 篇一我喜欢狮子我喜欢狮子,因为它们是世界上最强壮的动物之一。狮子有一头浓密的金...
看电影作文200字二年级【实... 看电影作文200字二年级 篇一我喜欢看电影我喜欢看电影,因为电影可以带给我快乐和惊喜。每次我看电影,...
小宁捡到钱二年级作文【经典6... 小宁捡到钱二年级作文 篇一今天放学的时候,我在回家的路上捡到了一张钱。当时我正在走路,突然看到地上闪...
二年级游乐园冲浪作文(优秀6... 二年级游乐园冲浪作文 篇一我最喜欢的游乐园冲浪今天,我和爸爸妈妈去了一个很大很有趣的游乐园。这个游乐...
二年级有趣的游戏作文200字... 二年级有趣的游戏作文200字 篇一:捉迷藏捉迷藏是我们二年级最喜欢的游戏之一。这个游戏的规则很简单:...
我的好朋友二年级作文【实用6... 我的好朋友二年级作文 篇一我的好朋友我有一个非常好的朋友,她叫小芳。她和我在同一个班级,我们从小学一...
我的家【优质6篇】 我的家 篇一我的家是一个温馨而快乐的地方。无论是平日的热闹还是周末的宁静,家里总是充满着欢声笑语和爱...
二年级作文不少于200个字【... 二年级作文不少于600个字 篇一我的暑假生活暑假终于来了,我迫不及待地迎接了这个长假。在这个暑假里,...
二年级暑假趣事作文捉老鼠(推... 二年级暑假趣事作文捉老鼠 篇一暑假快到了,我和弟弟决定在家里玩捉老鼠的游戏。我们找来了一些小道具,准...
小学二年级避暑山庄旅游作文(... 小学二年级避暑山庄旅游作文 篇一我和家人去了一个非常有趣的地方——避暑山庄。这个地方真的很美,有很多...
二年级作文游庐山【精简6篇】 二年级作文游庐山 篇一我和爸爸妈妈一起去了庐山。庐山是中国著名的山岳风景区,被誉为“江南第一山”。我...
二年级下册看图写话春天来了作... 二年级下册看图写话春天来了作文 篇一春天来了春天来了,大地变得生机勃勃。图中的小朋友们正在户外玩耍,...
二年级打雪仗作文指导【通用6... 二年级打雪仗作文指导 篇一打雪仗是冬天最有趣的活动之一,对于二年级的小朋友来说,更是一种享受。下面是...
二年级美丽的早晨作文(实用6... 二年级美丽的早晨作文 篇一美丽的早晨早晨的阳光透过窗户洒进来,房间里弥漫着一股清新的味道。我慢慢睁开...
小学二年级海边旅游作文200... 小学二年级海边旅游作文200字作文 篇一我和家人去海边旅游了,真是一个美好的经历!早上,我们一大早就...
二年级【优秀6篇】 二年级 篇一:我的暑假生活暑假终于来了,我迫不及待地开始了我的暑假生活。在这个悠长的假期里,我过得非...
赏荷花二年级作文【通用6篇】 赏荷花二年级作文 篇一欣赏荷花的美丽今天,我和爸爸妈妈一起去公园赏荷花。公园里有一个大大的荷花池,里...
舞蹈汇演作文二年级【精彩6篇... 舞蹈汇演作文二年级 篇一舞蹈汇演是一场精彩绝伦的表演,让我感受到了舞蹈的魅力和美妙。我在二年级的时候...
二年级作文我家的厨师(优质6... 二年级作文我家的厨师 篇一我家的厨师是我妈妈。她是一个非常厉害的厨师,每天都能给我们做出美味可口的饭...