MyBatis-Plus梳理

一 LomBok 工具使用(这个不是mp范围,但是搭配试用能提高开发效率)

概述:其实就是简化模型类的编写:

坐标:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <!--标识依赖不传递-->
    <optional>true</optional>
</dependency>

主要的注解(都是模型类注解):

@Data 生成 get 和 set 以及 toString,equale 等基础的方法完整的 javabean
@Getter 生成单独的 get 方法
@Setter 解释同上
@ToString
@EqualsAndHashCode
@AllArgsConstructor 生成全部参数的构造方法
@NoArgsConstructor 生成无参的构造方法
@Build 链式编程
链式编程示例:
public void method() {
// Perrsion perrsion = new Perrsion();
//链式编程示例
Perrsion zhangsan =
Perrsion.builder().age(22).name("zhangsan").id(1111L).build();
System.out.println(zhangsan);
}

链式编程的使用格式 类名.builder().属性(值)...bulid(); 

就是个小工具,就这样拉! !!!!


二 MP基本信息:

概述:是对mybati使用的简化,详细信息:简介 | MyBatis-Plus

坐标:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.0</version>
</dependency>

三 mp的注解:

@TableName(“具体的数据库表名”) //用于类上,注明映射类,若是数据库中的表名和实体 类名相同,则忽略不写,写上最好
表前缀在配置文件中配置格式:
# 表前缀,根据情况填写
mybatis-plus.global-config.db-config.table-prefix=tb_
@TableId(指明 id 规则) //实体类属性上,标明主键用,可以在配置文件中设置
配置文件中的配置方式
mybatis-plus.global-config.db-config.id-type = auto
@TableField(“数据库表中字段”) //用于数据库表中字段和实体类中的变量名不相同
@TableField(fill=FieldFill.INSERT) //实体类中变量上,用于完成自动添加插入,但是得配合自己重写的 handler
@TableField(fill=FieldFill.INSERT_UPDATE) //变量名上,更新时完成自动添加,这块主要用于完成一定的修改和更新上
@TableField(exit=false) //用于忽略该变量,不用将该变量映射到数据 库中
配合以上注解可以使得数据库表和模型类的直接映射:
示例(已经做了详细说明):
@Data
// @Getter
// @Setter
// @ToString
// @EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
@Builder //链式编程
/*
* 链式编程示例
Persion zhangsan =
Persion.builder().age(22).name("zhangsan").id(1111L).build();
System.out.println(zhangsan);
*
* */
//mybatisplus 表映射注解
@TableName("tb_user")
//指定表名 建立模型类和表之间的映射,若是表名和类名相同则不写(驼峰命名也是相同),
//注意:若是在配置文件中设置了 tb 延展,user 要是和表名相同,则不用注解
public class Persion implements Serializable {
private static final long serialVersionUID = 8683452581122892189L;
@TableId(type = IdType.AUTO) //主键自增
private Long id;
@TableField(value = "username")
//自动映射表中的 user_name,若是表中的字段名和实体类的字段名相同在,则忽略不写
private String name;
private Integer age;
@TableField(fill = FieldFill.INSERT)//在数据添加时自动补充映射到数据库中的表中
private Date createdate;
//@ TableField(fill =FieldFill.UPDATE)//在数据进行更新时会自动添加到数据库中
@TableField(fill = FieldFill.INSERT_UPDATE)//更新和添加都会填入数据库中的表中
private Date updatedate;
@TableField(exist = false)//忽略这个字段的插入和查询,不希望该值存入数据库
private String ts;
private Sex sex;}

这块要注意数据库中的字段名字和数据类型和模型类的数据类型以及字段的相同:

1 注意数据类型的匹配 Date 类型对应数据库中的 datetime 类型,数据类型不匹 无法完成映射
2 注意在数据库中的字段名为 createdate,则在实体类中对应的字段只能是 createdate(当然也可以通过注解绑定), 但是实体类中的子命名不为 createDate,因为 createDate 对应数据库表中的数据类型 只能是 create_date,从而造成无定法完,handler 中的配置属性名也是一样 

四 mp的枚举:

就是对一些常用的数据做的封装

使用mp的枚举格式必须进行枚举包的扫描配置

#具体的枚举类所在的包,在SpringBoot的配置文件中的配置
mybatis-plus.type-enums-package = com.nanfeng.nan.mybatisplus.enums

格式:

public enum 枚举类名字 implements IEnum{} //实现 mybatisplus,对一些常用的 不变的值的使用
示例(用到参考格式修改即可):
/*
* 用于一些常用的不变的数据
* 通过实现 mybatisplus 枚举接口 IEnum 实现* */
public enum Sex implements IEnum<Integer> {
男(1, "男"), 女(2, "女");
private Integer code;
private String doc;
Sex(Integer code, String doc) {
this.code = code;
this.doc = doc;
}
/*
* 将 code 转换到数据库中的数字存储,这块要是不写,无法完成枚举的映射
* */
@Override
public Integer getValue() {
return this.code; }
/*
* 将 code 自动转换成中文的文* */
@Override
public String toString() {
return this.doc; }}

五 mp的mapper文件:

在使用 mybatisplus 时 mapper 接口无需我们自己 写,继承 mybatisplus 提供的父 类 BaseMapper<T>即可完成 mapper 的各项功能,BaseMapper中封装了各种基本的方法,我们直接调用这些方法即可
mapper示例:
@Mapper //这块不标注,就需要引导类进行 mapper 的扫描
public interface PersionMapper extends BaseMapper<Persion> {
}

六 mp的Service:

用不用这个Service看我们自己,若是我们不需要在Service中做业务处理,只是中转调用,直接使用mp提供的即可,否则我们自己写Service做相关的业务处理,mp的Service实现:

1 定义接口继承IService<T>接口

2 定义实现类继承ServiceImpl<mapper,entity>,然后实现定义的接口即可:

示例:

接口:

public interface PersionService extends IService<Persion> {
}

实现类:

@Service
public class PersionServiceImp extends ServiceImpl<PersionMapper, Persion>implements PersionService {
}

七 mybatisplus 的拦截器:

在使用 mybatisplus 的分页查询时必须配置拦截器, 否则无法实现分页的拦截:

直接粘贴,谁写都一样,没有任何的技术含量:

@Configuration
public class PageConfig {

    /**
     * 3.4.0之前的版本用这个
     * @return
     */
   /* @Bean
    public PaginationInterceptor paginationInterceptor(){
        return  new PaginationInterceptor();
    }*/

    /**
     * 3.4.0之后提供的拦截器的配置方式
     * @return
     */
   @Bean
   public MybatisPlusInterceptor mybatisPlusInterceptor(){
       MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
       mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
       return mybatisPlusInterceptor;
   }
}

关于分页查询,下面做方法调用时候解释

八 mybaisplus 的 handler

mybatisplus 的 handler 主要用于自动插入,即配@TaleField(fill=INSERT_UPDATE ) 使用,就是呗该注解标注的变量在映射进数据库的时候会完成对该变量做自动的后置操作

 示例:


@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    /*
     * 说明:
     * 对于第一创建,created 和 update 相同,为同一时间
     * 但是对于第二次修改,created 存在,updated 也存在,
     * 触发第二个方法,会对该对象进行再 updated 的再次刷新
     * */
    @Override
    public void insertFill(MetaObject metaObject) {
/*
获取 metobjeect 中属性(凡是用到 TableField 注解的,都会在这进行检查)
根据指定的名称获取具体属性的赋值情况,若是为空就进行数据的填充
*/
//根据 getFieldValByName 方法将 mataObject 对象(其实就是一个个使用@TableField注解标注的属性的集合),指定属性检测赋值请款
        Object created = getFieldValByName("createdate", metaObject);
//如果 created 字段为空进行自动填充.(如果不为空,忽略)
        if (null == created) {
//为该属性赋值设置自动填充数据
            setFieldValByName("createdate", new Date(), metaObject);
        }
        Object updated = getFieldValByName("updatedate", metaObject);
//如果 update 字段为空进行自动填充.(如果不为空,忽略)
        if (null == created) {
//为该属性赋值设置自动填充数据
            setFieldValByName("updatedate", new Date(), metaObject);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        /*
        * 下面三行任选一行即可
        * */
        //只要改属性有变动就自动实现
        setUpdateFieldValByName("updatedate", new Date(), metaObject);
        strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        fillStrategy(metaObject, "updateTime", LocalDateTime.now());
    }
}

十 mapper的常用方法:

没啥好说的,直接看例子吧!

@SpringBootTest
@RunWith(SpringRunner.class)
class UserMapperTest {
@Autowired
private UserMapper userMapper;
/**
* 根据 id 查询
*/
@Test
public void testSelectById() {
User user = userMapper.selectById(1L);
System.out.println(user);
}
/**
* 添加
*/
@Test
public void testInsert() {
User user = new User();
//user.setId(6L);
user.setUserName("zahnsgan");
user.setPassword("root123");
int count = userMapper.insert(user);
System.out.println(count);
}
/**
* 删除
*/
@Test
public void testDelete() {
/*
//1. 根据 id 删除
int count = userMapper.deleteById(8L);
*/
/*
//2. 根据 id 集合批量删除
List ids = new ArrayList();
ids.add(6);
ids.add(7);
userMapper.deleteBatchIds(ids);
*/
//3. 根据 map 构造条件,删除
Map<String, Object> map = new HashMap<>();
//delete from tb_user where user_name = ? and age = ?
map.put("user_name","zhangsan");
map.put("age","18");
userMapper.deleteByMap(map);} }
/**
* 修改
*/
@Test
public void testUpdateById() {
User user = new User();
user.setId(2L);
user.setPassword("1111111");
int count = userMapper.updateById(user);
}
/**
* 分页查询:
* 1. 当前页码:currentPage
* 2. 每页显示条数:size
* 注意:使用 mybatisplus 的分页要设置一个拦截器!!!
*/
@Test
public void testSelectPage() {
int current = 1;//当前页码
int size = 2;//每页显示条数
IPage<User> page = new Page(current,size);
userMapper.selectPage(page,null);
List<User> records = page.getRecords();//当前页的数据
long pages = page.getPages();//总页数 2
long total = page.getTotal();//总记录数 4
System.out.println(records);
System.out.println(pages);
System.out.println(total);
}
}

条件构造器:

基本的运算符号和对应的方法:

eq( ) :  等于 =
ne( ) :  不等于 <>
gt( ) :  大于 >
ge( ) :  大于等于  >=
lt( ) :  小于 <
le( ) :  小于等于 <=
between ( ) :  BETWEEN 值1 AND 值2 
notBetween ( ) :  NOT BETWEEN 值1 AND 值2 
in( ) :  in
notIn( ) :not in

条件构造器查询
@SpringBootTest
@RunWith(SpringRunner.class)
public class WrapperTest {
@Autowired
private UserMapper userMapper;
/**
* 基础比较查询
* <p>
* Wrapper:
* 1.QueryWrapper
* LambdaQueryWrapper
* 2.UpdateWrapper
* LambdaUpdateWrapper
*/
@Test
public void testWrapper1() {
//1.创建查询条件构建器
QueryWrapper<User> wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.eq("user_name", "lisi")
.lt("age", 23)
.in("name", "李四", "王五");
/*
select * from tb_user where user_name = ? and age < ? and name in (?,?)
*/
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
@Test
public void testWrapper2() {
//1.创建查询条件构建器
QueryWrapper<User> wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.eq("user_name", "lisi")
.or()
.lt("age", 23)
.in("name", "李四", "王五");
/*
select * from tb_user where user_name = ? or age < ? and name in (?,?)
*/
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
/**
* 模糊查询
*/
@Test
public void testWrapper3() {
//1.创建查询条件构建器
QueryWrapper<User> wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.likeLeft("user_name", "zhang");
/*
SELECT id,user_name,password,name,age,email
from tb_user
where user_name like ?
%zhang
*/
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
/**
* 排序查询
*/
@Test
public void testWrapper4() {
//1.创建查询条件构建器
QueryWrapper<User> wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.eq("user_name", "lisi")
.or()
.lt("age", 23)
.in("name", "李四", "王五")
//.orderBy(true,true,"age")
.orderByDesc("age"); //倒序查询.顺序为 asc
/*
select * from tb_user where user_name = ? or age < ? and name in (?,?)
order by age asc
*/
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
/**
* select:指定需要查询的字段
*/
@Test
public void testWrapper5() {
//1.创建查询条件构建器
QueryWrapper<User> wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.eq("user_name", "lisi")
.or()
.lt("age", 23)
.in("name", "李四", "王五")
//.orderBy(true,true,"age")
.orderByDesc("age")
.select("id", "user_name");
/*
select id,user_name from tb_user where user_name = ? or age < ? and name in (?,?)
order by age asc
*/
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
/**
* 分页条件查询:使用 mp 的分页, 必须写拦截器
*/
@Test
public void testWrapper6() {
int current = 1;//当前页码
int size = 2;//每页显示条数
//1. 构建分页对象
Page<User> page = new Page<>(current, size);
//2. 构建条件对象
QueryWrapper<User> wrapper = new QueryWrapper();
wrapper.lt("age", 23);
userMapper.selectPage(page, wrapper);
List<User> records = page.getRecords();
long total = page.getTotal();
long pages = page.getPages();
System.out.println(records);
System.out.println(total);//2
System.out.println(pages);//1
}
/**
* LambdaQueryWrapper:消除代码中的硬编码
*/
@Test
public void testWrapper7() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getUserName, "zhangsan");
User user = userMapper.selectOne(wrapper);
}
/**
* 删除条件
*/
@Test
public void testWrapper8() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("user_name", "bbb");
userMapper.delete(wrapper);
}
/**
* 修改条件
*/
@Test
public void testWrapper9() {
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
//条件
wrapper.eq("user_name", "lisi")
.set("password", "22222");
//update tb_user set password = ? where user_name = ?
userMapper.update(null, wrapper);
}
@Test
public void testWrapper10() {
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
//条件
wrapper.eq("user_name", "lisi");
//update tb_user set password = ?,age = ? where user_name = ?
User user = new User();
user.setPassword("3333");
user.setAge(33);
userMapper.update(user, wrapper);
  }
}

mp实现的修改只是将指定的字段做了修改,原来没有指定的字段还是原来数据,并不是null 

 需要注意的是修改条件构造器和lam格式的条件构造器,大致上增删改查就这样完成了!!!

十一 面对多表的联查增删改查使用mp的思路:

方式一:

在mapper中添加自己的方法即可:

示例:

/**
 * 使用mp定义Mapper,需要让Mapper接口继承 BaseMapper接口。
 */

public interface UserMapper extends BaseMapper<User> {
    /**
     * 这个sql写的有问题,mp实现多表操作其实就是这样实现的(或者建立xml映射文件)
     * @return
     */
    @Select("select name, age from tb1,tb2 where id=1")
    public User selectManyTable();
}

方式二:

持久层进行单表查询,业务层实现pojo的数据重组

十二 配置文件:

plication.properties
# datasource
spring.datasource.url = jdbc:mysql://47.119.137.8:3306/mytest
spring.datasource.password = root
spring.datasource.username = root
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
# myatisplus 配置
# 表前缀,根据情况填写
#mybatis-plus.global-config.db-config.table-prefix=
# id 策略
mybatis-plus.global-config.db-config.id-type = auto
# 日志,查看生成的 sql 语句
mybatis-plus.configuration.log-impl = org.apache.ibatis.logging.stdout.StdOutImpl
# 枚举包的扫描(该枚举完成对一些不变数据的赋值)
mybatis-plus.type-enums-package = com.nanfeng.nan.mybatisplus.enums

使用mp注意事项:

(1)实体类的变量名和数据库中的表的字段名 数据库 username --> 实体类 username -->错误 userName 数据库 user_name --> 实体类 userName -->错误 username 一定注意映射时字段和变量的名字对应,若是不对应,不对应时注解标注
(2) 设置自动添加熟悉时需要重写 handler,再 handler 中做数据处理(格在上面文档)
(3) 在使用 mybatisplus 的分页查询时需要设置拦截器(配置方法在上面文档
基本上就这样了,啦啦啦去啦啦啦啦啦啦啦..................................................完事!!!!,
关于代码生成器,其实就是执行指定代码,生成模板,这个就算了,打死也不想用,太麻烦,自己动手,我觉得更简单   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis-Plus是一个基于MyBatis框架的增强工具库,它可以简化SQL的编写过程。根据引用,MyBatis-Plus是由谁帮我们写的呢?答案是我们自己。我们需要在项目中引入MyBatis-Plus的依赖,并根据需要配置相关的参数和插件。引用提到了如何配置日志,这是为了方便我们在调试和排查问题时能够更好地查看生成的SQL语句。 对于MyBatis-Plus的方法来自哪里的问题,可以根据引用中的描述得知,MyBatis-Plus提供了一套CRUD扩展的方法,使得我们在操作数据库时更加方便。这些方法是MyBatis-Plus库自己定义和实现的。 关于如何使用MyBatis-Plus,根据引用给出的代码示例,我们可以通过配置拦截器组件来使用MyBatis-Plus。可以在项目中定义一个MybatisPlusInterceptor的Bean,并通过addInnerInterceptor方法添加需要的插件,比如分页插件和乐观锁插件。配置好拦截器后,我们就可以直接使用MyBatis-Plus提供的Page对象进行分页查询,如引用中的代码所示。 总结来说,MyBatis-Plus是我们自己引入并配置的一个增强工具库,它提供了简化SQL编写和CRUD操作的方法。我们可以根据需要配置相关参数和插件,并直接使用MyBatis-Plus提供的方法来进行数据库操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Mybatis-Plus-【通俗易懂全讲解】](https://blog.csdn.net/qq_55293923/article/details/124382040)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值