【快速使用ShardingJDBC的哈希分片策略进行分表】

news2024/12/25 9:11:08

文章目录

  • 🔊博主介绍
  • 🥤本文内容
    • 🍊1.引入maven依赖
    • 🍊2.启动类上添加注解@MapperScan
    • 🍊3.添加application.properties配置
    • 🍊4.普通的自定义实体类
    • 🍊5.写个测试类验证一下
    • 🍊6.控制台打印的日志
    • 🍊7.观察一下数据库的数据
    • 🍊8.maven的setting文件
    • 🍊9.视频演示
  • 📢文章总结
  • 📥博主目标

🔊博主介绍

🌟我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文专业写手、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。🌎跑过十五公里、🚀徒步爬过衡山、🔥有过三个月减肥20斤的经历、是个喜欢躺平的狠人。

📕拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、Spring MVC、SpringCould、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RockerMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。

📙有过从0到1的项目高并发项目开发与管理经验,对JVM调优、MySQL调优、Redis调优 、ElasticSearch调优、消息中间件调优、系统架构调优都有着比较全面的实战经验。

📘有过云端搭建服务器环境,自动化部署CI/CD,弹性伸缩扩容服务器(最高200台),了解过秒级部署(阿里云的ACK和华为云的云容器引擎CCE)流程,能独立开发和部署整个后端服务,有过分库分表的实战经验。

🎥经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧,与清华大学出版社签下了四本书籍的合约,并将陆续在明年出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码–沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋能够多多支持!


文章目录

  • 🔊博主介绍
  • 🥤本文内容
    • 🍊1.引入maven依赖
    • 🍊2.启动类上添加注解@MapperScan
    • 🍊3.添加application.properties配置
    • 🍊4.普通的自定义实体类
    • 🍊5.写个测试类验证一下
    • 🍊6.控制台打印的日志
    • 🍊7.观察一下数据库的数据
    • 🍊8.maven的setting文件
    • 🍊9.视频演示
  • 📢文章总结
  • 📥博主目标

🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。

💡在这个美好的时刻,本人不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

🥤本文内容

CSDN

🍊1.引入maven依赖

在pom.xml中添加依赖

<!-- Maven 构建配置 -->
<build>
    <!-- 插件列表 -->
    <plugins>
        <!-- Maven 编译插件 -->
        <plugin>
            <!-- 插件所在 groupId -->
            <groupId>org.apache.maven.plugins</groupId>
            <!-- 插件所在 artifactId -->
            <artifactId>maven-compiler-plugin</artifactId>
            <!-- 插件配置 -->
            <configuration>
                <!-- 源码编译版本 -->
                <source>8</source>
                <!-- 目标编译版本 -->
                <target>8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

<!-- Maven 依赖管理配置 -->
<dependencyManagement>
    <!-- 依赖列表 -->
    <dependencies>
        <!-- Spring Boot 依赖管理 -->
        <dependency>
            <!-- 依赖所在 groupId -->
            <groupId>org.springframework.boot</groupId>
            <!-- 依赖所在 artifactId -->
            <artifactId>spring-boot-dependencies</artifactId>
            <!-- 依赖版本 -->
            <version>2.3.1.RELEASE</version>
            <!-- 依赖类型 -->
            <type>pom</type>
            <!-- 依赖范围 -->
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<!-- 项目依赖列表 -->
<dependencies>
    <!-- 分库分表组件 Sharding JDBC -->
    <dependency>
        <!-- 依赖所在 groupId -->
        <groupId>org.apache.shardingsphere</groupId>
        <!-- 依赖所在 artifactId -->
        <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
        <!-- 依赖版本 -->
        <version>4.1.1</version>
    </dependency>
    <!-- Spring Boot 核心依赖 -->
    <dependency>
        <!-- 依赖所在 groupId -->
        <groupId>org.springframework.boot</groupId>
        <!-- 依赖所在 artifactId -->
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!-- Spring Boot 测试依赖 -->
    <dependency>
        <!-- 依赖所在 groupId -->
        <groupId>org.springframework.boot</groupId>
        <!-- 依赖所在 artifactId -->
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <!-- 数据源连接池组件 Druid -->
    <dependency>
        <!-- 依赖所在 groupId -->
        <groupId>com.alibaba</groupId>
        <!-- 依赖所在 artifactId -->
        <artifactId>druid</artifactId>
        <!-- 依赖版本 -->
        <version>1.1.22</version>
    </dependency>
    <!-- MySQL 驱动依赖 -->
    <dependency>
        <!-- 依赖所在 groupId -->
        <groupId>mysql</groupId>
        <!-- 依赖所在 artifactId -->
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- MyBatis-Plus 集成依赖 -->
    <dependency>
        <!-- 依赖所在 groupId -->
        <groupId>com.baomidou</groupId>
        <!-- 依赖所在 artifactId -->
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <!-- 依赖版本 -->
        <version>3.0.5</version>
    </dependency>
</dependencies>

🍊2.启动类上添加注解@MapperScan

扫描对应的mapper路径

@MapperScan("com.example.shardingDemo.mapper")
@SpringBootApplication
public class ShardingJDBCApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShardingJDBCApplication.class,args);
    }
}

🍊3.添加application.properties配置

# 哈希分片策略

# 设置数据源名称为 m1
spring.shardingsphere.datasource.names=m1
# 设置数据源类型为 Druid 数据源
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
# 设置数据源驱动为 MySQLJDBC 驱动
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
# 设置数据源连接 URL,连接本地 MySQL 数据库的 coursedb 库
spring.shardingsphere.datasource.m1.url=jdbc:mysql://192.168.122.128:3306/masterdemo?serverTimezone=GMT%2B8
# 设置连接数据库所需的用户名和密码
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=bfb8f36cc2616995
# 设置分片表的实际数据节点,对应两个数据表:m1.t_course_1 和 m1.t_course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m1.t_course_$->{1..2}
# 设置分片键为 cid
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
# 设置分布式 ID 生成算法为 SNOWFLAKE 算法,worker ID1
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# Spring Boot 应用配置项:ShardingSphere 分库分表配置之课程表的主键生成策略配置项,属性名: worker.id,属性值: 1 (表示该应用程序所使用的 Snowflake 算法的工作节点 ID1)
spring.shardingsphere.sharding.tables.course.key-generator.props.worker.id=1
# 设置分表算法为 inline 分片算法,分片列为 cid,分片规则为课程编号为奇数的记录在 m1.t_course_1 表中,课程编号为偶数的记录在 m1.t_course_2 表中
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
# table-strategy.inline:表示使用内联表达式的分片策略。lgorithm-expression:表示表名生成算法表达式。t_course_$->{cid%2+1}:表示生成的表名,即t_course_后面接下标为(cid%2+1)的表。
# cid是表中的一个自增主键,%2表示对2取余数,+1表示取余结果加1,即cid值为偶数进入到t_course_1表,cid值为奇数进入到t_course_2表。
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=t_course_$->{cid%2+1}
# 设置 SQL 显示开启,方便调试
spring.shardingsphere.props.sql.show=true
# 允许覆盖 Bean 定义,用于调试时快速更新配置
spring.main.allow-bean-definition-overriding=true

🍊4.普通的自定义实体类

public class Course {
    private Long cid;
    private String cname;
    private Long userId;
    private String cstatus;
    //省略get/set方法了

🍊5.写个测试类验证一下

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.shardingDemo.entity.Course;
import com.example.shardingDemo.entity.Dict;
import com.example.shardingDemo.entity.User;
import com.example.shardingDemo.mapper.CourseMapper;
import com.example.shardingDemo.mapper.DictMapper;
import com.example.shardingDemo.mapper.UserMapper;
import org.apache.shardingsphere.api.hint.HintManager;
import org.junit.Test;
import org.junit.jupiter.api.Tags;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingJDBCTest {
    @Resource
    CourseMapper courseMapper;

    @Test
    public void addCourse(){
        for(int i = 0 ; i < 10 ; i ++){
            Course c = new Course();
            c.setCid(Long.valueOf(i));
            c.setCname("shardingsphere");
            c.setUserId(Long.valueOf(""+(1000+i)));
            c.setCstatus("1");
            courseMapper.insert(c);
        }
    }
}

🍊6.控制台打印的日志


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.1.RELEASE)

2023-11-08 18:02:14.029  INFO 11092 --- [           main] c.e.a.ShardingJDBCTest                   : Starting ShardingJDBCTest on WIN-20230222ULN with PID 11092 (started by Administrator in E:\WarkSpace\基础篇书籍\第8章\apache-shardingsphere-demo)
2023-11-08 18:02:14.032  INFO 11092 --- [           main] c.e.a.ShardingJDBCTest                   : No active profile set, falling back to default profiles: default
2023-11-08 18:02:14.414  INFO 11092 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'stringToNoneShardingStrategyConfigurationConverter' of type [org.apache.shardingsphere.spring.boot.converter.StringToNoneShardingStrategyConfigurationConverter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-08 18:02:14.422  INFO 11092 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.shardingsphere.sharding-org.apache.shardingsphere.shardingjdbc.spring.boot.sharding.SpringBootShardingRuleConfigurationProperties' of type [org.apache.shardingsphere.shardingjdbc.spring.boot.sharding.SpringBootShardingRuleConfigurationProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-08 18:02:14.422  INFO 11092 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.shardingsphere.masterslave-org.apache.shardingsphere.shardingjdbc.spring.boot.masterslave.SpringBootMasterSlaveRuleConfigurationProperties' of type [org.apache.shardingsphere.shardingjdbc.spring.boot.masterslave.SpringBootMasterSlaveRuleConfigurationProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-08 18:02:14.426  INFO 11092 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.shardingsphere.encrypt-org.apache.shardingsphere.shardingjdbc.spring.boot.encrypt.SpringBootEncryptRuleConfigurationProperties' of type [org.apache.shardingsphere.shardingjdbc.spring.boot.encrypt.SpringBootEncryptRuleConfigurationProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-08 18:02:14.426  INFO 11092 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.shardingsphere.shadow-org.apache.shardingsphere.shardingjdbc.spring.boot.shadow.SpringBootShadowRuleConfigurationProperties' of type [org.apache.shardingsphere.shardingjdbc.spring.boot.shadow.SpringBootShadowRuleConfigurationProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-08 18:02:14.430  INFO 11092 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.shardingsphere-org.apache.shardingsphere.shardingjdbc.spring.boot.common.SpringBootPropertiesConfigurationProperties' of type [org.apache.shardingsphere.shardingjdbc.spring.boot.common.SpringBootPropertiesConfigurationProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-08 18:02:14.549  INFO 11092 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration' of type [org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration$$EnhancerBySpringCGLIB$$f2dcf3ef] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-08 18:02:14.736  INFO 11092 --- [           main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
2023-11-08 18:02:15.200  INFO 11092 --- [           main] o.a.s.core.log.ConfigurationLogger       : ShardingRuleConfiguration:
tables:
  course:
    actualDataNodes: m1.t_course_$->{1..2}
    keyGenerator:
      column: cid
      props:
        worker.id: '1'
      type: SNOWFLAKE
    logicTable: course
    tableStrategy:
      inline:
        algorithmExpression: t_course_$->{cid%2+1}
        shardingColumn: cid

2023-11-08 18:02:15.200  INFO 11092 --- [           main] o.a.s.core.log.ConfigurationLogger       : Properties:
sql.show: 'true'

2023-11-08 18:02:15.208  INFO 11092 --- [           main] ShardingSphere-metadata                  : Loading 1 logic tables' meta data.
2023-11-08 18:02:15.254  INFO 11092 --- [           main] ShardingSphere-metadata                  : Loading 8 tables' meta data.
2023-11-08 18:02:15.285  INFO 11092 --- [           main] ShardingSphere-metadata                  : Meta data load finished, cost 85 milliseconds.
 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.0.5 
2023-11-08 18:02:15.391  WARN 11092 --- [           main] c.b.m.core.toolkit.TableInfoHelper       : Warn: Could not find @TableId in Class: com.example.apacheshardingspheredemo.entity.Course.
2023-11-08 18:02:15.466  WARN 11092 --- [           main] c.b.m.core.toolkit.TableInfoHelper       : Warn: Could not find @TableId in Class: com.example.apacheshardingspheredemo.entity.Dict.
2023-11-08 18:02:15.479  WARN 11092 --- [           main] c.b.m.core.toolkit.TableInfoHelper       : Warn: Could not find @TableId in Class: com.example.apacheshardingspheredemo.entity.User.
2023-11-08 18:02:15.577  INFO 11092 --- [           main] c.e.a.ShardingJDBCTest                   : Started ShardingJDBCTest in 1.698 seconds (JVM running for 2.242)
2023-11-08 18:02:15.949  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.949  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@5ee6fdc4), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@5ee6fdc4, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[0, shardingsphere, 1000, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[0])])
2023-11-08 18:02:15.949  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_1  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [0, shardingsphere, 1000, 1]
2023-11-08 18:02:15.966  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.966  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@43fd77d8), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@43fd77d8, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[1, shardingsphere, 1001, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[1])])
2023-11-08 18:02:15.966  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_2  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [1, shardingsphere, 1001, 1]
2023-11-08 18:02:15.966  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.966  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@32ba5c65), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@32ba5c65, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[2, shardingsphere, 1002, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[2])])
2023-11-08 18:02:15.966  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_1  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [2, shardingsphere, 1002, 1]
2023-11-08 18:02:15.971  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.971  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@702f4124), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@702f4124, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[3, shardingsphere, 1003, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[3])])
2023-11-08 18:02:15.971  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_2  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [3, shardingsphere, 1003, 1]
2023-11-08 18:02:15.975  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.975  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@22ff1372), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@22ff1372, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[4, shardingsphere, 1004, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[4])])
2023-11-08 18:02:15.975  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_1  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [4, shardingsphere, 1004, 1]
2023-11-08 18:02:15.975  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.975  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@4d825dbe), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@4d825dbe, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[5, shardingsphere, 1005, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[5])])
2023-11-08 18:02:15.975  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_2  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [5, shardingsphere, 1005, 1]
2023-11-08 18:02:15.979  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.979  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@63814bbe), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@63814bbe, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[6, shardingsphere, 1006, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[6])])
2023-11-08 18:02:15.979  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_1  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [6, shardingsphere, 1006, 1]
2023-11-08 18:02:15.983  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.983  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@70b196d3), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@70b196d3, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[7, shardingsphere, 1007, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[7])])
2023-11-08 18:02:15.983  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_2  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [7, shardingsphere, 1007, 1]
2023-11-08 18:02:15.983  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.983  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@72001c71), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@72001c71, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[8, shardingsphere, 1008, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[8])])
2023-11-08 18:02:15.983  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_1  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [8, shardingsphere, 1008, 1]
2023-11-08 18:02:15.987  INFO 11092 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO course  ( cid,
cname,
user_id,
cstatus )  VALUES  ( ?,
?,
?,
? )
2023-11-08 18:02:15.987  INFO 11092 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@7ab1ad9, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7d90644f), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7d90644f, columnNames=[cid, cname, user_id, cstatus], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=3)], parameters=[9, shardingsphere, 1009, 1])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=false, generatedValues=[9])])
2023-11-08 18:02:15.987  INFO 11092 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: INSERT INTO t_course_2  ( cid,
cname,
user_id,
cstatus )  VALUES  (?, ?, ?, ?) ::: [9, shardingsphere, 1009, 1]
2023-11-08 18:02:15.995  INFO 11092 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closing ...
2023-11-08 18:02:15.995  INFO 11092 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed
Disconnected from the target VM, address: '127.0.0.1:52128', transport: 'socket'

🍊7.观察一下数据库的数据

course_1表的数据如图下所示:
course_1表

可以发现course_1表的cid都是偶数。

course_2表的数据如图所示:
course_2表

可以发现course_2表的cid都是奇数。

🍊8.maven的setting文件

为了避免部分同学下载依赖包不一致导致maven依赖下载不下来,我这里给上自己的配置文件,代码如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Maven 的配置文件 -->
<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0
        http://maven.apache.org/xsd/settings-1.1.0.xsd">
  <!-- 设置本地仓库的路径 -->
  <localRepository>D:\Java\ReMaven</localRepository>
  <!-- 设置镜像 -->
  <mirrors>
  	<mirror>
      <id>central</id>
      <url>https://repo1.maven.org/maven2/</url>
      <mirrorOf>*</mirrorOf>
    </mirror>
    <!-- 定义一个镜像 -->
    <!-- <mirror>
      <id>aliyunmaven</id> 
      <name>Alibaba Maven Mirror</name> 
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url> 
      <mirrorOf>central</mirrorOf> 
    </mirror>
	-->
	<mirror>
	  <id>aliyunmaven</id><!-- 镜像的id -->
	  <mirrorOf>*</mirrorOf><!-- 镜像代理的仓库id,这里将中央仓库的地址替换为阿里云的地址 -->
	  <name>阿里云公共仓库</name><!-- 镜像的名称 -->
	  <url>https://maven.aliyun.com/repository/public</url><!-- 镜像的地址 -->
	</mirror>
  </mirrors>
  <!-- 设置代理 -->
  <proxies></proxies>
  <!-- 设置私有仓库的认证信息 -->
  <servers></servers>
  <!-- 定义构建时添加的环境参数 -->
  <profiles>
    <!-- 定义一个profile -->
    <profile>
      <id>jdk-1.8</id> <!-- profile的id -->
      <activation> <!-- 激活条件 -->
        <activeByDefault>true</activeByDefault> <!-- 默认激活 -->
        <jdk>1.8</jdk> <!-- 使用的JDK版本 -->
      </activation>
      <properties> <!-- 定义环境变量 -->
        <maven.compiler.source>1.8</maven.compiler.source> <!-- 编译代码的源版本 -->
        <maven.compiler.target>1.8</maven.compiler.target> <!-- 编译代码的目标版本 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 项目源码的编码方式 -->
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- 项目输出的编码方式 -->
        <java.version>1.8</java.version> <!-- 使用的Java版本 -->
      </properties>
    </profile>
  </profiles>
  <!-- 设置默认激活的环境 -->
  <activeProfiles>
    <activeProfile>jdk-1.8</activeProfile> <!-- 默认激活的profile -->
  </activeProfiles>
</settings>

🍊9.视频演示

这里提供一个视频演示,简单讲解一下,视频发布在哔哩哔哩平台上。

快速使用ShardingJDBC的哈希分片策略进行分表

CSDN

📢文章总结

对本篇文章进行总结:

🔔以上就是今天要讲的内容,阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。

以梦为马,不负韶华

🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

🚀🎉希望各位读者大大多多支持用心写文章的博主,现在时代变了,🚀🎉 信息爆炸,酒香也怕巷子深🔥,博主真的需要大家的帮助才能在这片海洋中继续发光发热🎨,所以,🏃💨赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

  • 💂 博客主页: 我是廖志伟
  • 👉开源项目:java_wxid
  • 🌥 哔哩哔哩:我是廖志伟
  • 🎏个人社区:幕后大佬
  • 🔖个人微信号SeniorRD
  • 🎉微信号二维码SeniorRD

📥博主目标

探寻内心世界,博主分享人生感悟与未来目标

  • 🍋程序开发这条路不能停,停下来容易被淘汰掉,吃不了自律的苦,就要受平庸的罪,持续的能力才能带来持续的自信。我本是一个很普通的程序员,放在人堆里,除了与生俱来的盛世美颜,就剩180的大高个了,就是我这样的一个人,默默写博文也有好多年了。
  • 📺有句老话说的好,牛逼之前都是傻逼式的坚持,希望自己可以通过大量的作品、时间的积累、个人魅力、运气、时机,可以打造属于自己的技术影响力。
  • 💥内心起伏不定,我时而激动,时而沉思。我希望自己能成为一个综合性人才,具备技术、业务和管理方面的精湛技能。我想成为产品架构路线的总设计师,团队的指挥者,技术团队的中流砥柱,企业战略和资本规划的实战专家。
  • 🎉这个目标的实现需要不懈的努力和持续的成长,但我必须努力追求。因为我知道,只有成为这样的人才,我才能在职业生涯中不断前进并为企业的发展带来真正的价值。在这个不断变化的时代,我们必须随时准备好迎接挑战,不断学习和探索新的领域,才能不断地向前推进。我坚信,只要我不断努力,我一定会达到自己的目标。

🔔有需要对自己进行综合性评估,进行职业方向规划,我可以让技术大牛帮你模拟面试、针对性的指导、传授面试技巧、简历优化、进行技术问题答疑等服务。

可访问:https://java_wxid.gitee.io/tojson/

开发人员简历优化、面试突击指导、技术问题解答

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1185106.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

竞赛 目标检测-行人车辆检测流量计数

文章目录 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 行人车辆目标检测计数系统 …

Linux之make/maakefile

access不是实时更新的。 printf打印并不是直接给屏幕而是先放到缓冲区。 可以通过fflush(stdout)强制刷新缓冲区。 换行是指直接到同一位置的下一行&#xff0c;回车是回到开头。

【MySQL数据库】 七

本文主要介绍了Java的JDBC编程的过程. 超详细 !!! 一.JDBC JDBC就是通过Java代码,来操作数据库 由于我们在实际开发中,绝大部分都是用代码来操作数据库的 , 因此一个成熟的数据库,都会提供一些API让程序员来使用. 常见的数据库比如mysql / oracl / sqlserver / SQLite 都会提…

Python类与对象:类的定义、实例化、方法、属性、构造函数

文章目录 类的定义类的实例化方法属性构造函数Python 类和对象是面向对象编程的基础。在 Python 中,几乎所有东西都是对象,拥有属性和方法。类是创建对象的蓝图或模板。让我们一步步来探索类的定义、实例化、方法、属性以及构造函数,并提供详细的代码示例。 类的定义 在 P…

SQL注入漏洞 其他注入

文章目录 宽字节注入案例 HTTP头部注入Cookie注入base64User-Agent注入Referer 注入 SQL注入读写文件条件1.是否拥有读写权限2.文件路径3.secure_file_priv 读取文件写入文件 SQLMap安装sqlmapkail 源安装仓库克隆 参数简介快速入门&#xff1b;SQLmap&#xff08;常规&#xf…

【Docker】设置容器系统字符集zh_CN.UTF-8退出失效:关于Docker容器配置环境变量,再次进入失效问题

设置容器系统字符集zh_CN.UTF-8退出失效&#xff1a;关于Docker容器配置环境变量&#xff0c;再次进入失效问题 修改正在运行的Docker容器内的字符集: 先进入Docker容器&#xff1a;docker exec -it 容器ID /bin/bash查看是否支持中文字符集&#xff1a;locale -a | grep zh&a…

B站双11,联手天猫暴涨2亿消费新势力

一直以来&#xff0c;手持高活跃、高粘性用户群体的B站是行业用来观察年轻人消费习惯的重要平台。以至于用户群体的不断壮大带动了B站的商业价值。如今B站的商业舞台越来越大&#xff0c;不断地向外界招手&#xff0c;欢迎更多品牌积极加入到这个千万年轻人聚集的内容社区。 2…

如何有效防爬虫?教你打造安全堡垒

企业拥抱数字化技术的过程中&#xff0c;网络犯罪分子的“战术”也更难以觉察&#xff0c;并且这些攻击越来越自动化和复杂&#xff0c;也更加难以觉察。在众多攻击手段总&#xff0c;网络爬虫是企业面临的主要安全挑战&#xff0c;对于企业所造成的经济损失是难以计量的。那么…

设备密集型单位如何提升效率?智能巡检软件哪个好?

在设备密集型单位&#xff0c;如钢铁、化工、电力、烟草、日用品等行业以及运维商&#xff0c;日常工作中面临着设备巡检这一重要且繁琐的任务。传统的巡检方式往往依靠纸质记录&#xff0c;数据难以进行统计或分析&#xff0c;巡检人员需要手动记录各种数据&#xff0c;不仅效…

visual studio 启用DPI识别功能

在开发widow程序时&#xff0c;有时必须将电脑 设置-->显示-->缩放与布局-->更改文本、应用项目的大小-->100%后&#xff0c;程序的画面才能正确运行&#xff0c;居说这是锁定了dpi的原因&#xff0c;需要启dpi识别功能。设置方法如下&#xff1a; 或者

unity - Blend Shape - 变形器 - 实践

文章目录 目的Blend Shape 逐顶点 多个混合思路Blender3Ds maxUnity 中使用Project 目的 拾遗&#xff0c;备份 Blend Shape 逐顶点 多个混合思路 blend shape 基于&#xff1a; vertex number, vertex sn 相同&#xff0c;才能正常混合、播放 也就是 vertex buffer 的顶点数…

CocosCreator让一个物体跟随鼠标移动(两种方式 本地坐标系和世界坐标系)

在 Cocos Creator 3.x 游戏运行时显示的画布大小就是屏幕区域&#xff0c;屏幕坐标是从画布的左下角为原点开始计算 在 Creator 3.x 里&#xff0c;屏幕和 UI 是完全区分开的&#xff0c;用户可以在没有 UI 的情况下点击屏幕获取触点信息。因此&#xff0c;获取屏幕触点&#…

Jmeter工具二次开发

一、JMeter 二次开发方向 1、函数开发&#xff0c;主要为JMeter 函数库 2、插件开发&#xff0c;一般主要做取样器开发 3、基于执行引擎开发&#xff0c;有效解决单独开发的测试平台或工具中&#xff0c;底层执行引擎开发相对复杂、周期长的问题&#xff0c;利用 JMeter 执行…

分享vmware和Oracle VM VirtualBox虚拟机的区别,简述哪一个更适合我?

VMware和Oracle VM VirtualBox虚拟机的区别主要体现在以下几个方面&#xff1a; 首先两种软件的安装使用教程如下&#xff1a; 1&#xff1a;VMware ESXI 安装使用教程 2&#xff1a;Oracle VM VirtualBox安装使用教程 商业模式&#xff1a;VMware是一家商业公司&#xff0c;而…

数据结构: 哈希桶

目录 1.概念 2.模拟实现 2.1框架 2.2哈希桶结构 2.3相关功能 Modify --Insert --Erase --Find 2.4非整型数据入哈希桶 1.仿函数 2.BKDR哈希 1.概念 具有相同地址的key值归于同一集合中,这个集合称为一个桶,各个桶的元素通过单链表链接 2.模拟实现 2.1框架 a.写出…

oracle数据导出exp导入imp

Oracle的exp/imp命令用于实现对数据库的导出/导入操作&#xff1b; exp命令用于把数据从远程数据库服务器导出至本地&#xff0c;生成dmp文件&#xff1b; imp命令用于把本地的数据库dmp文件从本地导入到远程的Oracle数据库。 一、获取帮助信息 exp/imp helpy 二、数据导出 1…

打破边界,一触即达——全新跨境电商业态,一键开启全球贸易新时代!

随着全球电子商务的飞速发展&#xff0c;跨境电商已成为连接国内外市场的桥梁。为了满足商家日益增长的海外拓展需求&#xff0c;我们重磅推出跨境电商源码商城&#xff0c;融合商家一键铺货、代理商后台、供货商后台、商品采集、短视频、直播、社交、分销、积分、多语言、国际…

阿里云双11优惠:云服务器1年99元,新老同享,续费同价!

阿里云2核2G3M带宽99元服务器新老用户同享&#xff0c;续费不涨价&#xff0c;99元即可续费&#xff0c;可以续费到2027年&#xff0c;相当于396元买4年&#xff0c;阿里云百科aliyunbaike.com来详细说下阿里云99元服务器配置、购买条件、优惠价格和续费攻略&#xff1a; 阿里…

js获取地址中携带的省市区

match() 方法可在字符串内检索指定的值&#xff0c;或找到一个或多个正则表达式的匹配。 match() 方法将检索字符串 String Object&#xff0c;以找到一个或多个与 regexp 匹配的文本。这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g。如果 regexp 没有标志 g&#x…

图形界面应用案例——关灯游戏(以及扩展)(python)

7.8 图形界面应用案例——关灯游戏 题目: [案例]游戏初步——关灯游戏。 关灯游戏是很有意思的益智游戏,玩家通过单击关掉(或打开)一盏灯。如果关(掉(或打开)一个电灯,其周围(上下左右)的电灯也会触及开关,成功地关掉所有电灯即可过关。 图7-43 关灯游戏运行效…