ShardingSphere应用专题--4.1.1版本--Sharding-JDBC环境搭建(四)

26 篇文章 3 订阅
18 篇文章 4 订阅
前言:

以下数据配置在后面讲的所有场景中不变,具体场景需要增加的配置,各场景均有介绍。你可以打开具体的场景文章,对着本文理解

文章链接:

专题文章涉及的所有用例均在github的项目中(其中sql在common-demo同级db文件下),点击地址下载,项目目录如下:

在这里插入图片描述
项目中配置了启动参数,点击选在具体的环境即可。注意:确认启动日志是否是你要的环境,防止误选环境启动报错
在这里插入图片描述

1.数据库

数据库:mysql
数据库版本:5.7
数据库特殊配置:需要两个mysql,并开启主从复制

如果想实操一遍,你可以选择:

  • 在自己本地执行sql脚本,自己搭建主从环境(比较费时费力)
  • 在自己本地执行sql脚本,不搭建主从环境(比较省力,但:是否走从库查询需要根据log确定,测试效果差)
  • (推荐)下载本文配套的mysql-master-slave-docker-docker-compose,环境及数据都在里面具体使用见下载链接
(1)数据库sql
CREATE DATABASE IF NOT EXISTS mydb;
CREATE DATABASE IF NOT EXISTS mydb0;
CREATE DATABASE IF NOT EXISTS mydb1;

DROP TABLE IF EXISTS `mydb`.`bill`;
CREATE TABLE `mydb`.`bill` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `bill_name` varchar(255) NOT NULL DEFAULT '' COMMENT '账单名称',
  `bill_amount` int unsigned NOT NULL DEFAULT '0' COMMENT '账单金额',
  `create_time` datetime(3) NOT NULL COMMENT '创建时间',
  `is_delete` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否删除 0:未删除 1:已删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


DROP TABLE IF EXISTS `mydb`.`bill_item`;
CREATE TABLE `mydb`.`bill_item` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `bill_id` bigint unsigned NOT NULL DEFAULT 0 COMMENT '账单id',
  `bill_item_name` varchar(255) NOT NULL DEFAULT '' COMMENT '子账单名称',
  `bill_item_amount` int unsigned NOT NULL DEFAULT '0' COMMENT '账单金额',
  `create_time` datetime(3) NOT NULL COMMENT '创建时间',
  `is_delete` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否删除 0:未删除 1:已删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
(2)数据库

在这里插入图片描述

2.SpringBoot代码环境:

以下代码在所有测试场景中不变。

(0)Entry
  • BillModel
package com.example.sharding.entry;
import java.io.Serializable;
import java.util.List;

import java.util.Date;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

@Data
@NoArgsConstructor
public class BillModel implements Serializable {

    /**
     * 主键
     */
    private Long id;

    /**
     * 账单名称
     */
    private String billName;

    /**
     * 账单金额
     */
    private Integer billAmount;

    /**
     * 创建时间
     */
    @JsonFormat(pattern="YYYY-MM-dd HH:mm")
    @DateTimeFormat(pattern="YYYY-MM-dd HH:mm")
    private Date createTime;

    /**
     * 是否删除 0:未删除 1:已删除
     */
    private Integer isDelete;
}
  • BillItemModel
package com.example.sharding.entry;

import java.util.Date;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

@Data
@NoArgsConstructor
public class BillItemModel {
    /**
    * 主键
    */
    private Long id;

    /**
    * 关联账单id
    */
    private Long billId;

    /**
    * 子账单名称
    */
    private String billItemName;

    /**
    * 账单金额
    */
    private Integer billItemAmount;

    /**
    * 创建时间
    */
    @JsonFormat(pattern="YYYY-MM-dd HH:mm")
    @DateTimeFormat(pattern="YYYY-MM-dd HH:mm")
    private Date createTime;

    /**
    * 是否删除 0:未删除 1:已删除
    */
    private Integer isDelete;
}
(1)Controller
package com.example.sharding.controller;

import com.example.sharding.entry.BillDTO;
import com.example.sharding.entry.BillItemModel;
import com.example.sharding.entry.BillModel;
import com.example.sharding.service.BillService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * auth:suyouliang
 */
@RestController
@RequestMapping("sharding/")
@Validated
public class ShardingTestController {
    @Autowired
    private BillService billService;

    //----------------------基础测试----------------------//

    @PostMapping("insertSelective")
    public int insertSelective(BillModel record) {
        return billService.insertSelective(record);
    }

    @PostMapping("batchInsert")
    public int batchInsert(@RequestBody List<BillModel> list) {
        return billService.batchInsert(list);
    }

    /**
     * 使用sharding分库分表时如果更新了分库分表字段:
     * Can not update sharding key, logic table: [bill],
     *
     * @param record
     * @return
     */
    @PostMapping("updateByPrimaryKeySelective")
    public int updateByPrimaryKeySelective(BillModel record) {
        return billService.updateByPrimaryKeySelective(record);
    }

    /**
     * 批量更新测试
     * <p>
     * 分库分表时不支持,底层使用了case when
     * 4.x.x不支持case when语法
     *
     * @param
     * @return
     */
    @PostMapping("updateBatchSelective")
    public int updateBatchSelective(@RequestBody List<BillModel> list) {
        return billService.updateBatchSelective(list);
    }

    /**
     * 删除测试
     *
     * @param id
     * @return
     */
    @PostMapping("deleteByPrimaryKey")
    public int deleteByPrimaryKey(Long id) {
        return billService.deleteByPrimaryKey(id);
    }

    /**
     * 查询测试
     *
     * @param id
     * @return
     */
    @GetMapping("selectByPrimaryKey")
    public BillModel selectByPrimaryKey(Long id) {
        return billService.selectByPrimaryKey(id);
    }


    /**
     * OR及range语句测试
     *
     * @return
     */
    @GetMapping("selectOfOrAndRange")
    public List<BillModel> selectOfOr() {
        return billService.selectOfOr();
    }

    /**
     * 手动分页测试
     *
     * @param billModel
     * @param pageNum
     * @param pageSize
     * @return
     */
    @GetMapping("selectPage")
    public PageInfo<BillModel> selectPage(BillModel billModel, @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "2") Integer pageSize) {
        return billService.selectPage(billModel, pageNum, pageSize);
    }

    /**
     * pageHelper分页测试
     *
     * @param billModel
     * @param pageNum
     * @param pageSize
     * @return
     */
    @GetMapping("selectPageByPageHelper")
    public PageInfo<BillModel> selectPageByPageHelper(BillModel billModel, @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "2") Integer pageSize) {
        return billService.selectPageByPageHelper(billModel, pageNum, pageSize);
    }

    /**
     * 简单聚合函数
     * 不可以同时使用普通聚合函数和DISTINCT聚合函数
     * 如:SELECT SUM(DISTINCT col1), SUM(col1) FROM tbl_name
     * 语句去除distinct可以成功
     *
     * @return
     */
    @GetMapping("selectOfSimpleSumFunction")
    public Map<String, Object> selectOfSimpleSumFunction() {
        return billService.selectOfSimpleSumFunction();
    }

    /**
     * 聚合函数及去重
     * 不可以同时使用普通聚合函数和DISTINCT聚合函数
     * 如:SELECT SUM(DISTINCT col1), SUM(col1) FROM tbl_name
     * 语句去除distinct可以成功
     *
     * @return
     */
    @GetMapping("selectOfSumFunction")
    public Map<String, Object> selectOfSumFunction() {
        return billService.selectOfSumFunction();
    }

    /**
     * 聚合排序无having
     * <p>
     * 不支持having,去除having可正常执行
     *
     * @return
     */
    @GetMapping("selectOfGroupBy")
    public Map<String, Object> selectOfGroupBy() {
        return billService.selectOfGroupBy();
    }

    /**
     * 聚合排序+having
     * <p>
     * 不支持having,去除having可正常执行
     *
     * @return
     */
    @GetMapping("selectOfGroupByHaving")
    public Map<String, Object> selectOfGroupByHaving() {
        return billService.selectOfGroupByHaving();
    }

    /**
     * UNION ALL
     * <p>
     * 分库分表时不支持UNION(ALL)
     *
     * @return
     */
    @GetMapping("selectOfUnionAll")
    public List<BillModel> selectOfUnionAll() {
        return billService.selectOfUnionAll();
    }

    /**
     * 跨库关联 join
     *
     * @return
     */
    @GetMapping("selectOfJoin")
    public List<Map<String, Object>> selectOfJoin() {
        return billService.selectOfJoin();
    }

    /**
     * insert on duplicate key update
     * 4.1.1版本有bug,报参数错误: No value specified for parameter 5
     * Actual SQL: master :::
     * <p>
     * insert into bill ( id,bill_name,bill_amount,create_time )
     * values
     * (?, ?, ?, ?)
     * on duplicate key update
     * id = ?, bill_name = ?, bill_amount = ?,create_time = ?
     * <p>
     * ::: [20, bill-insert-on-duplicate-key-6, 10000, 2020-12-27 13:13:00.0]
     * <p>
     * 解析后的sql
     * insert into bill ( id,bill_name,bill_amount,create_time )
     * values
     * ( ?, ?,?,? )
     * on duplicate key update
     * id = ?,bill_name = ?,bill_amount = ?,create_time = ?
     * <p>
     * <p>
     * 分表后:不可修改分库分表逻辑字段
     * <p>
     * 分库分表后(对应sharding-sub-db-tb):join对应的表(bill_item)没有做分库,由于[db0,db1]<->[bill_0,bill_1]有四种组合情况
     * ,而对应的bill_item会插到db0,还是db1是不固定的(随机的还是有算法暂不知道)
     * 导致如果bill进入了db0,很有可能bill_item进入db1,就会导致join的结果为空,但是不会报错
     * 但是分库分表的表A,join一个没有库分表的表B,是存在这种情况的,比如B为字典表,数据量固定,增量不大。
     * <p>
     * 这种情况下,可以让B在多个db中主从同步,从而方便A在各个DB join查询。
     *
     * @return
     */
    @PostMapping("insertOnDuplicateKeyUpdate")
    public int insertOnDuplicateKeyUpdate(BillModel record) {
        return billService.insertOnDuplicateKeyUpdate(record);
    }
    //----------------------基础测试----------------------//


    //----------------------基础其他测试----------------------//

    /**
     * 更新分库分表字段
     * <p>
     * 使用sharding分库分表时:Can not update sharding key, logic table: [bill],
     *
     * @return
     */
    @PostMapping("updateSubDbAndTbColumn")
    public int updateSubDbAndTbColumn(Long sourceId, Long changeId) {
        return billService.updateSubDbAndTbColumn(sourceId, changeId);
    }


    /**
     * 基础事务
     * 说明:直接在方法里制造异常是无法证明分布式事务的问题的,制造异常,本地代码直接报错,事务在本地不会提交
     * 真正测试应该是在代码运行过程正确,提交过程失败
     *
     * 让数据冲突(无法成功,mysql会拦住):
     * 设置bill或者billItem的id=A 此时A在数据库不存在
     * debug到最后一行,让数据库预处理通过,此时更改某个数据的id为A,放开debug
     * 事实上,修改的表在执行完insert语句等待提交时,数据库会给表上表级锁,你根本无法修改数据,表也无法删除。
     *
     * 可以使用两个不同mysql实例的两个表,debug到最后一行,让数据库预处理通过,停到其中一个mysql service,验证错误(其他的方法自行探究)
     * 由于现有的环境,使用的billItem表与bill在同一个mysql实例,暂时不做此测试
     *
     *
     *
     * 分库情况下,不同的两个库的两个表:一个提交成功,一个提交失败,数据提交成功,此时将不满足事务原子性(A):要么全部成功,要么全部失败
     *
     * 本来是用来做事务测试的,由于不好复现,现在这个方法用来添加billItem的数据
     *
     * //TODO 事务专题调研
     *
     * @return
     */
    @PostMapping("transaction")
    public int transactionTest(BillModel billModel, BillItemModel itemModel) {
        return billService.transactionTest(billModel, itemModel);
    }


    @GetMapping("selectBillItemById")
    public BillItemModel selectBillItemById(Long billItemId) {
        return billService.selectBillItemById(billItemId);
    }

    /**
     * 关键字
     * 使用sharding时:
     * 4.1.1版本有bug:no viable alternative at input 'text'
     *
     * @return
     */
    @GetMapping("keyword")
    public BillDTO transactionTest(Long id) {
        return billService.getIncludeKeyword(id);
    }

}

(2)Service
  • BillService
package com.example.sharding.service;

import com.example.sharding.dao.BillItemMapper;
import com.example.sharding.dao.BillMapper;
import com.example.sharding.entry.BillDTO;
import com.example.sharding.entry.BillItemModel;
import com.example.sharding.entry.BillModel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
public class BillService {

    @Autowired
    private BillMapper billMapper;
    @Autowired
    private BillItemMapper billItemMapper;


    public int insertSelective(BillModel record) {
        return billMapper.insertSelective(record);
    }

    public int deleteByPrimaryKey(Long id) {
        return billMapper.deleteByPrimaryKey(id);
    }


    public int updateByPrimaryKeySelective(BillModel record) {
        return billMapper.updateByPrimaryKeySelective(record);
    }

    public BillModel selectByPrimaryKey(Long id) {
        return billMapper.selectByPrimaryKey(id);
    }

    public int updateBatchSelective(List<BillModel> list) {
        return billMapper.updateBatchSelective(list);
    }

    public int batchInsert(List<BillModel> list) {
        return billMapper.batchInsert(list);
    }

    public PageInfo<BillModel> selectPage(BillModel billModel, Integer pageNum, Integer pageSize) {
        Long size = billMapper.countBySelective(billModel);
        List<BillModel> billModels = billMapper.selectPage(billModel, (pageNum - 1) * pageNum, pageSize);
        PageInfo<BillModel> pageInfo = new PageInfo<>(billModels);
        pageInfo.setTotal(size);
        return pageInfo;
    }

    public PageInfo<BillModel> selectPageByPageHelper(BillModel billModel, Integer pageNum, Integer pageSize) {
        return PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> billMapper.selectPageByPageHelper(billModel));
    }

    public Map<String, Object> selectOfSimpleSumFunction() {
        return billMapper.selectOfSimpleSumFunction();
    }

    public Map<String,Object> selectOfSumFunction() {
        return billMapper.selectOfSumFunction();
    }

    public Map<String, Object> selectOfGroupBy() {
        return billMapper.selectOfGroupBy();
    }

    public Map<String, Object> selectOfGroupByHaving() {
        return billMapper.selectOfGroupByHaving();
    }

    public List<BillModel> selectOfUnionAll() {
        return billMapper.selectOfUnionAll();
    }

    public List<Map<String, Object>> selectOfJoin() {
        return billMapper.selectOfJoin();

    }

    public int updateSubDbAndTbColumn(Long sourceId, Long changeId) {
        return billMapper.updateSubDbAndTbColumn(sourceId,changeId);
    }

    public int insertOnDuplicateKeyUpdate(BillModel record) {
        return billMapper.insertOrUpdateSelective(record);
    }
    @Transactional
    public int transactionTest(BillModel billModel, BillItemModel itemModel) {
        billMapper.insert(billModel);
        itemModel.setBillId(billModel.getId());
        billItemMapper.insertSelective(itemModel);

        return 1;
    }

    public BillDTO getIncludeKeyword(Long id) {
        return billMapper.getIncludeKeyword(id);
    }

    public BillItemModel selectBillItemById(Long billItemId) {
        return billItemMapper.selectByPrimaryKey(billItemId);
    }

    public List<BillModel> selectOfOr() {
        return billMapper.selectOfOr();
    }
}





  • BillItemService
package com.example.sharding.service;

import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import com.example.sharding.entry.BillItemModel;
import com.example.sharding.dao.BillItemMapper;
@Service
public class BillItemService{

    @Resource
    private BillItemMapper billItemMapper;

    
    public int insertSelective(BillItemModel record) {
        return billItemMapper.insertSelective(record);
    }

    
    public BillItemModel selectByPrimaryKey(Long id) {
        return billItemMapper.selectByPrimaryKey(id);
    }

    
    public int updateByPrimaryKeySelective(BillItemModel record) {
        return billItemMapper.updateByPrimaryKeySelective(record);
    }

}

(3)DAO
  • BillMapper
package com.example.sharding.dao;

import com.example.sharding.entry.BillDTO;
import com.example.sharding.entry.BillModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

@Mapper
public interface BillMapper {
    int deleteByPrimaryKey(Long id);

    int insert(BillModel record);

    int insertOrUpdate(BillModel record);

    int insertOrUpdateSelective(BillModel record);

    int insertSelective(BillModel record);

    BillModel selectByPrimaryKey(Long id);

    int updateByPrimaryKeySelective(BillModel record);

    int updateBatchSelective(List<BillModel> list);

    int batchInsert(@Param("list") List<BillModel> list);

    List<BillModel> selectPage(@Param("bill") BillModel bill, @Param("pageNum") Integer pageNum, @Param("pageSize") Integer pageSize);

    List<BillModel> selectPageByPageHelper(BillModel billModel);

    Long countBySelective(BillModel record);


    Map<String, Object> selectOfSumFunction();

    Map<String, Object> selectOfSimpleSumFunction();

    Map<String, Object> selectOfGroupBy();

    Map<String, Object> selectOfGroupByHaving();

    List<BillModel> selectOfUnionAll();

    List<Map<String, Object>> selectOfJoin();

    int updateSubDbAndTbColumn(@Param("sourceId") Long sourceId, @Param("changeId") Long changeId);

    BillDTO getIncludeKeyword(Long id);

    List<BillModel> selectOfOr();

}

}
  • BillItemMapper
package com.example.sharding.dao;

import com.example.sharding.entry.BillItemModel;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BillItemMapper {
    int insertSelective(BillItemModel record);

    BillItemModel selectByPrimaryKey(Long id);

    int updateByPrimaryKeySelective(BillItemModel record);

}
(4)Mapper.xml
  • BillMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.sharding.dao.BillMapper">
  <resultMap id="BaseResultMap" type="com.example.sharding.entry.BillModel">
    <!--@mbg.generated-->
    <!--@Table bill-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="bill_name" jdbcType="VARCHAR" property="billName" />
    <result column="bill_amount" jdbcType="INTEGER" property="billAmount" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="is_delete" jdbcType="TINYINT" property="isDelete" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, bill_name, bill_amount, create_time, is_delete
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select 
    <include refid="Base_Column_List" />
    from bill
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--@mbg.generated-->
    delete from bill
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.example.sharding.entry.BillModel" useGeneratedKeys="true">
    <!--@mbg.generated-->
    insert into bill (bill_name, bill_amount, create_time, 
      is_delete)
    values (#{billName,jdbcType=VARCHAR}, #{billAmount,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP}, 
      #{isDelete,jdbcType=TINYINT})
  </insert>
  <insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.example.sharding.entry.BillModel" useGeneratedKeys="true">
    <!--@mbg.generated-->
    insert into bill
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="billName != null and billName != ''">
        bill_name,
      </if>
      <if test="billAmount != null">
        bill_amount,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="isDelete != null">
        is_delete,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="billName != null and billName != ''">
        #{billName,jdbcType=VARCHAR},
      </if>
      <if test="billAmount != null">
        #{billAmount,jdbcType=INTEGER},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="isDelete != null">
        #{isDelete,jdbcType=TINYINT},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.example.sharding.entry.BillModel">
    <!--@mbg.generated-->
    update bill
    <set>
      <if test="billName != null and billName != ''">
        bill_name = #{billName,jdbcType=VARCHAR},
      </if>
      <if test="billAmount != null">
        bill_amount = #{billAmount,jdbcType=INTEGER},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="isDelete != null">
        is_delete = #{isDelete,jdbcType=TINYINT},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.example.sharding.entry.BillModel">
    <!--@mbg.generated-->
    update bill
    set bill_name = #{billName,jdbcType=VARCHAR},
      bill_amount = #{billAmount,jdbcType=INTEGER},
      create_time = #{createTime,jdbcType=TIMESTAMP},
      is_delete = #{isDelete,jdbcType=TINYINT}
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateBatchSelective" parameterType="java.util.List">
    <!--@mbg.generated-->
    update bill
    <trim prefix="set" suffixOverrides=",">
      <trim prefix="bill_name = case" suffix="end,">
        <foreach collection="list" index="index" item="item">
          <if test="item.billName != null">
            when id = #{item.id,jdbcType=BIGINT} then #{item.billName,jdbcType=VARCHAR}
          </if>
        </foreach>
      </trim>
      <trim prefix="bill_amount = case" suffix="end,">
        <foreach collection="list" index="index" item="item">
          <if test="item.billAmount != null">
            when id = #{item.id,jdbcType=BIGINT} then #{item.billAmount,jdbcType=INTEGER}
          </if>
        </foreach>
      </trim>
      <trim prefix="create_time = case" suffix="end,">
        <foreach collection="list" index="index" item="item">
          <if test="item.createTime != null">
            when id = #{item.id,jdbcType=BIGINT} then #{item.createTime,jdbcType=TIMESTAMP}
          </if>
        </foreach>
      </trim>
      <trim prefix="is_delete = case" suffix="end,">
        <foreach collection="list" index="index" item="item">
          <if test="item.isDelete != null">
            when id = #{item.id,jdbcType=BIGINT} then #{item.isDelete,jdbcType=TINYINT}
          </if>
        </foreach>
      </trim>
    </trim>
    where id in
    <foreach close=")" collection="list" item="item" open="(" separator=", ">
      #{item.id}
    </foreach>
  </update>
  <insert id="batchInsert" keyColumn="id" keyProperty="id" parameterType="map" useGeneratedKeys="true">
    <!--@mbg.generated-->
    insert into bill
    (bill_name, bill_amount, create_time, is_delete)
    values
    <foreach collection="list" item="item" separator=",">
      (#{item.billName,jdbcType=VARCHAR}, #{item.billAmount,jdbcType=INTEGER}, #{item.createTime,jdbcType=TIMESTAMP},
        #{item.isDelete,jdbcType=TINYINT})
    </foreach>
  </insert>
  <insert id="insertOrUpdate" keyColumn="id" keyProperty="id" parameterType="com.example.sharding.entry.BillModel" useGeneratedKeys="true">
    <!--@mbg.generated-->
    insert into bill
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      bill_name,
      bill_amount,
      create_time,
      is_delete,
    </trim>
    values
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      #{billName,jdbcType=VARCHAR},
      #{billAmount,jdbcType=INTEGER},
      #{createTime,jdbcType=TIMESTAMP},
      #{isDelete,jdbcType=TINYINT},
    </trim>
    on duplicate key update 
    <trim suffixOverrides=",">
      <if test="id != null">
        id = values(id),
      </if>
      bill_name = values(bill_name),
      bill_amount =values(bill_amount),
      create_time =values(create_time),
      is_delete = values(is_delete)},
    </trim>
  </insert>
  <insert id="insertOrUpdateSelective" keyColumn="id" keyProperty="id" parameterType="com.example.sharding.entry.BillModel" useGeneratedKeys="true">
    <!--@mbg.generated-->
    insert into bill
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="billName != null">
        bill_name,
      </if>
      <if test="billAmount != null">
        bill_amount,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="isDelete != null">
        is_delete,
      </if>
    </trim>
    values
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="billName != null">
        #{billName,jdbcType=VARCHAR},
      </if>
      <if test="billAmount != null">
        #{billAmount,jdbcType=INTEGER},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="isDelete != null">
        #{isDelete,jdbcType=TINYINT},
      </if>
    </trim>
    on duplicate key update 
    <trim suffixOverrides=",">
      <if test="id != null">
        id = #{id,jdbcType=BIGINT},
      </if>
      <if test="billName != null">
        bill_name = #{billName,jdbcType=VARCHAR},
      </if>
      <if test="billAmount != null">
        bill_amount = #{billAmount,jdbcType=INTEGER},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="isDelete != null">
        is_delete = #{isDelete,jdbcType=TINYINT},
      </if>
    </trim>
  </insert>

<!--auto generated by MybatisCodeHelper on 2021-02-22-->
  <select id="selectPage" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from bill
    <where>
      <if test="bill.id != null">
        and id=#{bill.id,jdbcType=BIGINT}
      </if>
      <if test="bill.billName != null and bill.billName != ''">
        and bill_name=#{bill.billName,jdbcType=VARCHAR}
      </if>
      <if test="bill.billAmount != null">
        and bill_amount=#{bill.billAmount,jdbcType=INTEGER}
      </if>
      <if test="bill.createTime != null">
        and create_time=#{bill.createTime,jdbcType=TIMESTAMP}
      </if>
      <if test="bill.isDelete != null">
        and is_delete=#{bill.isDelete,jdbcType=TINYINT}
      </if>
    </where>
    order by create_time
    LIMIT #{pageNum},#{pageSize}
  </select>

  <select id="selectPageByPageHelper" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from bill
    <where>
      <if test="id != null">
        and id=#{id,jdbcType=BIGINT}
      </if>
      <if test="billName != null and billName != ''">
        and bill_name=#{billName,jdbcType=VARCHAR}
      </if>
      <if test="billAmount != null">
        and bill_amount=#{billAmount,jdbcType=INTEGER}
      </if>
      <if test="createTime != null">
        and create_time=#{createTime,jdbcType=TIMESTAMP}
      </if>
      <if test="isDelete != null">
        and is_delete=#{isDelete,jdbcType=TINYINT}
      </if>
    </where>
    order by create_time
  </select>

<!--auto generated by MybatisCodeHelper on 2021-02-22-->
  <select id="countBySelective" resultType="java.lang.Long">
    select count(1)
    from bill
    <where>
      <if test="id != null">
        and id=#{id,jdbcType=BIGINT}
      </if>
      <if test="billName != null and billName != ''">
        and bill_name=#{billName,jdbcType=VARCHAR}
      </if>
      <if test="billAmount != null">
        and bill_amount=#{billAmount,jdbcType=INTEGER}
      </if>
      <if test="createTime != null">
        and create_time=#{createTime,jdbcType=TIMESTAMP}
      </if>
      <if test="isDelete != null">
        and is_delete=#{isDelete,jdbcType=TINYINT}
      </if>
    </where>
  </select>

  <select id="selectOfSumFunction" resultType="java.util.Map">
     select COUNT(1) as num,COUNT(distinct bill_amount) as amount_num, SUM(bill_amount) as amountTotal, MIN(bill_amount) as amountMin, MAX(bill_amount) as amountMax, AVG(bill_amount) as amountAvg
    from bill
  </select>

  <select id="selectOfGroupBy" resultType="java.util.Map">
       select COUNT(1),sum(bill_amount)  from bill group by is_delete
  </select>

  <select id="selectOfGroupByHaving" resultType="java.util.Map">
    select COUNT(1),sum(bill_amount)  from bill group by is_delete having sum(bill_amount)>200
  </select>

  <select id="selectOfUnionAll" resultMap="BaseResultMap">
      select
      <include refid="Base_Column_List"/>
      from bill
      where id>10
      union all
      select
      <include refid="Base_Column_List"/>
      from bill
      where id &lt; 5
  </select>

  <select id="selectOfJoin" resultType="java.util.Map">
      select
      *
      from bill_item as bi
        join  bill as b
      on b.id=bi.bill_id
      where b.is_delete=0
  </select>
    <update id="updateSubDbAndTbColumn" >
        update bill set bill_amount=bill_amount+250,id=#{changeId} where id=#{sourceId}
    </update>

  <select id="getIncludeKeyword" resultType="com.example.sharding.entry.BillDTO">
    select
    id, bill_name as text, bill_amount as billAmount, create_time as createTime, is_delete as isDelete
    from bill
    where id = #{id,jdbcType=BIGINT}
  </select>

  <select id="selectOfSimpleSumFunction" resultType="java.util.Map">
    select COUNT(1) as num,COUNT(bill_amount) as amount_num, SUM(bill_amount) as amountTotal, MIN(bill_amount) as amountMin, MAX(bill_amount) as amountMax, AVG(bill_amount) as amountAvg
    from bill
  </select>

  <select id="selectOfOr" resultMap="BaseResultMap">
    select *
    from bill where id &lt; 30 or bill_amount &gt; 40
  </select>


</mapper>
  • BillItemMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.sharding.dao.BillItemMapper">
  <resultMap id="BaseResultMap" type="com.example.sharding.entry.BillItemModel">
    <!--@mbg.generated-->
    <!--@Table bill_item-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="bill_id" jdbcType="BIGINT" property="billId" />
    <result column="bill_item_name" jdbcType="VARCHAR" property="billItemName" />
    <result column="bill_item_amount" jdbcType="INTEGER" property="billItemAmount" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="is_delete" jdbcType="TINYINT" property="isDelete" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, bill_id, bill_item_name, bill_item_amount, create_time, is_delete
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select 
    <include refid="Base_Column_List" />
    from bill_item
    where id = #{id,jdbcType=BIGINT}
  </select>
  <insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.example.sharding.entry.BillItemModel" useGeneratedKeys="true">
    <!--@mbg.generated-->
    insert into bill_item
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="billId != null">
        bill_id,
      </if>
      <if test="billItemName != null and billItemName != ''">
        bill_item_name,
      </if>
      <if test="billItemAmount != null">
        bill_item_amount,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="isDelete != null">
        is_delete,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="billId != null">
        #{billId,jdbcType=BIGINT},
      </if>
      <if test="billItemName != null and billItemName != ''">
        #{billItemName,jdbcType=VARCHAR},
      </if>
      <if test="billItemAmount != null">
        #{billItemAmount,jdbcType=INTEGER},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="isDelete != null">
        #{isDelete,jdbcType=TINYINT},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.example.sharding.entry.BillItemModel">
    <!--@mbg.generated-->
    update bill_item
    <set>
      <if test="billId != null">
        bill_id = #{billId,jdbcType=BIGINT},
      </if>
      <if test="billItemName != null and billItemName != ''">
        bill_item_name = #{billItemName,jdbcType=VARCHAR},
      </if>
      <if test="billItemAmount != null">
        bill_item_amount = #{billItemAmount,jdbcType=INTEGER},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="isDelete != null">
        is_delete = #{isDelete,jdbcType=TINYINT},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
(5)pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.syl.learn</groupId>
    <artifactId>sharding-sphere</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sharding-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <nacos-version>1.4.1</nacos-version>
        <sharding-version>4.1.1</sharding-version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>

        <!--mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.googlecode.aviator</groupId>
            <artifactId>aviator</artifactId>
            <version>5.1.4</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>${nacos-version}</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.10</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <!-- 原生ORM环境 -->
            <id>原生ORM环境</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <profileActive>common</profileActive>
            </properties>
        </profile>
        <profile>
            <!-- sharding 读写分离环境 -->
            <id>读写分离</id>
            <properties>
                <profileActive>sharding-rw</profileActive>
            </properties>
        </profile>
        <profile>
            <!-- sharding 分表环境 -->
            <id>分表</id>
            <properties>
                <profileActive>sharding-sub-tb</profileActive>
            </properties>
        </profile>
        <profile>
            <!-- sharding 分表读写分离环境 -->
            <id>分表+读写分离</id>
            <properties>
                <profileActive>sharding-sub-tb-rw</profileActive>
            </properties>
        </profile>
        <profile>
            <!-- sharding 分库分表环境 -->
            <id>分库分表</id>
            <properties>
                <profileActive>sharding-sub-db-tb</profileActive>
            </properties>
        </profile>
        <profile>
            <!-- sharding 分库分表读写分离环境 -->
            <id>分库分表+读写分离</id>
            <properties>
                <profileActive>sharding-sub-db-tb-rw</profileActive>
            </properties>
        </profile>
        <!--########################专项配置##############################-->
        <profile>
            <!-- special 数据加密 -->
            <id>数据加密</id>
            <properties>
                <profileActive>sp-encrypt</profileActive>
            </properties>
        </profile>
        <profile>
            <!-- special 分布式主键 -->
            <id>分布式主键</id>
            <properties>
                <profileActive>sp-key-generator</profileActive>
            </properties>
        </profile>
        <profile>
            <!-- special 分布式治理 -->
            <id>分布式治理</id>
            <properties>
                <profileActive>sp-distributed</profileActive>
            </properties>
        </profile>
    </profiles>


    <build>
        <filters> <!-- 指定使用的filter文件,根据profile设置过滤文件 -->
            <filter>src/main/filters/${profileActive}.properties</filter>
        </filters>
        <!--开启资源过滤:将resources中配置文件的变量利用profile进行替换-->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <!--允许进行资源过滤-->
            </resource>
            <resource>
                <directory>src/main/bin</directory>
                <!--允许进行资源过滤-->
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>utf-8</encoding>
                    <useDefaultDelimiters>true</useDefaultDelimiters>
                </configuration>
            </plugin>
        </plugins>
        <finalName>${project.artifactId}</finalName>
    </build>


</project>

(6)application.properties
spring.profiles.active=${profileActive}

mybatis.mapper-locations=classpath:mapper/*Mapper.xml
mybatis.type-aliases-package=com.example.sharding.entry

#pagehelper
pagehelper.helperDialect=mysql
pagehelper.params=count=countSql

#showSql
logging.level.com.example.mapper=info

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=111
spring.datasource.url=jdbc:mysql://127.0.0.1:4406/mydb?useUnicode=true&character_set_server=utf8mb4&autoReconnect=true&useSSL=false&verifyServerCertificate=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=CONVERT_TO_NULL
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5

#log相关配置
logging.level.root=info
server.compression.enabled=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值