sharding-jdbc 4 + pagehelper + group by 分表异常

当使用PageHelper和Sharding-JDBC时,遇到带有GroupBy的SQL语句无法正确路由到分表的情况。PageHelper默认将SQL改写为先进行count操作,但不适用于包含聚合函数和GroupBy的复杂查询。文中介绍了这个问题的具体表现,并提出了通过自定义count语句ID来解决这个问题的方法,即为原始查询添加 '_COUNT' 后缀,以确保分表的正确路由。
摘要由CSDN通过智能技术生成

分表 + pagehelper + group by 语句的问题

PageHelper为了算总记录条数,会改写原始sql,做1次count,比如:

select order_id, order_name, order_date from t_order_logic_0 where order_date='2020-09-06';

会首先被改写为:

select count(0) from t_order_logic_0 where order_date='2020-09-06';

然后再由sharding-jdbc改写成:(精确路由)

select count(0) from t_order_0 where order_date='2020-09-06';

对于简单语句,这样没什么问题。但是如果原始语句上,有一些聚合函数或group by,比如下面这样:

在这里插入图片描述
 如上图,加了group by 后,下面的语句

SELECT count(0) FROM (SELECT order_id FROM t_order_logic WHERE order_date = ? GROUP BY order_id) table_count

sharding-jdbc并不能正确解析为t_order_0,仍然还是t_order_logic

SELECT count(0) FROM (SELECT order_id FROM t_order_logic WHERE order_date = ? GROUP BY order_id) table_count ::: [2020-09-06]

解决办法:pagehelper对于count语句,允许用户自定义,只要在原来的语句id,加上“_COUNT”

在这里插入图片描述

<select id="selectList2" resultMap="BaseResultMap">
select order_id from t_order_logic${tableIndex} where order_date=#{orderDate} group by order_id
</select>

<select id="selectList2_COUNT" resultType="long">
select count(1) from t_order_logic${tableIndex} where order_date=#{orderDate} group by order_id
</select>

在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
在使用Sharding-JDBC 5.2和Spring Boot时,配置XA事务需要进行以下步骤: 1. 首先需要在pom.xml文件中添加XA事务依赖: ```xml <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-transaction-xa-core</artifactId> <version>${sharding-jdbc-version}</version> </dependency> ``` 其中,`${sharding-jdbc-version}`是Sharding-JDBC的版本号。 2. 在Spring Boot的配置文件(application.yml或application.properties)中添加以下配置: ```yaml spring: shardingsphere: datasource: names: master, slave master: url: jdbc:mysql://localhost:3306/db_master?useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver slave: url: jdbc:mysql://localhost:3306/db_slave?useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver sharding: default-data-source-name: master tables: order: actual-data-nodes: master.order, slave.order database-strategy: inline: sharding-column: user_id algorithm-expression: db${user_id % 2} table-strategy: inline: sharding-column: order_id algorithm-expression: order_${order_id % 2} key-generator: column: order_id type: SNOWFLAKE binding-tables: - order transaction: type: XA ``` 其中,`transaction.type`配置为`XA`表示启用XA事务。 3. 配置数据源为XA数据源。 在Spring Boot的配置类中,可以使用如下代码创建XA数据源: ```java @Bean public DataSource dataSource() throws SQLException { AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource"); xaDataSource.setUniqueResourceName("dataSource"); Properties properties = new Properties(); properties.put("user", "root"); properties.put("password", "root"); properties.put("URL", "jdbc:mysql://localhost:3306/db_master?useSSL=false"); xaDataSource.setXaProperties(properties); return xaDataSource; } ``` 在上面的代码中,我们使用了AtomikosDataSourceBean来创建XA数据源,同时配置了数据库的用户名、密码和连接URL。 4. 使用XA事务进行数据库操作。 在需要使用XA事务的地方,可以使用如下代码: ```java @Autowired private TransactionTemplate transactionTemplate; public void doTransaction() { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { // 进行数据库操作 } }); } ``` 在上面的代码中,我们通过注入`TransactionTemplate`对象来执行数据库操作,并使用`TransactionCallbackWithoutResult`回调函数来指定具体的操作。在回调函数中,我们可以通过`TransactionStatus`对象来控制事务的提交和回滚。 总之,以上就是使用Sharding-JDBC 5.2和Spring Boot进行XA事务配置的步骤。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值