mybatis-plus整合spring boot极速入门

使用mybatis-plus整合spring boot,接下来我来操作一番。

一,创建spring boot工程

勾选下面的选项

紧接着,还有springboot和依赖我们需要选。

这样我们就创建好了我们的spring boot,项目。

简化目录结构:

我们发现,这些零碎文件很多,占时用不到的,就先删除。

看看简化后的,项目目录结构。

修改boot项目版本:

启动项目:

找到启动来,把我们的项目跑起来。

可以看到项目是正常启动的

二,添加依赖

添加mybatis-plus依赖:

<!--mybatis-plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.5</version></dependency>
添加mysql依赖:

        <!-- mysql依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency>
yml文件的配置:

把一properties结尾的文件,改成yml结尾的格式

 改后的效果:

我添加了下面的配置:

#项目的端口
server:port: 8080#mysql配置
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mp_db?serverTimezone=UTCusername: rootpassword: root#mabatis-plus的配置
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印sql日志map-underscore-to-camel-case: true  # 是否开启驼峰命名转换
运行项目:

项目还是正常启动的

三,创建各种业务层

我们把mapper,service,controller,utils都创建好,看看目录结构。

Emp实体类

代码:

@Data
public class Emp {private Long id; // 员工IDprivate String name; // 员工姓名private String password; // 密码private Integer age; // 年龄private String tel; // 电话号码}

mapper接口:

代码:

@Mapper
public interface EmpMapper extends BaseMapper<Emp> {
}

EmpService接口:

代码:

public interface EmpSerevice extends IService<Emp> {
}
 EmpServiceImpl:实现类

代码:

@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpSerevice{}
 EmpController类:

代码:

@RestController
@RequestMapping("/emps")
public class EmpController {}
新建一个测试类:

代码:

@Slf4j
@SpringBootTest
public class TestMp {}

四,测试mybatis-plus的service层接口:

测试查询:
mp的service提供的查询方法:

getById   通常用于表示根据ID获取数据的方法 。

getOne  通常用于查询符合条件的单条记录。

getMap  根据wrapper条件,可以查询多条数据。

查询常用的拼接关系条件:

通常是写 wrapper里面的:

就比如 >, >=, < ,<= ,=   

  • gt:大于
  • ge:大于等于
  • lt:小于
  • le:小于等于
  • eq:等于

还有一些模糊查询用到的:

like 模糊查询类似于 like '%XXX%'

likeLeft 左边模糊查询 like '%XXX'

likeRight 右边模糊查询 类似于 like 'XXX%'

notLike   返回的模糊查询条件中,都不包含某条件。 no like '%XXX%'

notLikeLeft  返回的模糊查询条件中,左边不包含某条件。not like '%XXX'

notLikeRight 返回的模糊查询条件中,右边不包含某条件。not like 'XXX%'

查询条件的排序:

orderBy 根据什么字段排序,自己决定升序还是降序 

orderByAsc    根据条件成立的字段,升序

orderByDesc   根据条件成立的字段,降序

单个无条件查询:

代码:

    @Test@DisplayName("简单的测试")void testSimple() {//调用empservice的根据id查询的方法Emp emp = empSerevice.getById(1);//输出结果System.out.println(emp);}

查看结果: 

单个拼接条件查询:

代码:

    @Test@DisplayName("单个测试")void testGetOne(){//1,构造查询条件QueryWrapper wrapper = new QueryWrapper();wrapper.eq("id",1);//2,调用接口查询Emp emp = empSerevice.getOne(wrapper);//打印数据System.out.println(emp);}

 查看结果:

多条件拼接查询:
 

代码:

    @Test@DisplayName("多条件拼接查询")void testMoreQuery(){//1,创建查询条件QueryWrapper wrapper = new QueryWrapper();wrapper.ge("age",8);wrapper.like("name","张");//2,调用方法查询Map map = empSerevice.getMap(wrapper);//3,打印结果System.out.println(map);}

查询不包含某个条件返回多条数据:

 

代码:

    @Test@DisplayName("测试不包含条件的模糊查询")void testWrapper(){//1,创建查询条件QueryWrapper wrapper = new QueryWrapper();wrapper.notLike("name","张");  //结果中不能包含 张//2,调用service接口Map map = empSerevice.getMap(wrapper);//3,打印结果System.out.println(map);}

结果:

测试in包含的条件:

代码:

    @Test@DisplayName("测试in包含带的条件")void testExiste(){//1,创建查询条件QueryWrapper wrapper = new QueryWrapper();wrapper.in("id",1,2,3);//2,调用接口查询Map map = empSerevice.getMap(wrapper);//3,打印结果System.out.println(map);}

结果:

 

排序查询:

代码:

    @Test@DisplayName("测试")void test(){//1,创建查询条件QueryWrapper wrapper = new QueryWrapper();//第一个参数,条件是否成立,第二个参数,是否升序,第三个参数,排序字段wrapper.orderBy(true,false,"age");//2,调用接口查询Map map = empSerevice.getMap(wrapper);//3,打印结果System.out.println(map);}

结果:

 测试lamdba方式的查询:

为什么要使用lamdba的这中方式呢,因为这样就可以避免我们写死,要插叙条件的字段了。要是后面修改,实体类的属性,就能避免很多麻烦。

单个查询:

代码:

    @Test@DisplayName("单个查询")void getById(){//1,调用接口查询Emp emp = empSerevice.getById(3L);//2,打印结果System.out.println(emp);}

结果:

简单条件查询:

代码:

    @Test@DisplayName("lamdba的简单查询")void testLamdba(){//1,创建查询条件LambdaQueryWrapper<Emp> lambdaQuery = new LambdaQueryWrapper<>();lambdaQuery.eq(Emp::getId,1);//2,调用接口Emp emp = empSerevice.getOne(lambdaQuery);//3,打印结果System.out.println(emp);}

结果:

复杂条件查询(一): 

 

代码:

    @Test@DisplayName("复杂条件查询")void testMoreQuery(){//1,创建查询条件LambdaQueryWrapper<Emp> lambdaQuery = new LambdaQueryWrapper<>();//查询姓名包含张,年龄大于等于8,小于等于30lambdaQuery.like(Emp::getName,"张");lambdaQuery.ge(Emp::getAge,8);lambdaQuery.le(Emp::getAge,30);//2,调用接口Map<String, Object> map = empSerevice.getMap(lambdaQuery);//3,打印结果System.out.println(map);}

结果:

 

复杂查询(二)

代码:

    @Test@DisplayName("复杂条件查询")void testMoreQuery2(){//1,创建查询条件LambdaQueryWrapper<Emp> lambdaQuery = new LambdaQueryWrapper<>();//查询密码包含6并且,名字中包含j,年龄大于8岁,小于20岁lambdaQuery.like(Emp::getPassword,"6");lambdaQuery.like(Emp::getName,"j");lambdaQuery.ge(Emp::getAge,8);lambdaQuery.le(Emp::getAge,20);//2,,调用接口Map<String, Object> map = empSerevice.getMap(lambdaQuery);//3,打印结果System.out.println(map);}

结果:

 

测试删除:

mybatis-plus也给我们提供了很多的,删除的方法。

remove 根据条件删除

removeBatchByIds  批量删除 

removeById 根据id单个删除

测试单个删除:

代码:

    @Test@DisplayName("测试单个删除")void TestById(){//1,调用接口boolean b = empSerevice.removeById(1L);//打印结果if (b){System.out.println("删除成功");}}

结果:

根据条件删除:

代码:

    @Test@DisplayName("根据条件删除")void testByWrapper(){//1,创建条件LambdaQueryWrapper<Emp> lambdaWrapper = new LambdaQueryWrapper<>();//删除名字为单的员工lambdaWrapper.like(Emp::getName,"单");//2,调用接口boolean b = empSerevice.remove(lambdaWrapper);//3,打印结果if (b){System.out.println("删除成功");}}

结果:

 

 根据复杂条件批量删除:

代码:

    @Test@DisplayName("根据复杂条件批量删除")void TestByWrapperBatch(){//1,创建条件LambdaQueryWrapper<Emp> lambdaWrapper = new LambdaQueryWrapper<>();//删除年龄22岁,密码包含6,且名字中是姓张的lambdaWrapper.eq(Emp::getAge,22).like(Emp::getPassword,"6").like(Emp::getName,"张");//2,调用接口boolean b = empSerevice.remove(lambdaWrapper);//3,打印结果if (b){System.out.println("删除成功");}}

结果:

根据ID批量删除:

代码:

    @Test@DisplayName("根据id批量删除")void testBatchById(){//1,调用接口boolean b = empSerevice.removeBatchByIds(List.of(2L, 3L, 4L));//打印结果if (b){System.out.println("删除成功");}}

结果:

 测试新增(添加):

mubatis-plus也为我们提供了很多现成的,新增方法。

save  就是一个简单的新增方法

saveBatch   批量新增         

saveOrUpdate   存在就修改,不存在就新增

简单的新增:

代码:

    @Test@DisplayName("测试新增")void testAdd(){//1,创建实体类Emp emp = new Emp(null, "sde", "123456789", 18, "66666666666");//2,调用接口boolean b = empSerevice.save(emp);//3,返回结果if (b){System.out.println("新增成功");}}

 结果:

批量新增:
 

代码:

    @Test@DisplayName("批量添加")void testAddBatch(){//1,创建新增的实体集合List<Emp> empList = new ArrayList<Emp>();//2,创建多个实体对象Emp emp1 = new Emp(null, "sde1", "123456789", 18, "66666666666");Emp emp2 = new Emp(null, "sde2", "123456789", 18, "66666666666");Emp emp3 = new Emp(null, "sde3", "123456789", 18, "66666666666");Emp emp4 = new Emp(null, "sde4", "123456789", 18, "66666666666");//3,添加到集合中empList.add(emp1);empList.add(emp2);empList.add(emp3);empList.add(emp4);//4,调用接口boolean b = empSerevice.saveBatch(empList);//5,返回结果if (b){System.out.println("批量新增成功");}}

结果:

 新增或者修改:

代码:

    @Test@DisplayName("新增或者修改")void saveOrUpdate(){//1,创建实体Emp emp = new Emp(5L, "snake存在就修改", "123456789", 18, "66666666666");//2,调用接口boolean b = empSerevice.saveOrUpdate(emp);//3,返回结果if (b){System.out.println("新增或者修改成功");}}

结果:

我们看看数据库是修改还是新增了

很明显是新增了

测试修改:
 

mybatis-plus也给我们提供了很多修改的方法:

 updateById  根据id修改

update    根据条件修改,第一个参数是实体类,第二个参数是wrapper

根据ID修改:

代码:

    @Test@DisplayName("简单的修改")void testUpdate(){//1,创建要修改的实体类Emp emp = new Emp(7L, "张三", "123456", 20, "12345678901");//2,调用接口boolean b = empSerevice.updateById(emp);//3,打印结果if (b){System.out.println("修改成功");}}

结果:

 根据条件修改:

 代码:

    @Test@DisplayName("根据条件修改")void testByWrapper(){//1,创建修改的条件LambdaQueryWrapper<Emp> lambdaWrapper = new LambdaQueryWrapper<>();//修改名字为张三,iqe密码是123456的lambdaWrapper.eq(Emp::getPassword, "123456").eq(Emp::getName, "张三");//2,创建实体类Emp emp = new Emp(888L, "a张三", "123456", 20, "12345678901");//3,调用接口boolean b = empSerevice.update(emp, lambdaWrapper);//4,打印结果if (b){System.out.println("修改成功");}}

结果:

 注意不会修改·id

 修改或者新增:

代码:

    @Test@DisplayName("新增或者修改")void updateOrAdd(){//1,创建实体类Emp emp = new Emp(9L, "a张三", "54545454", 20, "12345678901");//2,调用接口boolean b = empSerevice.saveOrUpdate(emp);//3,打印结果if (b){System.out.println("修改成功");}}

结果:

五,测试mybatis-plus的mapper层接口:

测试查询:
单个查询:

代码:

    @Test@DisplayName("单个查询")void testSelect() {//1,创建查询条件LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Emp::getId, 7);//2,调用接口Emp emp = empMapper.selectOne(queryWrapper);//3,打印结果System.out.println(emp);}

结果:

 

批量查询:

代码:

    @Test@DisplayName("批量查询")void testSelectList(){//1,创建查询条件LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.in(Emp::getId, 6,7,8,9);//2,调用接口List<Emp> empList = empMapper.selectList(queryWrapper);//3,打印结果System.out.println(empList);}

 结果:

查询数据个数:
    @Test@DisplayName("简单查询")void testSimple() {//1,创建查询条件LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.like(Emp::getName, "张");//2,调用接口Long count = empMapper.selectCount(queryWrapper);//3,打印结果System.out.println(count);}

结果:

 

 测试删除:
单个删除:

代码:

    @Test@DisplayName("单个删除")void testById(){//1,调用接口int count = empMapper.deleteById(7L);//2,打印结果System.out.println(count);}

结果:

 

批量删除:
 

代码:

    @Test@DisplayName("批量删除")void testDelByIds(){//1,创建一个集合List<Integer> ids = List.of(6,7,8,9,10);//2,调用接口int count = empMapper.deleteBatchIds(ids);//3,打印结果System.out.println(count);}

结果:

 

 测试新增:
单个添加:

代码:

    @Test@DisplayName("测试新增")void testInsert(){//1,创建实体类Emp emp = new Emp(null, "六十的", "123456", 22, "1232321");//调用接口int count = empMapper.insert(emp);//输出结果System.out.println(count);}

结果:

 

测试修改:
 

代码:

    @Test@DisplayName("测试修改")void update(){//1,创建条件LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<Emp>();//名字中包含张的都修改queryWrapper.like(Emp::getName, "张");//2,创建实体类Emp emp = new Emp(null, "张三", "43434343434", 34, "1222222");//3,调用结果int count = empMapper.update(emp,queryWrapper);//4,输出返回值System.out.println(count);}

结果:

 根据id修改:

    @Test@DisplayName("修改")void testUpdate(){//1,创建实体类Emp emp = new Emp(5L, "大苏打", "1234567890", 18, "1234567890");//2,调用接口int count = empMapper.updateById(emp);//3,打印结果System.out.println(count);}

结果:

 

 六,常见注解:

@TableName注解:
  • 描述:表名注解,标识实体类对于的表

  • 使用位置:实体类类名上面

 示例:

@TableName("user")
public class User {private Long id;private String name;
}
 @TableId注解:
  • 描述:主键注解;用于标记实体类中的主键字段

  • 使用位置:实体类中属性之上

示例:

@TableName("user")
public class User {@TableIdprivate Long id;private String name;
}
 TableId注解有两个属性:
属性类型必须指定默认值描述
valueString""表名
typeEnumIdType.NONE指定主键类型
 IdType支持的类型:
描述
AUTO数据库 ID 自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert 前自行 set 主键值
ASSIGN_ID分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)
 比较常用的也就是下面这三个:
  • AUTO:利用数据库的id自增长

  • INPUT:手动生成id

  • ASSIGN_ID:雪花算法生成Long类型的全局唯一id,这是默认的ID策略

 测试IdType的AUTO:

emp实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {@TableId(value = "id", type = IdType.AUTO)  //利用数据库的id自增长private Long id; // 员工IDprivate String name; // 员工姓名private String password; // 密码private Integer age; // 年龄private String tel; // 电话号码}

看看数据库的数据:

 测试效果:

代码:

    @Test@DisplayName("TableId类型的测试")void testAddEmp(){//1,创建实体类Emp emp = new Emp(null, "测试TableId", "123456", 22, "1232321");//2,调用mapper接口int count = empMapper.insert(emp);//3,打印结果System.out.println(count);}

 数据库的变化:

id从7,到8了。

 测试IdType的INPUT:
 

实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {@TableId(value = "id", type = IdType.INPUT)  //自己设置主键idprivate Long id; // 员工IDprivate String name; // 员工姓名private String password; // 密码private Integer age; // 年龄private String tel; // 电话号码}

 测试:

代码:

    @Test@DisplayName("TableId类型的测试")void testAddEmp(){//1,创建实体类Emp emp = new Emp(10L, "测试TableId", "123456", 22, "1232321");//2,调用mapper接口int count = empMapper.insert(emp);//3,打印结果System.out.println(count);}

 看看数据库:

主键ID已经变成了我们自己输入的10

 测试IdType的ASSIGN_ID:

实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {@TableId(value = "id", type = IdType.ASSIGN_ID)  //基于雪花算法生成idprivate Long id; // 员工IDprivate String name; // 员工姓名private String password; // 密码private Integer age; // 年龄private String tel; // 电话号码}

 测试:

代码:

    @Test@DisplayName("TableId类型的测试")void testAddEmp(){//1,创建实体类Emp emp = new Emp(null, "测试TableId", "123456", 22, "1232321");//2,调用mapper接口int count = empMapper.insert(emp);//3,打印结果System.out.println(count);}

效果:

 七,常见配置:

mybatis-plus也支持基于yaml文件的自定义配置,详见官方文档:使用配置 | MyBatis-Plus 

大多数的配置都有默认值,因此我们都无需配置。但还有一些是没有默认值的,例如:

  • 实体类的别名扫描包

  • 全局id类型

mybatis-plus:type-aliases-package: com.sde.mp.domain.poglobal-config:db-config:id-type: auto # 全局id类型为自增长

需要注意的是,MyBatisPlus也支持手写SQL的,而mapper文件的读取地址可以自己配置:

mybatis-plus:mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,当前这个是默认值。

八,分页插件:

在未引入分页插件的情况下,MybatisPlus是不支持分页功能的,IServiceBaseMapper中的分页方法都无法正常起效。 所以,我们必须配置分页插件。

配置分页插件:

在我们的包下,新建一个config包,然后编写一个MybatisConfig的配置类

代码:

public class MybatisConfig {
}
 配置Mybatis-plus的分页拦截器:

代码:

//在类上添加这个注解
@Configuration
public class MybatisConfig {//配置Mybatisplus的分页拦截器@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}}
 测试分页:
简单测试:

在查询之间我们先看一下,我数据库的数据情况。

编写测试代码:

代码:

    @Test@DisplayName("测试简单的分页")void testPage(){//定义当前页码:int pageNum = 1;//定义每页显示的记录数:int pageSize = 2;//设置分页参数Page<Emp> page = new Page<>(pageNum, pageSize);//进行查询Page<Emp> empPage = empSerevice.page(page);//获取总记录数System.out.println("总记录数:" + empPage.getTotal());//获取页数System.out.println("总页数:" + empPage.getPages());//打印结果empPage.getRecords().forEach(System.out::println);}

结果:

 

简化写法:

代码:

    @Test@DisplayName("简化写法")void testPage2(){//分页查询Page<Emp> empPage = empSerevice.page(new Page<Emp>(2, 2));//获取总记录数System.out.println("总记录数:" + empPage.getTotal());//遍历出数据empPage.getRecords().forEach(System.out::println);}

结果:

自定义条件分页查询:
编写查询参数实体类:

empQueryDto类

代码:

@Data
public class EmpQueryDto {private String name; // 员工姓名private Integer age; // 年龄private String tel; // 电话号码private Integer pageNum;// 当前页码private Integer pageSize;// 每页显示条数
}
编写EmpController

条件分页查询的getEmpPage方法:

现在EmpService还没有写,empPage这个方法。报错先不用管

代码:

@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {@Autowiredprivate EmpSerevice empService;@GetMapping("/page")public Result getEmpPage(EmpQueryDto query){log.info("接收到的参数;"+query);Page<Emp> empPage = empService.empPage(query);return Result.success(empPage);}}
编写EmpService接口

 代码:

public interface EmpSerevice extends IService<Emp> {/*** 条件分页查询用户信息* @param query* @return*/Page<Emp> empPage(EmpQueryDto query);
}
EmpServiceImpl实现类:
 

代码:

@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpSerevice{@Autowiredprivate EmpMapper empMapper;/*** 条件分页查询用户信息* @param query* @return*/@Overridepublic Page<Emp> empPage(EmpQueryDto query) {return null;}
}
 实现ServiceImpl层的方法:

代码:

    @Overridepublic Page<Emp> empPage(EmpQueryDto query) {//1,设置分页参数Page<Emp> page = new Page<>(query.getPageNum(), query.getPageSize());//2,设置分页查询条件LambdaQueryWrapper<Emp> wrapper = new LambdaQueryWrapper<>();wrapper.like(query.getName() != null, Emp::getName, query.getName()).eq(query.getAge() != null, Emp::getAge, query.getAge()).eq(query.getTel() != null, Emp::getTel, query.getTel());//3,查询List<Emp> empList = empMapper.selectList(page, wrapper);//4,设置返回参数page.setRecords(empList);page.setTotal(empList.size());return page;}
 测试结果:

在ApiFox里面设置查询的参数

看看怎么执行的:

在ApiFox里面看看返回的数据:

{"code": 1,"msg": null,"data": {"records": [{"id": 8,"name": "测试TableId","password": "123456","age": 22,"tel": "1232321"},{"id": 10,"name": "测试TableId","password": "123456","age": 22,"tel": "1232321"},{"id": 1766100080533725186,"name": "测试TableId","password": "123456","age": 22,"tel": "1232321"}],"total": 3,"size": 10,"current": 1,"pages": 1}
}

 九,代码生成器:

在使用MybatisPlus以后,基础的MapperServicePO代码相对固定,重复编写也比较麻烦。因此MybatisPlus官方提供了代码生成器根据数据库表结构生成POMapperService等相关代码。

安装插件:

方式一:在Idea的plugins市场中搜索并安装MyBatisPlus插件(插件不太稳定,建议按照官网方式):

 点击Settings,找到plugins,搜索mybatisplus这个插件

然后重启Idea就可以了

方式二:上述的图形界面插件,存在不稳定因素;所以建议使用代码方式生成。官网安装说明。在项目中 pom.xml 添加依赖如下:

        <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.3.1</version><scope>test</scope></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.32</version><scope>test</scope></dependency>

使用:

使用图形界面方式的直接打开设置数据信息和填写其它界面中需要的内容即可。

在新版IDEA中;入口在 others这个里面: 

使用图形工具生成: 
 
设置连接数据库的配置信息:
 

点击测试连接:

可以看到 test successful连接成功了

 

使用介绍:

成功标志:

 目录结构

使用代码生成:

1,添加依赖:

2,写一个测试类,名字为MybatisPlusGenTest的类

代码:

public class MybatisPlusGenTest {}

 3,添加生成的配置信息:

代码:

 public static void main(String[] args) {String url = "jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true";FastAutoGenerator.create(url , "root", "root").globalConfig(builder -> {builder.author("sde") // 设置作者.enableSwagger() // 开启 swagger 模式.outputDir("D:\\cloud-java\\allcode2\\gen"); // 指定输出目录}).dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {int typeCode = metaInfo.getJdbcType().TYPE_CODE;if (typeCode == Types.SMALLINT) {// 自定义类型转换return DbColumnType.INTEGER;}return typeRegistry.getColumnType(metaInfo);})).packageConfig(builder -> {builder.parent("com.sdep") // 设置父包名.controller("controller").entity("domain.po") // 设置实体类包名.service("service") // 设置service包名.serviceImpl("service.impl") // 设置service实现类包名.mapper("mapper") // 设置mapper包名//.moduleName("address") // 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, "D:\\cloud-java\\allcode2\\gen\\mapper")); // 设置mapperXml生成路径}).strategyConfig(builder -> {builder.addInclude("address") // 设置需要生成的表名.addTablePrefix("t_", "c_") // 设置过滤表前缀.controllerBuilder().enableRestStyle() // 开启restful风格控制器.enableFileOverride() // 覆盖已生成文件.entityBuilder().enableLombok(); // 开启lombok模型,默认是false}).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板.execute();}

 将生成的实体、Mapper、Service、Controller等对应的类放置到项目中。即可

4,点击运行:

5,查看生成的目录:

 

完整版的代码生成器,代码:

public class MybatisPlusGeneratorTest {public static void main(String[] args) {String url = "jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true";FastAutoGenerator.create(url , "root", "root").globalConfig(builder -> {builder.author("JBL") // 设置作者.enableSwagger() // 开启 swagger 模式.outputDir("D:\\itcast\\generatedCode"); // 指定输出目录}).dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {int typeCode = metaInfo.getJdbcType().TYPE_CODE;if (typeCode == Types.SMALLINT) {// 自定义类型转换return DbColumnType.INTEGER;}return typeRegistry.getColumnType(metaInfo);})).packageConfig(builder -> {builder.parent("com.itheima.mp") // 设置父包名.controller("controller").entity("domain.po") // 设置实体类包名.service("service") // 设置service包名.serviceImpl("service.impl") // 设置service实现类包名.mapper("mapper") // 设置mapper包名//.moduleName("address") // 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, "D:\\itcast\\generatedCode\\mapper")); // 设置mapperXml生成路径}).strategyConfig(builder -> {builder.addInclude("address") // 设置需要生成的表名.addTablePrefix("t_", "c_") // 设置过滤表前缀.controllerBuilder().enableRestStyle() // 开启restful风格控制器.enableFileOverride() // 覆盖已生成文件.entityBuilder().enableLombok(); // 开启lombok模型,默认是false}).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板.execute();}
}

 十,静态工具类:

使用Db实现如下需求:

1、根据id查询用户;

2、查询名字中包含o且年龄大于8岁的;

3、更新用户名为tom的年龄为18

测试根据ID查询:
 

代码:

@SpringBootTest
public class DbTest {@Test@DisplayName("根据id查询用户")public void testById(){Emp emp = Db.getById(1L, Emp.class);System.out.println(emp);}
}

结果:

 

测试查询名字中包含j且年龄大于8岁的
 

代码:

    @Test@DisplayName("测试查询名字中包含j且年龄大于8岁的")void testWrapper(){//查询参数设置List<Emp> empList = Db.lambdaQuery(Emp.class).like(Emp::getName, "j").ge(Emp::getAge, 8).list();//遍历empList.forEach(emp -> System.out.println(emp));}

结果:

 

 更新用户名为tom的年龄为18

代码:

    @Test@DisplayName("更新用户名为tom的年龄为18")void testUpdate(){Db.lambdaUpdate(Emp.class).set(Emp::getAge, 18).eq(Emp::getName, "tom").update();}

结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/275209.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言:内存函数

目录 1.memcpy2.memmove3.memset4.memcmp5.atoi 1.memcpy void * memcpy ( void * destination, const void * source, size_t num ); 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置这个函数再遇到\0时不会停下来如果source和destination有…

哪个骨传导蓝牙耳机的好?独家揭秘六大选购技巧

在科技飞速前进的今天&#xff0c;骨传导蓝牙耳机以独特的听觉技术逐渐进入大众视野&#xff0c;赢得了众多消费者的青睐。作为一名资深的数码爱好者&#xff0c;我最近频繁地收到朋友们的咨询&#xff0c;他们希望了解哪个骨传导蓝牙耳机的好&#xff1f;对于初入数码圈的朋友…

zabbix 7.0编译部署教程

zabbix 7.0编译部署教程 2024-03-08 16:50乐维社区 zabbix7.0 alpha版本、beta版本已经陆续发布&#xff0c;Zabbix7.0 LTS版本发布时间也越来越近。据了解&#xff0c;新的版本在性能提升、架构优化等新功能方面有非常亮眼的表现&#xff0c;不少小伙伴对此也已经跃跃欲试。心…

ThreeJs 射线拾取不准确设置

欢迎关注进来点个关注; 关注获取更多咨询!关注获取答案! 1、效果图如下: 2、问题描述:点击一开始无法获取当前的位置,官方推荐直接使用 mouseClick.x = (event.offsetX / window.innderWidth) * 2 - 1; mouseClick.y = -(event.offsetY / window.innderHeight) * 2 + 1;…

promise,async →await,then→catch,try→catch 使用简介

提示&#xff1a;promise&#xff0c;async →await&#xff0c;then→catch&#xff0c;try→catch 使用简介 文章目录 前言一、Promise二、promise then/catch三、promise async/await try/catch总结 前言 需求&#xff1a;promise&#xff0c;async →await&#xff0c;then…

多数问题求解之蒙特卡洛与分治法

多数问题&#xff08;Majority Problem&#xff09;是一个有多种求解方法的经典问题&#xff0c;其问题定义如下&#xff1a; 给定一个大小为 n n n的数组&#xff0c;找出其中出现次数超过 n / 2 n/2 n/2的元素 例如&#xff1a;当输入数组为 [ 5 , 3 , 5 , 2 , 3 , 5 , 5 ] […

爬虫案例2:playwright 超爽体验

参考链接&#xff1a;https://playwright.bootcss.com/python/docs/intro 目标网站&#xff1a;https://spa6.scrape.center/通过观察&#xff0c;页面的信息是通过Ajax请求后返回的信息 下面使用playwright实现绕过token的获取直接拿到返回的数据import asyncio import json f…

邮件发送:行业会议邀请的高效新选择

随着数字化浪潮的不断深入&#xff0c;营销手段也在不断的创新和升级。因此&#xff0c;如何高效、精准地触达并吸引目标用户群体参与行业会议已成为众多会议举办方的核心关注点。在这一背景下&#xff0c;邮件推送服务凭借其独特的优势正逐渐成为行业会议邀请的新选择。 邮件推…

Linux本地搭建FastDFS系统

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…

初级爬虫实战——伯克利新闻

文章目录 发现宝藏一、 目标二、简单分析网页1. 寻找所有新闻2. 分析模块、版面和文章 三、爬取新闻1. 爬取模块2. 爬取版面3. 爬取文章 四、完整代码五、效果展示 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不…

挑战杯 基于深度学习的人脸表情识别

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的人脸表情识别 该项目较…

explain关键字的用法(mysql高级部分)

文章目录 简介explain关键字分析 简介 explain主要是用来分析sql语句的&#xff0c;当你的系统中出现慢查询SQL后&#xff0c;你可以使用explain关键字对该语句进行分析。通过使用explain&#xff0c;我们可以得到以下结果 表的读取顺序 哪些索引可能使用 哪些索引被实际使用…

48. 【Linux教程】yum 软件包管理

本小节介绍如何在 Linux 系统中使用 yum 命令软件管理。 1.yum 简介 yum 是 Red Hat 软件包管理器&#xff0c;它能够查询有关可用软件包的信息&#xff0c;从存储库获取软件包&#xff0c;安装和卸载软件包&#xff0c;以及将整个系统更新到最新的可用版本。yum 在更新&#…

netty草图笔记

学一遍根本记不住&#xff0c;那就再学一遍 public static void test_nettyFuture() {NioEventLoopGroup group new NioEventLoopGroup();log.info("开始提交任务");Future<String> future group.next().submit(() -> {log.info("执行异步任…

如何实现sam(Segment Anything Model)|fastsam模型

sam是2023年提出的一个在图像分割领域的大模型&#xff0c;其具备了对任意现实数据的分割能力&#xff0c;其论文的介绍可以参考 https://hpg123.blog.csdn.net/article/details/131137939&#xff0c;sam的亮点在于提出一种工作模式&#xff0c;同时将多形式的prompt集成到了语…

【漏洞复现】网康科技 NS-ASG 应用安全网关 SQL注入漏洞(CVE-2024-2330)

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

Spring学习 基础(三)MVC

5、Spring MVC 传统Web模式&#xff1a; Model:系统涉及的数据&#xff0c;也就是 dao 和 bean。View&#xff1a;展示模型中的数据&#xff0c;只是用来展示。Controller&#xff1a;处理用户请求都发送给 &#xff0c;返回数据给 JSP 并展示给用户。 随着 Spring 轻量级开发…

Python逆向:pyc字节码转py文件

一、 工具准备 反编译工具&#xff1a;pycdc.exe 十六进制编辑器&#xff1a;010editor 二、字节码文件转换 在CTF中&#xff0c;有时候会得到一串十六进制文件&#xff0c;通过010editor使用查看后&#xff0c;怀疑可能是python的字节码文件。 三、逆向反编译 将010editor得到…

【Redis】redis持久化

redis 持久化 Redis是内存数据库&#xff0c;数据都是存储在内存中&#xff0c;为了避免进程退出导致数据的永久丢失&#xff0c;需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘&#xff1b;当下次Redis重启时&#xff0c;利用持久化文件实现数据恢复。除此之…

前端性能优化 | CDN缓存

前言 CDN&#xff08;Content Delivery Network&#xff09;是一种分布式的网络架构&#xff0c;通过在全球各地部署节点服务器来快速传输和分发网络内容。CDN的主要目标是提供快速、可靠的内容传输&#xff0c;以提升用户体验。 本文主要从以下方面讲解CDN 什么是CDNCDN的作…