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.mzph.cn/news/733723.shtml

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

相关文章

Qt 实现诈金花的牌面值分析工具

诈金花是很多男人最爱的卡牌游戏 , 每当你拿到三张牌的时候, 生活重新充满了期待和鸟语花香. 那么我们如果判断手中的牌在所有可能出现的牌中占据的百分比位置呢. 这是最终效果: 这是更多的结果: 在此做些简单的说明: 炸弹(有些地方叫豹子) > 同花顺 > 同花 > 顺…

Day27:安全开发-PHP应用TP框架路由访问对象操作内置过滤绕过核心漏洞

目录 TP框架-开发-配置架构&路由&MVC模型 TP框架-安全-不安全写法&版本过滤绕过 思维导图 PHP知识点 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0c;资源下载&#xff0c;留言版&#xff0c;后台模块&#xff0c;模版引用&#xff0c;框架开发等 技…

安卓提示风险解决源码搭建教程

一&#xff0e;环境 1.安装Nginx 2.安装Tomcat8.5 3. 安装Mysql5.7 二&#xff0e;修改app已生成的文件下载地址 1.打开编辑config.properties 2.填写你的ip&#xff0c;端口不用修改 三&#xff0e;启动教程 启动命令&#xff1a;sh.start.sh 源码下载链接:https://p…

ArrayDeque集合源码分析

ArrayDeque集合源码分析 文章目录 ArrayDeque集合源码分析一、字段分析二、构造函数分析方法、方法分析四、总结 实现了 Deque&#xff0c;说面该数据结构一定是个双端队列&#xff0c;我们知道 LinkedList 也是双端队列&#xff0c;并且是用双向链表 存储结构的。而 ArrayDequ…

哪些狗粮比较适合幼年犬?

亲爱的朋友&#x1f44b;&#xff0c;你为家中的幼年犬挑选狗粮可真是个贴心的主人呢&#xff01;选择适合幼年犬的狗粮&#xff0c;确实是个需要仔细考虑的问题。幼年犬处于生长发育的关键期&#xff0c;所以狗粮的营养成分和口感都非常重要。 &#x1f436; 在选择狗粮时&…

排序算法全景:从基础到高级的Java实现

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

CentOS系统上安装Redis操作教程

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

Pulsar 社区周报 | No.2024.03.08 Pulsar-Spark Connector 助力实时计算

关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目&#xff0c;是下一代云原生分布式消息流平台&#xff0c;集消息、存储、轻量化函数式计算为一体&#xff0c;采用计算与存储分离架构设计&#xff0c;支持多租户、持久化存储、多机房跨区域数据复制&#xff0c…

每日一练:LeeCode-209、长度最小的子数组【滑动窗口+双指针】

每日一练&#xff1a;LeeCode-209、长度最小的子数组【滑动窗口双指针】 思路暴⼒解法滑动窗口 本文是力扣 每日一练&#xff1a;LeeCode-209、长度最小的子数组【滑动窗口双指针】 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐 L…

基于php的用户登录实现(v2版)(持续迭代)

目录 版本说明 数据库连接 登录页面&#xff1a;login.html 登录处理实现&#xff1a;login.php 用户欢迎页面&#xff1a;welcome.php 密码修改页面&#xff1a;change_password.html 修改执行&#xff1a;change_password.php 用户注册页面&#xff1a;register.html …

远程连接Linux系统

图形化、命令行 对于操作系统的使用&#xff0c;有2种使用形式&#xff1a; 图形化页面使用操作系统 图形化&#xff1a;使用操作系统提供的图形化页面&#xff0c;以获得图形化反馈的形式去使用操作系统。 以命令的形式使用操作系统 命令行&#xff1a;使用操作系统提供的各…

React-路由导航

1.声明式路由导航 1.1概念 说明&#xff1a;声明式导航是指通过在模版中通过<Link/>组件描述出要跳转到哪里去&#xff0c;比如后台管理系统的左侧菜单通常使用这种方式进行。 import {Link} from "react-router-dom" const Login()>{return (<div>…

物联网云原生云边协同

文章目录 一、物联网平台设计1.物联网平台设计2.物联网平台实现 二、部署环境1.节点配置2.版本信息 三、物联网平台部署1.部署 Kubernetes 集群2.部署 KubeEdge3.部署 ThingsBoard 集群4.部署 ThingsBoard Edge4.1.创建 Edge 实例4.2.部署 PostgreSQL4.3.创建数据库4.4.部署 Th…

在Blender中清理由Instant-NGP等几何学习技术生成的网格

使用布尔运算: 创建一个大的立方体或其他简单几何体包裹住全部网格。使用布尔修改器对两个网格进行“差集”运算。这将移除超出包裹体之外的多余网格部分。 手动选择并删除: 进入编辑模式&#xff08;按Tab键&#xff09;。按A键取消选择所有顶点。按B键并拖动以选择您想要删除…

11. 搭建较通用的GoWeb开发脚手架

文章目录 导言一、加载配置二、初始化日志三、初始化MySQL连接四、初始化Redis连接五、初始化gin框架内置的校验器使用的翻译器六、注册路由七、 启动服务八、测试运行九&#xff1a;注意事项 代码地址&#xff1a;https://gitee.com/lymgoforIT/bluebell 导言 有了前述知识的…

最简单的基于 FFmpeg 的内存读写的例子:内存转码器

最简单的基于 FFmpeg 的内存读写的例子&#xff1a;内存转码器 最简单的基于 FFmpeg 的内存读写的例子&#xff1a;内存转码器正文源程序结果工程文件下载参考链接 最简单的基于 FFmpeg 的内存读写的例子&#xff1a;内存转码器 参考雷霄骅博士的文章&#xff0c;链接&#xf…

Chrome中如何导出和导入书签

导出书签 如下图所示&#xff1a; 右上角三点->书签和清单->书签管理器->右上角三点->导出书签 然后你选择保存地址即可。打开后如下&#xff1a; 导入书签 如下图所示&#xff1a; 右上角三点->书签和清单->导入书签和设置->选择以前导出的书签&…

【Node.js】-闲聊:前端框架发展史

前端框架的发展史是一个不断演进和创新的过程&#xff0c;旨在提高开发效率、优化用户体验&#xff0c;并推动前端技术的不断发展。以下是前端框架发展的主要阶段和关键里程碑&#xff1a; 早期阶段&#xff1a; 在这个阶段&#xff0c;前端主要由HTML、CSS和JavaScript等基础技…

LLM Drift(漂移), Prompt Drift Cascading(级联)

原文地址&#xff1a;LLM Drift, Prompt Drift & Cascading 提示链接可以手动或自动执行&#xff1b;手动需要通过 GUI 链构建工具手工制作链。自治代理在执行时利用可用的工具动态创建链。这两种方法都容易受到级联、LLM 和即时漂移的影响。 2024 年 2 月 23 日 在讨论大型…

什么是自动化测试?什么情况下使用?

什么是自动化测试? 自动化测试是指把以人为驱动的测试行为转化为机器执行的过程。实际上自动化测试往往通过一些测试工具或框架&#xff0c;编写自动化测试脚本&#xff0c;来模拟手工测试过程。比如说&#xff0c;在项目迭代过程中&#xff0c;持续的回归测试是一项非常枯燥…