乐趣区

关于mybatis:MybatisPlus不支持联合主键复合主键怎么办试试MybatisTiny

Mybatis-Tiny 是什么

Mybatis-Tiny 是一个基于 Mybatis 框架的一层极简的扩大,它旨在应用 DSL 的形式对单表进行 CRUD 操作,相似于 Mybatis-Plus 框架,但它绝不是反复造轮子!区别于别的相似框架(如 Mybatis-Plus、Fluent-Mybatis 等)的实现形式,它采纳一种逆向曲线救国的实现形式,通过较少的代码,极简的扩大实现了相似于他们大多数的性能,齐全满足日常开发中对单表的各种 CRUD 操作。

我的项目地址:https://github.com/penggle/my…

联结主键应用案例

  • 引入并应用 Mybatis-Tiny

    (以下基于 SpringBoot 形式应用 Mybatis)

    • 引入依赖
      <dependency>
          <groupId>io.github.penggle</groupId>
          <artifactId>mybatis-tiny-core</artifactId>
          <!-- 版本阐明:3.5 指的是基于 Mybatis 3.5.x 版本的意思 -->
          <version>3.5</version>
      </dependency>
    • 相干配置

      引入相干 Maven 依赖后在 SpringBoot 启动类上应用注解 @EnableMybatisTiny 即可,例如:

      import com.penglecode.codeforce.mybatistiny.EnableMybatisTiny;
      import com.penglecode.codeforce.mybatistiny.examples.BasePackage;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      
      @EnableMybatisTiny
      @SpringBootApplication(scanBasePackageClasses=BasePackage.class)
      public class MybatisTinyExampleApplication {public static void main(String[] args) {SpringApplication.run(MybatisTinyExampleApplication.class, args);
          }
      
      }

      mybatis-spring-boot-starterDataSource 的配置依旧就好了,application.yml例如:

      #SpringBoot 利用的名称
      spring:
          application:
              name: mybatis-tiny-examples-springboot
          #Hikari 连接池配置
          datasource:
              hikari:
                  #连接池名字
                  pool-name: defaultHikariCP
                  #最小闲暇连贯数量
                  minimum-idle: 5
                  #闲暇连贯存活最大工夫,默认 600000(10 分钟)
                  idle-timeout: 180000
                  #连接池最大连接数,默认是 10
                  maximum-pool-size: 10
                  #池中连贯的默认主动提交行为,默认值 true
                  auto-commit: true
                  #池中连贯的最长生命周期,0 示意有限生命周期,默认 1800000(30 分钟)
                  max-lifetime: 1800000
                  #期待来自池的连贯的最大毫秒数,默认 30000(30 秒)
                  connection-timeout: 30000
                  #连贯测试语句
                  connection-test-query: SELECT 1
              username: root
              password: 123456
              url: jdbc:mysql://127.0.0.1:3306/examples?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false&rewriteBatchedStatements=true&useCursorFetch=true
      
      #Mybatis-SpringBoot 配置
      mybatis:
          config-location: classpath:config/mybatis/mybatis-config.xml
          mapper-locations: classpath*:com/penglecode/codeforce/mybatistiny/examples/**/*Mapper.xml
          type-aliases-package: com.penglecode.codeforce.mybatistiny.examples
          type-aliases-super-type: com.penglecode.codeforce.common.domain.DomainObject
  • 基于 Mybatis-Tiny 的联结主键应用案例

    • 基于注解的实体对象定义:
      package com.penglecode.samples.order.domain.model;
      
      import com.penglecode.codeforce.common.domain.EntityObject;
      import com.penglecode.codeforce.mybatistiny.annotations.GenerationType;
      import com.penglecode.codeforce.mybatistiny.annotations.Id;
      import com.penglecode.codeforce.mybatistiny.annotations.Table;
      import com.penglecode.samples.order.domain.enums.OrderStatusEnum;
      
      /**
       * 主订单信息
       */
      @Table("t_order")
      public class Order implements EntityObject {
      
          /** 订单 ID */
          @Id(strategy=GenerationType.NONE)
          private Long orderId;
      
          /** 客户 ID */
          private Long customerId;
      
          /** 总金额(单位分) */
          private Long totalAmount;
      
          /** 总运费(单位分) */
          private Long totalFreight;
      
          /** 商户 ID */
          private Long shopId;
      
          /** 下单工夫 */
          private String orderTime;
      
          /** 订单状态 */
          private OrderStatusEnum orderStatus;
      
          /** 订单备注 */
          private String remark;
      
          private String createTime;
      
          private String updateTime;
      
          //getter/setter 省略
      
          @Override
          public Long identity() {return orderId;}
      
      }
      package com.penglecode.samples.order.domain.model;
      
      import com.penglecode.codeforce.common.domain.EntityObject;
      import com.penglecode.codeforce.common.domain.ID;
      import com.penglecode.codeforce.mybatistiny.annotations.GenerationType;
      import com.penglecode.codeforce.mybatistiny.annotations.Id;
      import com.penglecode.codeforce.mybatistiny.annotations.Table;
      import com.penglecode.samples.order.domain.enums.OrderStatusEnum;
      
      /**
       * 订单明细
       */
      @Table("t_order_line")
      public class OrderLine implements EntityObject {
      
          /** 订单 ID */
          @Id(strategy= GenerationType.NONE)
          private Long orderId;
      
          /** 商品 ID */
          @Id(strategy=GenerationType.NONE)
          private Long productId;
      
          /** 商品名称 */
          private String productName;
      
          /** 商品详情页 URL */
          private String productUrl;
      
          /** 商品单价(单位分) */
          private Long unitPrice;
      
          /** 购买数量 */
          private Integer quantity;
      
          /** 运费 */
          private Long freight;
      
          /** 小计(单位分) */
          private Long subTotalAmount;
      
          /** 订单状态 */
          private OrderStatusEnum orderStatus;
      
          /** 下单工夫 */
          private String orderTime;
      
          private String createTime;
      
          private String updateTime;
      
          //getter/setter 省略
      
          @Override
          public ID identity() {
              // 联结主键
              return new ID().addKey("orderId", orderId).addKey("productId", productId);
          }
      
      }
      
      /**
       * 订单状态
       */
      public enum OrderStatusEnum {
      
          WAIT_PAY,
      
          PAIED,
      
          REFUND,
      
          CLOSED
      
      }
    • 实体 Mapper 接口定义:
      @Mapper
      public interface OrderMapper extends BaseEntityMapper<Order> {
      
      }
      
      @Mapper
      public interface OrderLineMapper extends BaseEntityMapper<OrderLine> {}
    • CRUD 应用示例:
      @SpringBootTest(classes=SamplesApplication.class)
      public class OrderMapperTest {
      
          @Autowired
          private OrderMapper orderMapper;
      
          @Autowired
          private OrderLineMapper orderLineMapper;
      
          @Autowired
          private DataSourceTransactionManager dataSourceTransactionManager;
      
          protected <T> void doInTransaction(Supplier<T> executor) {new TransactionTemplate(dataSourceTransactionManager).execute(status -> executor.get());
          }
      
          @Test
          public void createOrder() {doInTransaction(this::doCreateOrder);
          }
      
          protected Object doCreateOrder() {String nowTime = DateTimeUtils.formatNow();
              //Long orderId = System.currentTimeMillis();
              Long orderId = 1651560129068L;
      
              List<OrderLine> orderLines = new ArrayList<>();
              OrderLine orderLine1 = new OrderLine();
              orderLine1.setProductId(100026667880L);
              orderLine1.setProductName("Apple iPhone 13 (A2634) 128GB 午夜色 反对挪动联通电信 5G 双卡双待手机");
              orderLine1.setProductUrl("https://item.jd.com/100026667880.html");
              orderLine1.setUnitPrice(599900L);
              orderLine1.setQuantity(1);
              orderLine1.setFreight(0L);
              orderLines.add(orderLine1);
      
              OrderLine orderLine2 = new OrderLine();
              orderLine2.setProductId(100034710000L);
              orderLine2.setProductName("Apple iPad Air5 10.9 英寸平板电脑 2022 年款(64G WLAN 版 /M1 芯片 Liquid 视网膜屏 MME23CH/A) 紫色");
              orderLine2.setProductUrl("https://item.jd.com/100034710000.html");
              orderLine2.setUnitPrice(439900L);
              orderLine2.setQuantity(1);
              orderLine2.setFreight(0L);
              orderLines.add(orderLine2);
      
              Order order = new Order();
              order.setOrderId(orderId);
              order.setOrderTime(nowTime);
              order.setCustomerId(123L);
              order.setShopId(1000000127L);
              order.setTotalAmount(0L);
              order.setTotalFreight(0L);
              order.setOrderStatus(OrderStatusEnum.WAIT_PAY);
              order.setCreateTime(nowTime);
              order.setUpdateTime(nowTime);
      
              for(OrderLine orderLine : orderLines) {orderLine.setOrderId(orderId);
                  orderLine.setSubTotalAmount(orderLine.getUnitPrice() * orderLine.getQuantity());
                  order.setTotalFreight(order.getTotalFreight() + orderLine.getFreight());
                  order.setTotalAmount(order.getTotalAmount() + orderLine.getSubTotalAmount());
                  orderLine.setOrderStatus(order.getOrderStatus());
                  orderLine.setOrderTime(nowTime);
                  orderLine.setCreateTime(nowTime);
                  orderLine.setUpdateTime(nowTime);
              }
      
              //insert 主订单信息
              orderMapper.insert(order);
              // 批量 insert 订单明细
              orderLineMapper.batchUpdate(orderLines, orderLine -> orderLineMapper.insert(orderLine));
              return orderId;
          }
      
          @Test
          public void updateOrder() {doInTransaction(this::doUpdateOrder);
          }
      
          protected Object doUpdateOrder() {
              Long orderId = 1651560129068L;
              String nowTime = DateTimeUtils.formatNow();
              OrderStatusEnum targetOrderStatus = OrderStatusEnum.PAIED;
      
              Map<String,Object> orderUpdateColumns = MapLambdaBuilder.<Order>ofEmpty()
                      .withOverride(Order::getOrderStatus, targetOrderStatus)
                      .withOverride(Order::getRemark, "已付款,请发顺丰快递!")
                      .withOverride(Order::getUpdateTime, nowTime)
                      .build();
              orderMapper.updateById(orderId, orderUpdateColumns); // 更新主订单
      
              Map<String,Object> orderLineUpdateColums = MapLambdaBuilder.<OrderLine>ofEmpty()
                      .withOverride(OrderLine::getOrderStatus, targetOrderStatus)
                      .withOverride(OrderLine::getUpdateTime, nowTime)
                      .build();
              QueryCriteria<OrderLine> orderLineUpdateCriteria = LambdaQueryCriteria.ofSupplier(OrderLine::new)
                      .eq(OrderLine::getOrderId, orderId);
              orderLineMapper.updateByCriteria(orderLineUpdateCriteria, orderLineUpdateColums); // 更新子订单
              return orderId;
          }
      
          @Test
          public void getOrderById() {
              Long orderId = 1651560129068L;
              Order order = orderMapper.selectById(orderId); // 依据单个 ID 查问
              System.out.println(JsonUtils.object2Json(order));
      
              // 联结主键
              List<ID> orderLineIds = new ArrayList<>();
              orderLineIds.add(new ID().addKey(OrderLine::getOrderId, orderId).addKey(OrderLine::getProductId, 100026667880L));
              orderLineIds.add(new ID().addKey(OrderLine::getOrderId, orderId).addKey(OrderLine::getProductId, 100034710000L));
              List<OrderLine> orderLines = orderLineMapper.selectListByIds(orderLineIds); // 依据多个 ID 查问
              orderLines.forEach(orderLine -> System.out.println(JsonUtils.object2Json(orderLine)));
          }
      
      }

      打印 SQL:

      #createOrder()
      
       - ==>  Preparing: INSERT INTO t_order(order_id, customer_id, total_amount, total_freight, shop_id, order_time, order_status, remark, create_time, update_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
       - ==> Parameters: 1651560129068(Long), 123(Long), 1039800(Long), 0(Long), 1000000127(Long), 2022-05-03 17:29:30(String), WAIT_PAY(String), null, 2022-05-03 17:29:30(String), 2022-05-03 17:29:30(String)
       - <==    Updates: 1
       
       - ==>  Preparing: INSERT INTO t_order_line(order_id, product_id, product_name, product_url, unit_price, quantity, freight, sub_total_amount, order_status, order_time, create_time, update_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
       - ==> Parameters: 1651560129068(Long), 100026667880(Long), Apple iPhone 13 (A2634) 128GB 午夜色 反对挪动联通电信 5G 双卡双待手机(String), https://item.jd.com/100026667880.html(String), 599900(Long), 1(Integer), 0(Long), 599900(Long), WAIT_PAY(String), 2022-05-03 17:29:30(String), 2022-05-03 17:29:30(String), 2022-05-03 17:29:30(String)
       - ==> Parameters: 1651560129068(Long), 100034710000(Long), Apple iPad Air5 10.9 英寸平板电脑 2022 年款(64G WLAN 版 /M1 芯片 Liquid 视网膜屏 MME23CH/A) 紫色(String), https://item.jd.com/100034710000.html(String), 439900(Long), 1(Integer), 0(Long), 439900(Long), WAIT_PAY(String), 2022-05-03 17:29:30(String), 2022-05-03 17:29:30(String), 2022-05-03 17:29:30(String)
      
      
      #updateOrder()
      
       - ==>  Preparing: UPDATE t_order SET order_status = ?, remark = ?, update_time = ? WHERE order_id = ?
       - ==> Parameters: PAIED(String), 已付款,请发顺丰快递!(String), 2022-05-03 17:31:05(String), 1651560129068(Long)
       - <==    Updates: 1
       - ==>  Preparing: UPDATE t_order_line SET order_status = ?, update_time = ? WHERE order_id = ?
       - ==> Parameters: PAIED(String), 2022-05-03 17:31:05(String), 1651560129068(Long)
       - <==    Updates: 2
       
      #getOrderById()
      
       - ==>  Preparing: SELECT order_id AS orderId, customer_id AS customerId, total_amount AS totalAmount, total_freight AS totalFreight, shop_id AS shopId, order_time AS orderTime, order_status AS orderStatus, remark AS remark, create_time AS createTime, update_time AS updateTime FROM t_order WHERE order_id = ?
       - ==> Parameters: 1651560129068(Long)
       - <==      Total: 1
       - ==>  Preparing: SELECT order_id AS orderId, product_id AS productId, product_name AS productName, product_url AS productUrl, unit_price AS unitPrice, quantity AS quantity, freight AS freight, sub_total_amount AS subTotalAmount, order_status AS orderStatus, order_time AS orderTime, create_time AS createTime, update_time AS updateTime FROM t_order_line WHERE (order_id = ? AND product_id = ?) OR (order_id = ? AND product_id = ?)
       - ==> Parameters: 1651560129068(Long), 100026667880(Long), 1651560129068(Long), 100034710000(Long)
       - <==      Total: 2
  • 更多示例请见:https://github.com/penggle/my…
退出移动版