Offer to come, dig friends take it! I am participating in the 2022 Spring Recruit Punch card activity. Click here for details.
Introduction to the
ShardingSphere is an ecosystem of open source distributed database middleware solutions, which is composed of three independent products, Sharding-JDBC, Sharding-Proxy and Sharding-Sidecar (planned). They all provide standardized data sharding, distributed transaction and database governance functions, which can be applied to diverse application scenarios such as Java isomorphism, heterogeneous languages, cloud native and so on.
ShardingSphere is positioned as relational database middleware, aiming at fully and reasonably utilizing the computing and storage capabilities of relational databases in distributed scenarios, rather than realizing a brand new relational database. It coexists with NoSQL and NewSQL rather than being mutually exclusive. NoSQL and NewSQL are highly recommended as being at the forefront of new technology exploration, looking to the future and embracing change. Conversely, you can look at things in a different way, looking to the future, focusing on what doesn’t change, and then grasping the essence of things. Relational databases still occupy a huge market today, and are the cornerstone of each company’s core business, and will be difficult to shake in the future. At present, we are more focused on incremental, rather than subversive, on the original foundation.
ShardingSphere has graduated from the Apache Incubator as an Apache Top-level project on April 16, 2020.
Quick start
Create a table
The important thing to note here is that the field does not have a keyword subclass, as long as possible.
create database `cloud-order`;
use `cloud-order`;
create database if not exists `cloud-order` default charset utf8mb4 collate utf8mb4_general_ci;
create table t_order_1 (
`oid` bigint(20) unsigned not null auto_increment comment 'primary key id',
`order_code` varchar(64) not null default ' ' comment 'Order Number'.primary key (`oid`),
key `idx_order_code` (`order_code`)
) comment 'Order sheet';
create table t_order_2 (
`oid` bigint(20) unsigned not null auto_increment comment 'primary key id',
`order_code` varchar(64) not null default ' ' comment 'Order Number'.primary key (`oid`),
key `idx_order_code` (`order_code`)
)comment 'Order sheet';
Copy the code
Add the dependent
Let me tell you the basic information of the project:
- Spring boot 2.6.5
- Spring cloud 2021.0.1
- Mybatis – spring – the boot – starter 2.2.2
- Sharding – JDBC – spring – the boot – starter 4.4.1
At present, it is a relatively new version, so there will be a lot of pits. The specific configuration is as follows (since my configuration is modified in the previous project, it is not concise enough for everyone to see) :
plugins {
id 'java'
id 'org.springframework.boot' version '2.6.5'
id 'io.spring.dependency-management' version '1.0.11. RELEASE'
}
group 'io.zhengsh'
version = '0.0.1 - the SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenLocal()
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral()
}
ext {
set('springCloudVersion'."2021.0.1")
}
configurations {
compile.exclude module: 'spring-boot-starter-tomcat'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-undertow'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j'
// mysql
implementation 'mysql:mysql-connector-java'
// mybatis
implementation 'org. Mybatis. Spring. The boot: mybatis - spring - the boot - starter: 2.2.2'
// shardingsphere
implementation 'org. Apache. Shardingsphere: sharding - JDBC - spring - the boot - starter: 4.4.1'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
compileOnly 'org. Projectlombok: lombok: 1.18.22'
annotationProcessor 'org. Projectlombok: lombok: 1.18.22'
testCompileOnly 'org. Projectlombok: lombok: 1.18.22'
testAnnotationProcessor 'org. Projectlombok: lombok: 1.18.22'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
Copy the code
Add the YML configuration
Add the YML configuration, mainly with the following configuration
- By setting up the data source, you configure which libraries are available
- Set up the table, the table that participates in sharding
- To set the strategy of sub-table, I used the snowflake algorithm to generate ID and specify the data location by taking the mode of module.
spring:
shardingsphere:
# set data source
datasource:
names: o1
o1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: JDBC: mysql: / / 127.0.0.1:3306 / cloud - the order? useUnicode=true&zeroDateTimeBehavior=convertToNull&useSSL=false
username: root
password: root123
props:
# print SQL
sql.show: true
sharding:
default-data-source-name: o1
tables:
t_order:
# specify the table to be divided
# expression, actual data node: find this value based on the previous node, {0.. 1} for Groovy, $will be replaced with {0.. 1}, the database tables are t_order_1, t_order_2
This configuration tells Sharding how many tables there are
actual-data-nodes: o1.t_order_$->{1.. 2}
key-generator:
# specify primary key
column: oid
# Generation method: Snowflake algorithm
type: snowflake
props:
worker:
id: 1
# table splitting strategy
table-strategy:
inline:
# configure sharding's computed column
sharding-column: oid
Sharding column = sharding column = sharding column = sharding column = sharding column = sharding column
algorithm-expression: t_order_$->{oid % 2 + 1}
Copy the code
Java code
1. Entity classes
public class OrderEntity {
private Long oid;
private String orderCode;
// omit the get and set methods here
}
Copy the code
Mapper file
@Mapper
public interface OrderEntityMapper {
@Insert("insert into o1.t_order (`order_code`) values(#{orderCode})")
@Options(useGeneratedKeys = true, keyProperty = "oid", keyColumn = "oid")
int insertSelective(OrderEntity record);
@Select("select * from o1.t_order where oid = #{oid}")
OrderEntity selectOne(@Param("oid") Long oid);
}
Copy the code
Unit testing
@Test
public void insertOrder(a) {
for (int i = 0; i < 10; i++) {
OrderEntity order = new OrderEntity();
order.setOrderCode("OR000" + i);
int row = orderEntityMapper.insertSelective(order);
Assert.assertTrue(row > 0); }}@Test
public void selectOne(a) {
OrderEntity order1 = orderEntityMapper.selectOne(
715721929377452033L);
Assert.assertNotNull(order1);
}
Copy the code
The execution result
1. Insert data
2. Query results
Q&A
Health check error
The core is yML configuration. I met a problem before that the health check failed, so I couldn’t configure it, so I used Java Config to avoid this startup error
Add the Java Config configuration as follows:
@Configuration
public class DataSourceConfig {
@Bean
public HealthIndicator dbHealthIndicator(DataSource dataSource) {
DataSourceHealthIndicator indicator = new DataSourceHealthIndicator(dataSource);
indicator.setQuery("select 1");
returnindicator; }}Copy the code
Null pointer exception
A null pointer was reported in MyBatis. Mysql > select * from table where id = 1;
### Cause: java.lang.NullPointerException
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)...75 common frames omitted
Caused by: java.lang.NullPointerException: null
at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18)
at org.apache.shardingsphere.sql.parser.mysql.visitor.impl.MySQLDMLVisitor.createProjection(MySQLDMLVisitor.java:446)
// omit some exceptions
Copy the code
At first I thought it was the reason for the table, but later I checked the information on the Internet and found that there were keywords in the table. When viewing exception information, the top prompt is ignored:
line 1:176 mismatched input 'order' expecting {..... Ignore some keywords}Copy the code
Invoke Method mod() on null Object exception
Cannot invoke method mod() on null object] with root cause
### SQL: insert into o1.t_order (`order_code`, `code`) values(?, ?)
### Cause: java.lang.NullPointerException: Cannot invoke method mod(a) on null object
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)
at com.sun.proxy.$Proxy112.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272)
// omit some exceptions
Copy the code
Cause: The sharding key is inconsistent with the fields in the sharding policy