SpringBoot集成MybatisPlus

依赖

    <properties>
        <mybatis.plus.version>3.4.0</mybatis.plus.version>
    </properties>
	
    <dependencies>
	
        <!--mybatis-plus下面这两个依赖必须加-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis.plus.version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
		
        <!--mybatis-plus以下依赖是拓展,比如分页插件-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-extension</artifactId>
            <version>${mybatis.plus.version}</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-annotation</artifactId>
            <version>${mybatis.plus.version}</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-core</artifactId>
            <version>${mybatis.plus.version}</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>${mybatis.plus.version}</version>
        </dependency>
		
        <!--单元测试依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
        
    </dependencies>

SpringBoot的数据表配置:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#注意mysql的版本,如果是8.0及以上,要使用以下驱动,并修改pom文件的Mysql版本。
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://mysql的ip:端口/库名?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useTimezone=true
spring.datasource.username=xxx
spring.datasource.password=xxx

mybatisPlus 打印sql日志:

# mybatis-plus配置控制台打印完整带参数SQL语句
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

创建数据表:

CREATE TABLE tb_order_test
(
    id          INT         NOT NULL AUTO_INCREMENT COMMENT '主键,自增id',
    order_id    VARCHAR(25) NOT NULL UNIQUE COMMENT '订单号,唯一',
    pay_status  INT UNSIGNED DEFAULT 0 COMMENT '10:未支付,20:支付成功,30:支付失败, 40:已下单,50:申请退款,60:退款成功,70:退款失败 ',
    user_id     BIGINT(20)  NOT NULL COMMENT '用户id',
    total_price DECIMAL(25, 2)   DEFAULT 0.00 COMMENT '交易金额',
    result      TEXT COMMENT '结果',
    order_desc  VARCHAR(128)     DEFAULT '' COMMENT '订单描述',
    order_date  DATE             DEFAULT NULL COMMENT '订单日期',
    create_time DATETIME         DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间,默认当前时间',
    update_time DATETIME         DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间,更新时默认当前时间',
    is_delete   TINYINT(1)       DEFAULT 0 COMMENT '是否删除,0表示否,1表示是',
    PRIMARY KEY (id),
    INDEX idx_order (order_id)
) ENGINE = INNODB
  DEFAULT CHARSET = utf8
  AUTO_INCREMENT = 1 COMMENT ='示例表';

实体类

  • 注解 @TableName(),指定数据表名称。

  • 注解 @TableId指定主键。
    @TableId(type = IdType.AUTO) : 表示自增id。
    @TableId(type = IdType.ID_WORKER) :ID_WORKER生成19位数字,对应类型Long
    @TableId(type = IdType.ID_WORKER_STR) :ID_WORKER_STR 生成19位值字符串
    @TableId(type = IdType.INPUT) INPUT:设置id
    @TableId(type = IdType.UUID) UUID:随机唯一值
    @TableId(type = IdType.NONE) NONE:自动输入

  • fill属性可以表示插入或更新。
    @TableField(fill = FieldFill.INSERT):插入填充字段。
    @TableField(fill = FieldFill.UPDATE): 更新填充字段。
    @TableField(fill = FieldFill.INSERT_UPDATE):插入和更新填充字段。

@TableName("tb_order_test")
public class Order {
	//此处忽略 getter、setter、构造方法,自行添加
	
    @TableId(type = IdType.AUTO)
    private Integer id;

    private String orderId;

    private Integer payStatus;

    private Long userId;

    private BigDecimal totalPrice;

    private String orderDesc;

    private Date orderDate;

	@TableField(fill = FieldFill.INSERT)
    private Date createTime;
	
	@TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

    private Boolean isDelete;

    private String result;

}

扫描Mapper文件夹:

在spring boot启动类中添加@MapperScan注解,扫描Mapper接口的文件夹。

@SpringBootApplication(scanBasePackages = {"com.example.demo"})
@MapperScan(basePackages = { "com.example.demo.dao" })
public class demoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

Mapper接口:

  • Mapper接口,继承 BaseMapper
  • mybatisPlus,不需要配置xml文件。
public interface OrderMapper extends BaseMapper<Order> {

}

增删改查(不是很好用,更优的做法见后面的Service层)

  • 普通的增删改查:
    原生的不是很好用,代码如下。更好的增删改查,详情见后面的Service层讲解。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class MybatisPlusTest {

    @Autowired
    private OrderMapper orderMapper;

    @Test
    public void selectAll() {
        List<Order> orderList = orderMapper.selectList(null);
        System.out.println(orderList);
    }

    @Test
    public void selectById() {
        Order order = orderMapper.selectById(123456);
        System.out.println(order);
    }


    @Test
    public void insert() {
        Order order = new Order();
        order.setOrderId("sdfdfegegergb");
        order.setTotalPrice(new BigDecimal("99.3"));
        order.setUserId(789012L);

        orderMapper.insert(order);
        System.out.println(order);
    }

    @Test
    public void updateById() {
        Order order = new Order();
        order.setId(1);
        order.setOrderDesc("update");
        orderMapper.updateById(order);
    }

    @Test
    public void delete() {
        orderMapper.deleteById(1L);
    }

}

条件查询

QueryWrapper条件查询:

eq:等于
ne:不等于
gt:大于 
ge:大于等于
lt:小于
le:小于等于
between and:区间查询
like:模糊查询
notLike:模糊查询
likeLeft:左模糊
likeRight: 右模糊
in:范围查询
orderByDesc:降序
orderByAsc: 升序

代码示例如下 :

    /**
     * SELECT id,order_id,pay_status,user_id,total_price,order_desc,order_date,create_time,update_time,is_delete,result
     * FROM
     *   tb_order_test
     * WHERE
     *   user_id = 789012
     * ORDER BY
     *   create_time DESC
     *
     */
    public void selectByWrapper() {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<Order> wrapper = queryWrapper.lambda();
        //等于
        wrapper.eq(Order::getUserId, 789012L);
        wrapper.orderByDesc(Order::getCreateTime);
        List<Order> orderList = orderMapper.selectList(queryWrapper);
        System.out.println(orderList);
    }

    /**
     * 以下代码,相当于sql:
     * SELECT id,order_id,pay_status,user_id,total_price,order_desc,order_date,create_time,update_time,is_delete,result
     * FROM
     *   tb_order_test
     * WHERE
     *   user_id >= 10000
     *   AND pay_status IN (1, 2, 3)
     *   AND total_price BETWEEN 1.0 AND 1000.0
     * ORDER BY
     *   create_time ASC
     */
    public void selectWrapper() {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<Order> wrapper = queryWrapper.lambda();
        //大于等于
        wrapper.ge(Order::getUserId, 10000);
        wrapper.in(Order::getPayStatus, 1, 2, 3);
        wrapper.between(Order::getTotalPrice, 1.0, 1000.0);
        wrapper.orderByAsc(Order::getCreateTime);
        List<Order> orderList = orderMapper.selectList(queryWrapper);
        System.out.println(orderList);
    }

  • 动态查询:

在查询条件,比如 wrapper.ge(Order::getUserId, 10000); 前面可以加一些判断条件,满足条件时,才会进行查询。
比如 wrapper.ge(paramNum==123, Order::getUserId, 10000); 表示当传入的动态参数 paramNum为 123时,才拼接此查询条件。

    public void selectConditionTest() {
        int paramNum = 100;
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        //动态sql,第一个参数是条件,条件成立才会执行
        wrapper.ge(paramNum==123, Order::getUserId, 10000);

        List<Order> orderList = orderMapper.selectList(wrapper);
        System.out.println(orderList);
    }
  • 只查一条数据:

调用MybatisPlus的getOne和selectOne方法。如果存在多条结果,会报错如下:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: 
Expected one result (or null) to be returned by selectOne(), but found:

解决方法:
在查询语句后面,加上 .last(“LIMIT 1”)

如下:

    public void selectOne() {
        LambdaQueryWrapper<Order> lambdaQueryWrapper =new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(Order::getPayStatus, 1, 2, 3);
        //加上 LIMIT 1
        lambdaQueryWrapper.last("LIMIT 1");

        Order orderList = orderService.getOne(lambdaQueryWrapper);
        System.out.println("orderList:"+orderList);
    }

分页常用的方法:

Page.java :

    /**
     * 分页构造函数
     *
     * @param current 当前页
     * @param size    每页显示条数
     */
    public Page(long current, long size) {
        this(current, size, 0);
    }
   
   /**
     * 查询数据列表
     */
   @Override
    public List<T> getRecords() {
        return this.records;
    }
    
    /**
     * 数据的总数
     */
    @Override
    public long getTotal() {
        return this.total;
    }
    
    /**
     * 每页显示条数,默认 10
     */
    @Override
    public long getSize() {
        return this.size;
    }
    
    /**
     * 当前页
     */
    @Override
    public long getCurrent() {
        return this.current;
    }
    
    /**
     * 当前分页总页数
     */
    default long getPages() {
        if (getSize() == 0) {
            return 0L;
        }
        long pages = getTotal() / getSize();
        if (getTotal() % getSize() != 0) {
            pages++;
        }
        return pages;
    }

BaseMapper 查询分页结果:selectPage 第一个参数是分页page,第二个参数是查询条件

<E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);

分页的示例

    @Test
    public void page() {
        //Page第一个参数current表示第几页,从1开始。size表示每页多少条。
        Page<Order> pageQuery = new Page<>(1,10);
        //selectPage 第一个参数是分页page,第二个参数是查询条件
        Page<Order> page = orderMapper.selectPage(pageQuery, null);
        //分页返回的数据
        List<Order> records = page.getRecords();
        //数据的总数
        long total = page.getTotal();
        //每页数量
        long size = page.getSize();
        //当前页
        long current = page.getCurrent();
        //总页数
        long pages = page.getPages();

        System.out.println("分页返回的数据:"+records);
        System.out.println("数据的总数:"+ total);
        System.out.println("每页数量:"+size);
        System.out.println("当前页:"+ current);
        System.out.println("总页数:"+ pages);

    }

Service层,更常用的增删改查

pom.xml文件中,添加了 mybatis-plus-extension 依赖后。

可以继承 ServiceImpl,直接使用ServiceImpl和 IService 已有的方法。

条件查询:list()
分页:page()
查询一条数据:getOne()。原生的selectOne()如果查到多条数据会报错,可以用getOne()代替,查到多条不报错。
根据id查询:getById()
插入:save()
更新:update(T entity, Wrapper updateWrapper)。第一个参数是要更新的字段,第二个参数是查询条件。
插入或更新:saveOrUpdate()等方法。
批量保存:saveBatch()
根据id批量更新:updateBatchById()

@Service
public class OrderServiceImpl
        extends ServiceImpl<OrderMapper, Order>
        implements OrderService {


    @Override
    public List<Order> getList() {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getOrderId, "12345");
        //直接复用 IService 已有的方法list()
        List<Order> list = list(queryWrapper);
        return list;
    }

    @Override
    public Page<Order> getPageList() {
        Page<Order> pageQuery = new Page<>(1,10);
        //直接复用 IService 已有的方法page()
        Page<Order> page = page(pageQuery, null);

        return page;
    }

    /**
     * boolean update(T entity, Wrapper<T> updateWrapper) 返回的是boolean 类型。
     * 如果需要返回 int 类型,可以继承ServiceImpl<Mapper接口, 数据表对应的Entity类>,然后用 baseMapper.update(T entity, Wrapper<T> updateWrapper)
     * 
     */
    public boolean updateByQuery() {
        //要修改的字段
        Order updateOrder = new Order();
        updateOrder.setOrderDesc("upadteDesc123");

        //查询条件
        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Order::getUserId, "12345");
        return update(updateOrder, wrapper);
    }
}

分页查询,并将数据表的entity 对象转换成 展示层的vo数据 :

mybatisPlus分页查询后,并把查询得到的数据表的entity 对象转换成 展示层的vo 数据,如下

public Page<MyVo> list(Integer pageNo, Integer pageSize) {
	if (pageNo == null) {
    	pageNo = 1;
     }
     if (pageSize == null) {
     	pageSize = 10;
     }
    Page<MyEntity> pageQuery = new Page<>(pageNo,pageSize);
    LambdaQueryWrapper<MyEntity> queryWrapper = new LambdaQueryWrapper<>();
    //补充查询条件,此处忽略
    IPage<MyEntity> page = page(pageQuery, queryWrapper);
    List<MyEntity> records = page.getRecords();
    //遍历list,将entity转换为 vo, changeEntityToVo是转换的方法
    List<MyVo> voList = Optional.ofNullable(records).orElse(new ArrayList<>())
    		.stream().map(this::changeEntityToVo).collect(Collectors.toList());

    return new Page<MyVo>(page.getCurrent(), page.getSize(), page.getTotal())
  				.setRecords(voList);

}

public MyVo changeEntityToVo(MyEntity myEntity) {
	MyVo myVo = new MyVo();
	BeanUtils.copyProperties(myEntity, myVo);
	//其他的set,此处忽略
	return myVo;
}

MybatisPlus 报错:

  • 报错如下:
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: 
Could not set property 'id' of '' with value '' 
Cause: java.lang.IllegalArgumentException: argument type mismatch

解决方法:

字段上面加上注解 @TableId(type = IdType.AUTO)

参考资料:

https://blog.csdn.net/m0_46313726/article/details/124187527

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值