diff --git a/.gitignore b/.gitignore
index c41a3cd..5b0a4e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,7 @@ stylesheet.css
# jenv local settings
.java-version
+
+# environment shell script
+
+env.sh
diff --git a/env.sh.example b/env.sh.example
new file mode 100644
index 0000000..8e0213a
--- /dev/null
+++ b/env.sh.example
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+export TIDB_HOST='xxxxxxxx.aws.tidbcloud.com'
+export TIDB_PORT='4000'
+export TIDB_USER='xxxxxxxxxxx.root'
+export TIDB_PASSWORD='xxxxxxx'
+export TIDB_DB_NAME='test'
+export USE_SSL='true'
+
+jdbc_url="jdbc:mysql://${TIDB_HOST}:${TIDB_PORT}/${TIDB_DB_NAME}"
+if [ 'true'=="${USE_SSL}" ]; then
+ jdbc_url="${jdbc_url}?sslMode=VERIFY_IDENTITY&enabledTLSProtocols=TLSv1.2,TLSv1.3"
+fi
+
+export TIDB_JDBC_URL=${jdbc_url}
diff --git a/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/pom.xml b/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/pom.xml
deleted file mode 100644
index 70191f3..0000000
--- a/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/pom.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-
- 4.0.0
-
- com.pingcap.example
- TiDBHibernateNormalExample
- 1.0-SNAPSHOT
- jar
-
- TiDBHibernateNormalExample
- https://www.pingcap.com
-
-
- UTF-8
- 17
- 17
-
-
-
-
- junit
- junit
- 4.13.2
- test
-
-
-
-
- mysql
- mysql-connector-java
- 8.0.33
-
-
-
- org.hibernate.orm
- hibernate-core
- 6.2.3.Final
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 3.3.0
-
-
- jar-with-dependencies
-
-
-
- com.pingcap.example.App
-
-
-
-
-
-
- make-assembly
- package
-
- single
-
-
-
-
-
-
-
diff --git a/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/src/main/java/com/pingcap/example/App.java b/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/src/main/java/com/pingcap/example/App.java
deleted file mode 100644
index db05d97..0000000
--- a/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/src/main/java/com/pingcap/example/App.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.pingcap.example;
-
-import org.hibernate.Session;
-import org.hibernate.SessionFactory;
-import org.hibernate.cfg.Configuration;
-
-public class App {
- public static void main( String[] args ) {
- try (SessionFactory sessionFactory = new Configuration()
- .configure("hibernate.cfg.xml")
- .buildSessionFactory(); Session session = sessionFactory.openSession()) {
- String result = session.createNativeQuery("SELECT 'Hello World'", String.class)
- .getSingleResult();
- System.out.println(result);
- }
- }
-}
diff --git a/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/src/main/resources/hibernate.cfg.xml b/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/src/main/resources/hibernate.cfg.xml
deleted file mode 100644
index b02a02a..0000000
--- a/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/src/main/resources/hibernate.cfg.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
- com.mysql.cj.jdbc.Driver
- org.hibernate.dialect.TiDBDialect
- jdbc:mysql://localhost:4000/test
- root
-
- false
-
-
- true
- true
-
-
diff --git a/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/src/test/java/com/pingcap/example/AppTest.java b/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/src/test/java/com/pingcap/example/AppTest.java
deleted file mode 100644
index ea2f63f..0000000
--- a/hello-world-apps/Hibernate/normal/TiDBHibernateNormalExample/src/test/java/com/pingcap/example/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.pingcap.example;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}
diff --git a/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/pom.xml b/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/pom.xml
deleted file mode 100644
index 0e9b003..0000000
--- a/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/pom.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-
- 4.0.0
-
- com.pingcap.example
- TiDBHibernateServerlessExample
- 1.0-SNAPSHOT
- jar
-
- TiDBHibernateServerlessExample
- https://www.pingcap.com
-
-
- UTF-8
- 17
- 17
-
-
-
-
- junit
- junit
- 4.13.2
- test
-
-
-
-
- mysql
- mysql-connector-java
- 8.0.33
-
-
-
- org.hibernate.orm
- hibernate-core
- 6.2.3.Final
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 3.3.0
-
-
- jar-with-dependencies
-
-
-
- com.pingcap.example.App
-
-
-
-
-
-
- make-assembly
- package
-
- single
-
-
-
-
-
-
-
diff --git a/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/src/main/java/com/pingcap/example/App.java b/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/src/main/java/com/pingcap/example/App.java
deleted file mode 100644
index db05d97..0000000
--- a/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/src/main/java/com/pingcap/example/App.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.pingcap.example;
-
-import org.hibernate.Session;
-import org.hibernate.SessionFactory;
-import org.hibernate.cfg.Configuration;
-
-public class App {
- public static void main( String[] args ) {
- try (SessionFactory sessionFactory = new Configuration()
- .configure("hibernate.cfg.xml")
- .buildSessionFactory(); Session session = sessionFactory.openSession()) {
- String result = session.createNativeQuery("SELECT 'Hello World'", String.class)
- .getSingleResult();
- System.out.println(result);
- }
- }
-}
diff --git a/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/src/main/resources/hibernate.cfg.xml b/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/src/main/resources/hibernate.cfg.xml
deleted file mode 100644
index 5d0540f..0000000
--- a/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/src/main/resources/hibernate.cfg.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
- com.mysql.cj.jdbc.Driver
- org.hibernate.dialect.TiDBDialect
- jdbc:mysql://${host}:4000/test?sslMode=VERIFY_IDENTITY&enabledTLSProtocols=TLSv1.2,TLSv1.3
- ${user}
- ${password}
- false
-
-
- true
- true
-
-
diff --git a/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/src/test/java/com/pingcap/example/AppTest.java b/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/src/test/java/com/pingcap/example/AppTest.java
deleted file mode 100644
index ea2f63f..0000000
--- a/hello-world-apps/Hibernate/serverless/TiDBHibernateServerlessExample/src/test/java/com/pingcap/example/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.pingcap.example;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}
diff --git a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/pom.xml b/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/pom.xml
deleted file mode 100644
index 9978e99..0000000
--- a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/pom.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-
- 4.0.0
-
- com.pingcap.example
- TiDBMyBatisNormalExample
- 1.0-SNAPSHOT
- jar
-
- TiDBMyBatisNormalExample
- https://www.pingcap.com
-
-
- UTF-8
- 17
- 17
-
-
-
-
- junit
- junit
- 4.13.2
- test
-
-
-
-
- mysql
- mysql-connector-java
- 8.0.33
-
-
-
-
- org.mybatis
- mybatis
- 3.5.13
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 3.3.0
-
-
- jar-with-dependencies
-
-
-
- com.pingcap.example.App
-
-
-
-
-
-
- make-assembly
- package
-
- single
-
-
-
-
-
-
-
diff --git a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/main/java/com/pingcap/example/App.java b/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/main/java/com/pingcap/example/App.java
deleted file mode 100644
index a4d944b..0000000
--- a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/main/java/com/pingcap/example/App.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.pingcap.example;
-
-import org.apache.ibatis.io.Resources;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.apache.ibatis.session.SqlSessionFactoryBuilder;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-public class App {
- public static void main( String[] args ) throws IOException {
- InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- try (SqlSession session = sqlSessionFactory.openSession()) {
- HelloWorldMapper mapper = session.getMapper(HelloWorldMapper.class);
- System.out.println(mapper.helloWorld());
- }
- }
-}
diff --git a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/main/java/com/pingcap/example/HelloWorldMapper.java b/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/main/java/com/pingcap/example/HelloWorldMapper.java
deleted file mode 100644
index 059b066..0000000
--- a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/main/java/com/pingcap/example/HelloWorldMapper.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2022 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.pingcap.example;
-
-import org.apache.ibatis.annotations.Select;
-
-/**
- * HelloWorldMapper
- *
- * @author Icemap
- * @date 2023/7/13
- */
-public interface HelloWorldMapper {
- @Select("SELECT 'Hello World'")
- String helloWorld();
-}
\ No newline at end of file
diff --git a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/main/resources/mybatis-config.xml b/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/main/resources/mybatis-config.xml
deleted file mode 100644
index 7a16559..0000000
--- a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/main/resources/mybatis-config.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/test/java/com/pingcap/example/AppTest.java b/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/test/java/com/pingcap/example/AppTest.java
deleted file mode 100644
index ea2f63f..0000000
--- a/hello-world-apps/MyBatis/normal/TiDBMyBatisNormalExample/src/test/java/com/pingcap/example/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.pingcap.example;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}
diff --git a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/pom.xml b/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/pom.xml
deleted file mode 100644
index 0df50cb..0000000
--- a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/pom.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-
- 4.0.0
-
- com.pingcap.example
- TiDBMyBatisServerlessExample
- 1.0-SNAPSHOT
- jar
-
- TiDBMyBatisServerlessExample
- https://www.pingcap.com
-
-
- UTF-8
- 17
- 17
-
-
-
-
- junit
- junit
- 4.13.2
- test
-
-
-
-
- mysql
- mysql-connector-java
- 8.0.33
-
-
-
-
- org.mybatis
- mybatis
- 3.5.13
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 3.3.0
-
-
- jar-with-dependencies
-
-
-
- com.pingcap.example.App
-
-
-
-
-
-
- make-assembly
- package
-
- single
-
-
-
-
-
-
-
diff --git a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/main/java/com/pingcap/example/App.java b/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/main/java/com/pingcap/example/App.java
deleted file mode 100644
index a4d944b..0000000
--- a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/main/java/com/pingcap/example/App.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.pingcap.example;
-
-import org.apache.ibatis.io.Resources;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.apache.ibatis.session.SqlSessionFactoryBuilder;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-public class App {
- public static void main( String[] args ) throws IOException {
- InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- try (SqlSession session = sqlSessionFactory.openSession()) {
- HelloWorldMapper mapper = session.getMapper(HelloWorldMapper.class);
- System.out.println(mapper.helloWorld());
- }
- }
-}
diff --git a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/main/java/com/pingcap/example/HelloWorldMapper.java b/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/main/java/com/pingcap/example/HelloWorldMapper.java
deleted file mode 100644
index 059b066..0000000
--- a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/main/java/com/pingcap/example/HelloWorldMapper.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2022 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.pingcap.example;
-
-import org.apache.ibatis.annotations.Select;
-
-/**
- * HelloWorldMapper
- *
- * @author Icemap
- * @date 2023/7/13
- */
-public interface HelloWorldMapper {
- @Select("SELECT 'Hello World'")
- String helloWorld();
-}
\ No newline at end of file
diff --git a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/main/resources/mybatis-config.xml b/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/main/resources/mybatis-config.xml
deleted file mode 100644
index f2ab5ff..0000000
--- a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/main/resources/mybatis-config.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/test/java/com/pingcap/example/AppTest.java b/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/test/java/com/pingcap/example/AppTest.java
deleted file mode 100644
index ea2f63f..0000000
--- a/hello-world-apps/MyBatis/serverless/TiDBMyBatisServerlessExample/src/test/java/com/pingcap/example/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.pingcap.example;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/.gitignore b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/.gitignore
deleted file mode 100644
index 549e00a..0000000
--- a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### VS Code ###
-.vscode/
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/.mvn/wrapper/maven-wrapper.jar b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/.mvn/wrapper/maven-wrapper.jar
deleted file mode 100644
index cb28b0e..0000000
Binary files a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/.mvn/wrapper/maven-wrapper.jar and /dev/null differ
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/.mvn/wrapper/maven-wrapper.properties b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/.mvn/wrapper/maven-wrapper.properties
deleted file mode 100644
index 462686e..0000000
--- a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/.mvn/wrapper/maven-wrapper.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/mvnw b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/mvnw
deleted file mode 100755
index 66df285..0000000
--- a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/mvnw
+++ /dev/null
@@ -1,308 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.2.0
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
-#
-# Optional ENV vars
-# -----------------
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-# ----------------------------------------------------------------------------
-
-if [ -z "$MAVEN_SKIP_RC" ] ; then
-
- if [ -f /usr/local/etc/mavenrc ] ; then
- . /usr/local/etc/mavenrc
- fi
-
- if [ -f /etc/mavenrc ] ; then
- . /etc/mavenrc
- fi
-
- if [ -f "$HOME/.mavenrc" ] ; then
- . "$HOME/.mavenrc"
- fi
-
-fi
-
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
-mingw=false
-case "$(uname)" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
- if [ -z "$JAVA_HOME" ]; then
- if [ -x "/usr/libexec/java_home" ]; then
- JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
- else
- JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
- fi
- fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=$(java-config --jre-home)
- fi
-fi
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
-fi
-
-# For Mingw, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
- JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="$(which javac)"
- if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=$(which readlink)
- if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
- if $darwin ; then
- javaHome="$(dirname "\"$javaExecutable\"")"
- javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
- else
- javaExecutable="$(readlink -f "\"$javaExecutable\"")"
- fi
- javaHome="$(dirname "\"$javaExecutable\"")"
- javaHome=$(expr "$javaHome" : '\(.*\)/bin')
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
-
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- else
- JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
- fi
-fi
-
-if [ ! -x "$JAVACMD" ] ; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
-
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
-fi
-
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
- if [ -z "$1" ]
- then
- echo "Path not specified to find_maven_basedir"
- return 1
- fi
-
- basedir="$1"
- wdir="$1"
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
- basedir=$wdir
- break
- fi
- # workaround for JBEAP-8937 (on Solaris 10/Sparc)
- if [ -d "${wdir}" ]; then
- wdir=$(cd "$wdir/.." || exit 1; pwd)
- fi
- # end of workaround
- done
- printf '%s' "$(cd "$basedir" || exit 1; pwd)"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- # Remove \r in case we run on Windows within Git Bash
- # and check out the repository with auto CRLF management
- # enabled. Otherwise, we may read lines that are delimited with
- # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
- # splitting rules.
- tr -s '\r\n' ' ' < "$1"
- fi
-}
-
-log() {
- if [ "$MVNW_VERBOSE" = true ]; then
- printf '%s\n' "$1"
- fi
-}
-
-BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
-if [ -z "$BASE_DIR" ]; then
- exit 1;
-fi
-
-MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
-log "$MAVEN_PROJECTBASEDIR"
-
-##########################################################################################
-# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-# This allows using the maven wrapper in projects that prohibit checking in binary data.
-##########################################################################################
-wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
-if [ -r "$wrapperJarPath" ]; then
- log "Found $wrapperJarPath"
-else
- log "Couldn't find $wrapperJarPath, downloading it ..."
-
- if [ -n "$MVNW_REPOURL" ]; then
- wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- else
- wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- fi
- while IFS="=" read -r key value; do
- # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
- safeValue=$(echo "$value" | tr -d '\r')
- case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
- esac
- done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
- log "Downloading from: $wrapperUrl"
-
- if $cygwin; then
- wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
- fi
-
- if command -v wget > /dev/null; then
- log "Found wget ... using wget"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- else
- wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- fi
- elif command -v curl > /dev/null; then
- log "Found curl ... using curl"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- else
- curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- fi
- else
- log "Falling back to using Java to download"
- javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
- javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
- # For Cygwin, switch paths to Windows format before running javac
- if $cygwin; then
- javaSource=$(cygpath --path --windows "$javaSource")
- javaClass=$(cygpath --path --windows "$javaClass")
- fi
- if [ -e "$javaSource" ]; then
- if [ ! -e "$javaClass" ]; then
- log " - Compiling MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/javac" "$javaSource")
- fi
- if [ -e "$javaClass" ]; then
- log " - Running MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
- fi
- fi
- fi
-fi
-##########################################################################################
-# End of extension
-##########################################################################################
-
-# If specified, validate the SHA-256 sum of the Maven wrapper jar file
-wrapperSha256Sum=""
-while IFS="=" read -r key value; do
- case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
- esac
-done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
-if [ -n "$wrapperSha256Sum" ]; then
- wrapperSha256Result=false
- if command -v sha256sum > /dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- elif command -v shasum > /dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- else
- echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
- echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
- exit 1
- fi
- if [ $wrapperSha256Result = false ]; then
- echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
- echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
- echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
- exit 1
- fi
-fi
-
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
- [ -n "$MAVEN_PROJECTBASEDIR" ] &&
- MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
-fi
-
-# Provide a "standardized" way to retrieve the CLI args that will
-# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
-export MAVEN_CMD_LINE_ARGS
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-# shellcheck disable=SC2086 # safe args
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- $MAVEN_DEBUG_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/mvnw.cmd b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/mvnw.cmd
deleted file mode 100644
index 95ba6f5..0000000
--- a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/mvnw.cmd
+++ /dev/null
@@ -1,205 +0,0 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM https://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.2.0
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM set title of command window
-title %0
-@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
-if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
-
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
-)
-
-@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
-if exist %WRAPPER_JAR% (
- if "%MVNW_VERBOSE%" == "true" (
- echo Found %WRAPPER_JAR%
- )
-) else (
- if not "%MVNW_REPOURL%" == "" (
- SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- )
- if "%MVNW_VERBOSE%" == "true" (
- echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %WRAPPER_URL%
- )
-
- powershell -Command "&{"^
- "$webclient = new-object System.Net.WebClient;"^
- "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
- "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
- "}"^
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
- "}"
- if "%MVNW_VERBOSE%" == "true" (
- echo Finished downloading %WRAPPER_JAR%
- )
-)
-@REM End of extension
-
-@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
-SET WRAPPER_SHA_256_SUM=""
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
-)
-IF NOT %WRAPPER_SHA_256_SUM%=="" (
- powershell -Command "&{"^
- "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
- "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
- " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
- " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
- " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
- " exit 1;"^
- "}"^
- "}"
- if ERRORLEVEL 1 goto error
-)
-
-@REM Provide a "standardized" way to retrieve the CLI args that will
-@REM work with both Windows and non-Windows executions.
-set MAVEN_CMD_LINE_ARGS=%*
-
-%MAVEN_JAVA_EXE% ^
- %JVM_CONFIG_MAVEN_PROPS% ^
- %MAVEN_OPTS% ^
- %MAVEN_DEBUG_OPTS% ^
- -classpath %WRAPPER_JAR% ^
- "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
- %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
-if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%"=="on" pause
-
-if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
-
-cmd /C exit /B %ERROR_CODE%
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/pom.xml b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/pom.xml
deleted file mode 100644
index 8ec970a..0000000
--- a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.1.1
-
-
- com.pingcap
- TiDBSpringBootJPANormalExample
- 0.0.1-SNAPSHOT
- TiDBSpringBootJPANormalExample
- TiDBSpringBootJPANormalExample
-
- 17
-
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- com.mysql
- mysql-connector-j
- runtime
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/main/java/com/pingcap/example/HelloWorldController.java b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/main/java/com/pingcap/example/HelloWorldController.java
deleted file mode 100644
index 7169490..0000000
--- a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/main/java/com/pingcap/example/HelloWorldController.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2022 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.pingcap.example;
-
-import jakarta.persistence.EntityManager;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * HelloWorldController
- *
- * @author Icemap
- * @date 2023/7/12
- */
-@RestController
-@RequestMapping
-public class HelloWorldController {
- @Autowired
- private EntityManager entityManager;
-
- @GetMapping("/hello")
- public Object hello() {
- return entityManager
- .createNativeQuery("SELECT 'Hello World'")
- .getSingleResult();
- }
-}
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/main/java/com/pingcap/example/TiDBSpringBootJpaNormalExampleApplication.java b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/main/java/com/pingcap/example/TiDBSpringBootJpaNormalExampleApplication.java
deleted file mode 100644
index ddfc45e..0000000
--- a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/main/java/com/pingcap/example/TiDBSpringBootJpaNormalExampleApplication.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.pingcap.example;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class TiDBSpringBootJpaNormalExampleApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(TiDBSpringBootJpaNormalExampleApplication.class, args);
- }
-}
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/main/resources/application.yaml b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/main/resources/application.yaml
deleted file mode 100644
index f0833e6..0000000
--- a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/main/resources/application.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-spring:
- datasource:
- url: jdbc:mysql://localhost:4000/test
- username: root
- # password: xxx
- driver-class-name: com.mysql.cj.jdbc.Driver
- jpa:
- show-sql: true
- database-platform: org.hibernate.dialect.TiDBDialect
\ No newline at end of file
diff --git a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/test/java/com/pingcap/example/TiDbSpringBootJpaNormalExampleApplicationTests.java b/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/test/java/com/pingcap/example/TiDbSpringBootJpaNormalExampleApplicationTests.java
deleted file mode 100644
index 5a10024..0000000
--- a/hello-world-apps/SpringBoot-JPA/normal/TiDBSpringBootJPANormalExample/src/test/java/com/pingcap/example/TiDbSpringBootJpaNormalExampleApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.pingcap.example;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class TiDbSpringBootJpaNormalExampleApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/.gitignore b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/.gitignore
deleted file mode 100644
index 549e00a..0000000
--- a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### VS Code ###
-.vscode/
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/.mvn/wrapper/maven-wrapper.jar b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/.mvn/wrapper/maven-wrapper.jar
deleted file mode 100644
index cb28b0e..0000000
Binary files a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/.mvn/wrapper/maven-wrapper.jar and /dev/null differ
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/.mvn/wrapper/maven-wrapper.properties b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/.mvn/wrapper/maven-wrapper.properties
deleted file mode 100644
index 462686e..0000000
--- a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/.mvn/wrapper/maven-wrapper.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/mvnw b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/mvnw
deleted file mode 100755
index 66df285..0000000
--- a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/mvnw
+++ /dev/null
@@ -1,308 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.2.0
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
-#
-# Optional ENV vars
-# -----------------
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-# ----------------------------------------------------------------------------
-
-if [ -z "$MAVEN_SKIP_RC" ] ; then
-
- if [ -f /usr/local/etc/mavenrc ] ; then
- . /usr/local/etc/mavenrc
- fi
-
- if [ -f /etc/mavenrc ] ; then
- . /etc/mavenrc
- fi
-
- if [ -f "$HOME/.mavenrc" ] ; then
- . "$HOME/.mavenrc"
- fi
-
-fi
-
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
-mingw=false
-case "$(uname)" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
- if [ -z "$JAVA_HOME" ]; then
- if [ -x "/usr/libexec/java_home" ]; then
- JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
- else
- JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
- fi
- fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=$(java-config --jre-home)
- fi
-fi
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
-fi
-
-# For Mingw, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
- JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="$(which javac)"
- if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=$(which readlink)
- if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
- if $darwin ; then
- javaHome="$(dirname "\"$javaExecutable\"")"
- javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
- else
- javaExecutable="$(readlink -f "\"$javaExecutable\"")"
- fi
- javaHome="$(dirname "\"$javaExecutable\"")"
- javaHome=$(expr "$javaHome" : '\(.*\)/bin')
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
-
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- else
- JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
- fi
-fi
-
-if [ ! -x "$JAVACMD" ] ; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
-
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
-fi
-
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
- if [ -z "$1" ]
- then
- echo "Path not specified to find_maven_basedir"
- return 1
- fi
-
- basedir="$1"
- wdir="$1"
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
- basedir=$wdir
- break
- fi
- # workaround for JBEAP-8937 (on Solaris 10/Sparc)
- if [ -d "${wdir}" ]; then
- wdir=$(cd "$wdir/.." || exit 1; pwd)
- fi
- # end of workaround
- done
- printf '%s' "$(cd "$basedir" || exit 1; pwd)"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- # Remove \r in case we run on Windows within Git Bash
- # and check out the repository with auto CRLF management
- # enabled. Otherwise, we may read lines that are delimited with
- # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
- # splitting rules.
- tr -s '\r\n' ' ' < "$1"
- fi
-}
-
-log() {
- if [ "$MVNW_VERBOSE" = true ]; then
- printf '%s\n' "$1"
- fi
-}
-
-BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
-if [ -z "$BASE_DIR" ]; then
- exit 1;
-fi
-
-MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
-log "$MAVEN_PROJECTBASEDIR"
-
-##########################################################################################
-# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-# This allows using the maven wrapper in projects that prohibit checking in binary data.
-##########################################################################################
-wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
-if [ -r "$wrapperJarPath" ]; then
- log "Found $wrapperJarPath"
-else
- log "Couldn't find $wrapperJarPath, downloading it ..."
-
- if [ -n "$MVNW_REPOURL" ]; then
- wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- else
- wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- fi
- while IFS="=" read -r key value; do
- # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
- safeValue=$(echo "$value" | tr -d '\r')
- case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
- esac
- done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
- log "Downloading from: $wrapperUrl"
-
- if $cygwin; then
- wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
- fi
-
- if command -v wget > /dev/null; then
- log "Found wget ... using wget"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- else
- wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- fi
- elif command -v curl > /dev/null; then
- log "Found curl ... using curl"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- else
- curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- fi
- else
- log "Falling back to using Java to download"
- javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
- javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
- # For Cygwin, switch paths to Windows format before running javac
- if $cygwin; then
- javaSource=$(cygpath --path --windows "$javaSource")
- javaClass=$(cygpath --path --windows "$javaClass")
- fi
- if [ -e "$javaSource" ]; then
- if [ ! -e "$javaClass" ]; then
- log " - Compiling MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/javac" "$javaSource")
- fi
- if [ -e "$javaClass" ]; then
- log " - Running MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
- fi
- fi
- fi
-fi
-##########################################################################################
-# End of extension
-##########################################################################################
-
-# If specified, validate the SHA-256 sum of the Maven wrapper jar file
-wrapperSha256Sum=""
-while IFS="=" read -r key value; do
- case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
- esac
-done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
-if [ -n "$wrapperSha256Sum" ]; then
- wrapperSha256Result=false
- if command -v sha256sum > /dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- elif command -v shasum > /dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- else
- echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
- echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
- exit 1
- fi
- if [ $wrapperSha256Result = false ]; then
- echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
- echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
- echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
- exit 1
- fi
-fi
-
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
- [ -n "$MAVEN_PROJECTBASEDIR" ] &&
- MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
-fi
-
-# Provide a "standardized" way to retrieve the CLI args that will
-# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
-export MAVEN_CMD_LINE_ARGS
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-# shellcheck disable=SC2086 # safe args
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- $MAVEN_DEBUG_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/mvnw.cmd b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/mvnw.cmd
deleted file mode 100644
index 95ba6f5..0000000
--- a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/mvnw.cmd
+++ /dev/null
@@ -1,205 +0,0 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM https://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.2.0
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM set title of command window
-title %0
-@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
-if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
-
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
-)
-
-@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
-if exist %WRAPPER_JAR% (
- if "%MVNW_VERBOSE%" == "true" (
- echo Found %WRAPPER_JAR%
- )
-) else (
- if not "%MVNW_REPOURL%" == "" (
- SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- )
- if "%MVNW_VERBOSE%" == "true" (
- echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %WRAPPER_URL%
- )
-
- powershell -Command "&{"^
- "$webclient = new-object System.Net.WebClient;"^
- "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
- "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
- "}"^
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
- "}"
- if "%MVNW_VERBOSE%" == "true" (
- echo Finished downloading %WRAPPER_JAR%
- )
-)
-@REM End of extension
-
-@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
-SET WRAPPER_SHA_256_SUM=""
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
-)
-IF NOT %WRAPPER_SHA_256_SUM%=="" (
- powershell -Command "&{"^
- "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
- "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
- " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
- " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
- " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
- " exit 1;"^
- "}"^
- "}"
- if ERRORLEVEL 1 goto error
-)
-
-@REM Provide a "standardized" way to retrieve the CLI args that will
-@REM work with both Windows and non-Windows executions.
-set MAVEN_CMD_LINE_ARGS=%*
-
-%MAVEN_JAVA_EXE% ^
- %JVM_CONFIG_MAVEN_PROPS% ^
- %MAVEN_OPTS% ^
- %MAVEN_DEBUG_OPTS% ^
- -classpath %WRAPPER_JAR% ^
- "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
- %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
-if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%"=="on" pause
-
-if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
-
-cmd /C exit /B %ERROR_CODE%
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/pom.xml b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/pom.xml
deleted file mode 100644
index 8d29be6..0000000
--- a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.1.1
-
-
- com.pingcap
- TiDBSpringBootJPAServerlessExample
- 0.0.1-SNAPSHOT
- TiDBSpringBootJPAServerlessExample
- TiDBSpringBootJPAServerlessExample
-
- 17
-
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- com.mysql
- mysql-connector-j
- runtime
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/main/java/com/pingcap/example/HelloWorldController.java b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/main/java/com/pingcap/example/HelloWorldController.java
deleted file mode 100644
index 7169490..0000000
--- a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/main/java/com/pingcap/example/HelloWorldController.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2022 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.pingcap.example;
-
-import jakarta.persistence.EntityManager;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * HelloWorldController
- *
- * @author Icemap
- * @date 2023/7/12
- */
-@RestController
-@RequestMapping
-public class HelloWorldController {
- @Autowired
- private EntityManager entityManager;
-
- @GetMapping("/hello")
- public Object hello() {
- return entityManager
- .createNativeQuery("SELECT 'Hello World'")
- .getSingleResult();
- }
-}
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/main/java/com/pingcap/example/TiDBSpringBootJpaServerlessExampleApplication.java b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/main/java/com/pingcap/example/TiDBSpringBootJpaServerlessExampleApplication.java
deleted file mode 100644
index eaa14b0..0000000
--- a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/main/java/com/pingcap/example/TiDBSpringBootJpaServerlessExampleApplication.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.pingcap.example;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class TiDBSpringBootJpaServerlessExampleApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(TiDBSpringBootJpaServerlessExampleApplication.class, args);
- }
-
-}
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/main/resources/application.yaml b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/main/resources/application.yaml
deleted file mode 100644
index 57d1397..0000000
--- a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/main/resources/application.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-spring:
- datasource:
- url: jdbc:mysql://${host}:4000/test?sslMode=VERIFY_IDENTITY&enabledTLSProtocols=TLSv1.2,TLSv1.3
- username: ${user}
- password: ${password}
- driver-class-name: com.mysql.cj.jdbc.Driver
- jpa:
- show-sql: true
- database-platform: org.hibernate.dialect.TiDBDialect
\ No newline at end of file
diff --git a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/test/java/com/pingcap/example/TiDBSpringBootJpaServerlessExampleApplicationTests.java b/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/test/java/com/pingcap/example/TiDBSpringBootJpaServerlessExampleApplicationTests.java
deleted file mode 100644
index fad15b1..0000000
--- a/hello-world-apps/SpringBoot-JPA/serverless/TiDBSpringBootJPAServerlessExample/src/test/java/com/pingcap/example/TiDBSpringBootJpaServerlessExampleApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.pingcap.example;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class TiDBSpringBootJpaServerlessExampleApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/.gitignore b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/.gitignore
deleted file mode 100644
index 549e00a..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### VS Code ###
-.vscode/
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/.mvn/wrapper/maven-wrapper.jar b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/.mvn/wrapper/maven-wrapper.jar
deleted file mode 100644
index cb28b0e..0000000
Binary files a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/.mvn/wrapper/maven-wrapper.jar and /dev/null differ
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/.mvn/wrapper/maven-wrapper.properties b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/.mvn/wrapper/maven-wrapper.properties
deleted file mode 100644
index 462686e..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/.mvn/wrapper/maven-wrapper.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/mvnw b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/mvnw
deleted file mode 100755
index 66df285..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/mvnw
+++ /dev/null
@@ -1,308 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.2.0
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
-#
-# Optional ENV vars
-# -----------------
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-# ----------------------------------------------------------------------------
-
-if [ -z "$MAVEN_SKIP_RC" ] ; then
-
- if [ -f /usr/local/etc/mavenrc ] ; then
- . /usr/local/etc/mavenrc
- fi
-
- if [ -f /etc/mavenrc ] ; then
- . /etc/mavenrc
- fi
-
- if [ -f "$HOME/.mavenrc" ] ; then
- . "$HOME/.mavenrc"
- fi
-
-fi
-
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
-mingw=false
-case "$(uname)" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
- if [ -z "$JAVA_HOME" ]; then
- if [ -x "/usr/libexec/java_home" ]; then
- JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
- else
- JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
- fi
- fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=$(java-config --jre-home)
- fi
-fi
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
-fi
-
-# For Mingw, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
- JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="$(which javac)"
- if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=$(which readlink)
- if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
- if $darwin ; then
- javaHome="$(dirname "\"$javaExecutable\"")"
- javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
- else
- javaExecutable="$(readlink -f "\"$javaExecutable\"")"
- fi
- javaHome="$(dirname "\"$javaExecutable\"")"
- javaHome=$(expr "$javaHome" : '\(.*\)/bin')
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
-
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- else
- JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
- fi
-fi
-
-if [ ! -x "$JAVACMD" ] ; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
-
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
-fi
-
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
- if [ -z "$1" ]
- then
- echo "Path not specified to find_maven_basedir"
- return 1
- fi
-
- basedir="$1"
- wdir="$1"
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
- basedir=$wdir
- break
- fi
- # workaround for JBEAP-8937 (on Solaris 10/Sparc)
- if [ -d "${wdir}" ]; then
- wdir=$(cd "$wdir/.." || exit 1; pwd)
- fi
- # end of workaround
- done
- printf '%s' "$(cd "$basedir" || exit 1; pwd)"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- # Remove \r in case we run on Windows within Git Bash
- # and check out the repository with auto CRLF management
- # enabled. Otherwise, we may read lines that are delimited with
- # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
- # splitting rules.
- tr -s '\r\n' ' ' < "$1"
- fi
-}
-
-log() {
- if [ "$MVNW_VERBOSE" = true ]; then
- printf '%s\n' "$1"
- fi
-}
-
-BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
-if [ -z "$BASE_DIR" ]; then
- exit 1;
-fi
-
-MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
-log "$MAVEN_PROJECTBASEDIR"
-
-##########################################################################################
-# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-# This allows using the maven wrapper in projects that prohibit checking in binary data.
-##########################################################################################
-wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
-if [ -r "$wrapperJarPath" ]; then
- log "Found $wrapperJarPath"
-else
- log "Couldn't find $wrapperJarPath, downloading it ..."
-
- if [ -n "$MVNW_REPOURL" ]; then
- wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- else
- wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- fi
- while IFS="=" read -r key value; do
- # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
- safeValue=$(echo "$value" | tr -d '\r')
- case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
- esac
- done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
- log "Downloading from: $wrapperUrl"
-
- if $cygwin; then
- wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
- fi
-
- if command -v wget > /dev/null; then
- log "Found wget ... using wget"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- else
- wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- fi
- elif command -v curl > /dev/null; then
- log "Found curl ... using curl"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- else
- curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- fi
- else
- log "Falling back to using Java to download"
- javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
- javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
- # For Cygwin, switch paths to Windows format before running javac
- if $cygwin; then
- javaSource=$(cygpath --path --windows "$javaSource")
- javaClass=$(cygpath --path --windows "$javaClass")
- fi
- if [ -e "$javaSource" ]; then
- if [ ! -e "$javaClass" ]; then
- log " - Compiling MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/javac" "$javaSource")
- fi
- if [ -e "$javaClass" ]; then
- log " - Running MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
- fi
- fi
- fi
-fi
-##########################################################################################
-# End of extension
-##########################################################################################
-
-# If specified, validate the SHA-256 sum of the Maven wrapper jar file
-wrapperSha256Sum=""
-while IFS="=" read -r key value; do
- case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
- esac
-done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
-if [ -n "$wrapperSha256Sum" ]; then
- wrapperSha256Result=false
- if command -v sha256sum > /dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- elif command -v shasum > /dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- else
- echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
- echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
- exit 1
- fi
- if [ $wrapperSha256Result = false ]; then
- echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
- echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
- echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
- exit 1
- fi
-fi
-
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
- [ -n "$MAVEN_PROJECTBASEDIR" ] &&
- MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
-fi
-
-# Provide a "standardized" way to retrieve the CLI args that will
-# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
-export MAVEN_CMD_LINE_ARGS
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-# shellcheck disable=SC2086 # safe args
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- $MAVEN_DEBUG_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/mvnw.cmd b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/mvnw.cmd
deleted file mode 100644
index 95ba6f5..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/mvnw.cmd
+++ /dev/null
@@ -1,205 +0,0 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM https://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.2.0
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM set title of command window
-title %0
-@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
-if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
-
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
-)
-
-@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
-if exist %WRAPPER_JAR% (
- if "%MVNW_VERBOSE%" == "true" (
- echo Found %WRAPPER_JAR%
- )
-) else (
- if not "%MVNW_REPOURL%" == "" (
- SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- )
- if "%MVNW_VERBOSE%" == "true" (
- echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %WRAPPER_URL%
- )
-
- powershell -Command "&{"^
- "$webclient = new-object System.Net.WebClient;"^
- "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
- "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
- "}"^
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
- "}"
- if "%MVNW_VERBOSE%" == "true" (
- echo Finished downloading %WRAPPER_JAR%
- )
-)
-@REM End of extension
-
-@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
-SET WRAPPER_SHA_256_SUM=""
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
-)
-IF NOT %WRAPPER_SHA_256_SUM%=="" (
- powershell -Command "&{"^
- "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
- "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
- " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
- " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
- " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
- " exit 1;"^
- "}"^
- "}"
- if ERRORLEVEL 1 goto error
-)
-
-@REM Provide a "standardized" way to retrieve the CLI args that will
-@REM work with both Windows and non-Windows executions.
-set MAVEN_CMD_LINE_ARGS=%*
-
-%MAVEN_JAVA_EXE% ^
- %JVM_CONFIG_MAVEN_PROPS% ^
- %MAVEN_OPTS% ^
- %MAVEN_DEBUG_OPTS% ^
- -classpath %WRAPPER_JAR% ^
- "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
- %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
-if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%"=="on" pause
-
-if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
-
-cmd /C exit /B %ERROR_CODE%
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/pom.xml b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/pom.xml
deleted file mode 100644
index e64cb3d..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.1.1
-
-
- com.pingcap
- TiDBSpringBootMyBatisNormalExample
- 0.0.1-SNAPSHOT
- TiDBSpringBootMyBatisNormalExample
- TiDBSpringBootMyBatisNormalExample
-
- 17
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.mybatis.spring.boot
- mybatis-spring-boot-starter
- 3.0.2
-
-
-
- com.mysql
- mysql-connector-j
- runtime
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.mybatis.spring.boot
- mybatis-spring-boot-starter-test
- 3.0.2
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/java/com/pingcap/example/HelloWorldController.java b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/java/com/pingcap/example/HelloWorldController.java
deleted file mode 100644
index 349fb61..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/java/com/pingcap/example/HelloWorldController.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2022 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.pingcap.example;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * HelloWorldController
- *
- * @author Icemap
- * @date 2023/7/12
- */
-@RestController
-@RequestMapping
-public class HelloWorldController {
- @Autowired
- private HelloWorldMapper helloWorldMapper;
-
- @GetMapping("/hello")
- public Object hello() {
- return helloWorldMapper.getHelloWorld();
- }
-}
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/java/com/pingcap/example/HelloWorldMapper.java b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/java/com/pingcap/example/HelloWorldMapper.java
deleted file mode 100644
index 475a2b0..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/java/com/pingcap/example/HelloWorldMapper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2022 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.pingcap.example;
-
-import org.apache.ibatis.annotations.Select;
-import org.springframework.stereotype.Repository;
-
-/**
- * HelloWorldMapper
- *
- * @author Icemap
- * @date 2023/7/12
- */
-@Repository
-public interface HelloWorldMapper {
- @Select("SELECT 'Hello World'")
- String getHelloWorld();
-}
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/java/com/pingcap/example/TiDBSpringBootMyBatisNormalExampleApplication.java b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/java/com/pingcap/example/TiDBSpringBootMyBatisNormalExampleApplication.java
deleted file mode 100644
index 1ca596f..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/java/com/pingcap/example/TiDBSpringBootMyBatisNormalExampleApplication.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.pingcap.example;
-
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-@MapperScan("com.pingcap.example")
-public class TiDBSpringBootMyBatisNormalExampleApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(TiDBSpringBootMyBatisNormalExampleApplication.class, args);
- }
-
-}
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/resources/application.yaml b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/resources/application.yaml
deleted file mode 100644
index b5d18cb..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/main/resources/application.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-spring:
- datasource:
- url: jdbc:mysql://localhost:4000/test
- username: root
- # password: xxx
- driver-class-name: com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/test/java/com/pingcap/example/TiDBSpringBootMyBatisNormalExampleApplicationTests.java b/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/test/java/com/pingcap/example/TiDBSpringBootMyBatisNormalExampleApplicationTests.java
deleted file mode 100644
index 00ba880..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/normal/TiDBSpringBootMyBatisNormalExample/src/test/java/com/pingcap/example/TiDBSpringBootMyBatisNormalExampleApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.pingcap.example;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class TiDBSpringBootMyBatisNormalExampleApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/.gitignore b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/.gitignore
deleted file mode 100644
index 549e00a..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### VS Code ###
-.vscode/
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/.mvn/wrapper/maven-wrapper.jar b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/.mvn/wrapper/maven-wrapper.jar
deleted file mode 100644
index cb28b0e..0000000
Binary files a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/.mvn/wrapper/maven-wrapper.jar and /dev/null differ
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/.mvn/wrapper/maven-wrapper.properties b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/.mvn/wrapper/maven-wrapper.properties
deleted file mode 100644
index 462686e..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/.mvn/wrapper/maven-wrapper.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/mvnw b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/mvnw
deleted file mode 100755
index 66df285..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/mvnw
+++ /dev/null
@@ -1,308 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.2.0
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
-#
-# Optional ENV vars
-# -----------------
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-# ----------------------------------------------------------------------------
-
-if [ -z "$MAVEN_SKIP_RC" ] ; then
-
- if [ -f /usr/local/etc/mavenrc ] ; then
- . /usr/local/etc/mavenrc
- fi
-
- if [ -f /etc/mavenrc ] ; then
- . /etc/mavenrc
- fi
-
- if [ -f "$HOME/.mavenrc" ] ; then
- . "$HOME/.mavenrc"
- fi
-
-fi
-
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
-mingw=false
-case "$(uname)" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
- if [ -z "$JAVA_HOME" ]; then
- if [ -x "/usr/libexec/java_home" ]; then
- JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
- else
- JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
- fi
- fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=$(java-config --jre-home)
- fi
-fi
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
-fi
-
-# For Mingw, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
- JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="$(which javac)"
- if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=$(which readlink)
- if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
- if $darwin ; then
- javaHome="$(dirname "\"$javaExecutable\"")"
- javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
- else
- javaExecutable="$(readlink -f "\"$javaExecutable\"")"
- fi
- javaHome="$(dirname "\"$javaExecutable\"")"
- javaHome=$(expr "$javaHome" : '\(.*\)/bin')
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
-
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- else
- JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
- fi
-fi
-
-if [ ! -x "$JAVACMD" ] ; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
-
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
-fi
-
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
- if [ -z "$1" ]
- then
- echo "Path not specified to find_maven_basedir"
- return 1
- fi
-
- basedir="$1"
- wdir="$1"
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
- basedir=$wdir
- break
- fi
- # workaround for JBEAP-8937 (on Solaris 10/Sparc)
- if [ -d "${wdir}" ]; then
- wdir=$(cd "$wdir/.." || exit 1; pwd)
- fi
- # end of workaround
- done
- printf '%s' "$(cd "$basedir" || exit 1; pwd)"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- # Remove \r in case we run on Windows within Git Bash
- # and check out the repository with auto CRLF management
- # enabled. Otherwise, we may read lines that are delimited with
- # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
- # splitting rules.
- tr -s '\r\n' ' ' < "$1"
- fi
-}
-
-log() {
- if [ "$MVNW_VERBOSE" = true ]; then
- printf '%s\n' "$1"
- fi
-}
-
-BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
-if [ -z "$BASE_DIR" ]; then
- exit 1;
-fi
-
-MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
-log "$MAVEN_PROJECTBASEDIR"
-
-##########################################################################################
-# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-# This allows using the maven wrapper in projects that prohibit checking in binary data.
-##########################################################################################
-wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
-if [ -r "$wrapperJarPath" ]; then
- log "Found $wrapperJarPath"
-else
- log "Couldn't find $wrapperJarPath, downloading it ..."
-
- if [ -n "$MVNW_REPOURL" ]; then
- wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- else
- wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- fi
- while IFS="=" read -r key value; do
- # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
- safeValue=$(echo "$value" | tr -d '\r')
- case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
- esac
- done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
- log "Downloading from: $wrapperUrl"
-
- if $cygwin; then
- wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
- fi
-
- if command -v wget > /dev/null; then
- log "Found wget ... using wget"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- else
- wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- fi
- elif command -v curl > /dev/null; then
- log "Found curl ... using curl"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- else
- curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- fi
- else
- log "Falling back to using Java to download"
- javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
- javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
- # For Cygwin, switch paths to Windows format before running javac
- if $cygwin; then
- javaSource=$(cygpath --path --windows "$javaSource")
- javaClass=$(cygpath --path --windows "$javaClass")
- fi
- if [ -e "$javaSource" ]; then
- if [ ! -e "$javaClass" ]; then
- log " - Compiling MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/javac" "$javaSource")
- fi
- if [ -e "$javaClass" ]; then
- log " - Running MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
- fi
- fi
- fi
-fi
-##########################################################################################
-# End of extension
-##########################################################################################
-
-# If specified, validate the SHA-256 sum of the Maven wrapper jar file
-wrapperSha256Sum=""
-while IFS="=" read -r key value; do
- case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
- esac
-done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
-if [ -n "$wrapperSha256Sum" ]; then
- wrapperSha256Result=false
- if command -v sha256sum > /dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- elif command -v shasum > /dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- else
- echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
- echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
- exit 1
- fi
- if [ $wrapperSha256Result = false ]; then
- echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
- echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
- echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
- exit 1
- fi
-fi
-
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
- [ -n "$MAVEN_PROJECTBASEDIR" ] &&
- MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
-fi
-
-# Provide a "standardized" way to retrieve the CLI args that will
-# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
-export MAVEN_CMD_LINE_ARGS
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-# shellcheck disable=SC2086 # safe args
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- $MAVEN_DEBUG_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/mvnw.cmd b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/mvnw.cmd
deleted file mode 100644
index 95ba6f5..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/mvnw.cmd
+++ /dev/null
@@ -1,205 +0,0 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM https://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.2.0
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM set title of command window
-title %0
-@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
-if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
-
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
-)
-
-@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
-if exist %WRAPPER_JAR% (
- if "%MVNW_VERBOSE%" == "true" (
- echo Found %WRAPPER_JAR%
- )
-) else (
- if not "%MVNW_REPOURL%" == "" (
- SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
- )
- if "%MVNW_VERBOSE%" == "true" (
- echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %WRAPPER_URL%
- )
-
- powershell -Command "&{"^
- "$webclient = new-object System.Net.WebClient;"^
- "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
- "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
- "}"^
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
- "}"
- if "%MVNW_VERBOSE%" == "true" (
- echo Finished downloading %WRAPPER_JAR%
- )
-)
-@REM End of extension
-
-@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
-SET WRAPPER_SHA_256_SUM=""
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
-)
-IF NOT %WRAPPER_SHA_256_SUM%=="" (
- powershell -Command "&{"^
- "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
- "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
- " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
- " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
- " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
- " exit 1;"^
- "}"^
- "}"
- if ERRORLEVEL 1 goto error
-)
-
-@REM Provide a "standardized" way to retrieve the CLI args that will
-@REM work with both Windows and non-Windows executions.
-set MAVEN_CMD_LINE_ARGS=%*
-
-%MAVEN_JAVA_EXE% ^
- %JVM_CONFIG_MAVEN_PROPS% ^
- %MAVEN_OPTS% ^
- %MAVEN_DEBUG_OPTS% ^
- -classpath %WRAPPER_JAR% ^
- "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
- %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
-if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%"=="on" pause
-
-if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
-
-cmd /C exit /B %ERROR_CODE%
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/pom.xml b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/pom.xml
deleted file mode 100644
index 708c665..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.1.1
-
-
- com.pingcap
- TiDBSpringBootMyBatisServerlessExample
- 0.0.1-SNAPSHOT
- TiDBSpringBootMyBatisServerlessExample
- TiDBSpringBootMyBatisServerlessExample
-
- 17
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.mybatis.spring.boot
- mybatis-spring-boot-starter
- 3.0.2
-
-
-
- com.mysql
- mysql-connector-j
- runtime
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.mybatis.spring.boot
- mybatis-spring-boot-starter-test
- 3.0.2
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/java/com/pingcap/example/HelloWorldController.java b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/java/com/pingcap/example/HelloWorldController.java
deleted file mode 100644
index 349fb61..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/java/com/pingcap/example/HelloWorldController.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2022 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.pingcap.example;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * HelloWorldController
- *
- * @author Icemap
- * @date 2023/7/12
- */
-@RestController
-@RequestMapping
-public class HelloWorldController {
- @Autowired
- private HelloWorldMapper helloWorldMapper;
-
- @GetMapping("/hello")
- public Object hello() {
- return helloWorldMapper.getHelloWorld();
- }
-}
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/java/com/pingcap/example/HelloWorldMapper.java b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/java/com/pingcap/example/HelloWorldMapper.java
deleted file mode 100644
index 475a2b0..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/java/com/pingcap/example/HelloWorldMapper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2022 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.pingcap.example;
-
-import org.apache.ibatis.annotations.Select;
-import org.springframework.stereotype.Repository;
-
-/**
- * HelloWorldMapper
- *
- * @author Icemap
- * @date 2023/7/12
- */
-@Repository
-public interface HelloWorldMapper {
- @Select("SELECT 'Hello World'")
- String getHelloWorld();
-}
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/java/com/pingcap/example/TiDBSpringBootMyBatisServerlessExampleApplication.java b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/java/com/pingcap/example/TiDBSpringBootMyBatisServerlessExampleApplication.java
deleted file mode 100644
index de71d61..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/java/com/pingcap/example/TiDBSpringBootMyBatisServerlessExampleApplication.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.pingcap.example;
-
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-@MapperScan("com.pingcap.example")
-public class TiDBSpringBootMyBatisServerlessExampleApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(TiDBSpringBootMyBatisServerlessExampleApplication.class, args);
- }
-
-}
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/resources/application.yaml b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/resources/application.yaml
deleted file mode 100644
index 7ff9a57..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/main/resources/application.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-spring:
- datasource:
- url: jdbc:mysql://${host}:4000/test?sslMode=VERIFY_IDENTITY&enabledTLSProtocols=TLSv1.2,TLSv1.3
- username: ${user}
- password: ${password}
- driver-class-name: com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/test/java/com/pingcap/example/TiDBSpringBootMyBatisServerlessExampleApplicationTests.java b/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/test/java/com/pingcap/example/TiDBSpringBootMyBatisServerlessExampleApplicationTests.java
deleted file mode 100644
index 3f0232e..0000000
--- a/hello-world-apps/SpringBoot-MyBatis/serverless/TiDBSpringBootMyBatisServerlessExample/src/test/java/com/pingcap/example/TiDBSpringBootMyBatisServerlessExampleApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.pingcap.example;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class TiDBSpringBootMyBatisServerlessExampleApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
diff --git a/plain-java-batch-delete/Makefile b/plain-java-batch-delete/Makefile
index 4204b2b..36a73ba 100644
--- a/plain-java-batch-delete/Makefile
+++ b/plain-java-batch-delete/Makefile
@@ -15,13 +15,13 @@
.PHONY: all prepare build run
all:
- make prepare build run
+ . ../env.sh && make prepare build run
prepare:
- tiup demo bookshop prepare --drop-tables
+ tiup demo bookshop prepare -D $(TIDB_DB_NAME) -H $(TIDB_HOST) -P $(TIDB_PORT) -U $(TIDB_USER) -p $(TIDB_PASSWORD) --authors 100 --books 1000 --orders 11451 --users 1000 --ratings 11451 --drop-tables
build:
mvn clean package
run:
- java -jar target/plain-java-batch-delete-0.0.1-jar-with-dependencies.jar
\ No newline at end of file
+ java -jar target/plain-java-batch-delete-jar-with-dependencies.jar
\ No newline at end of file
diff --git a/plain-java-batch-delete/pom.xml b/plain-java-batch-delete/pom.xml
index cb0601b..19e35e9 100644
--- a/plain-java-batch-delete/pom.xml
+++ b/plain-java-batch-delete/pom.xml
@@ -33,6 +33,7 @@
+ ${project.name}
org.apache.maven.plugins
diff --git a/plain-java-batch-delete/src/main/java/com/pingcap/bulkDelete/BatchDeleteExample.java b/plain-java-batch-delete/src/main/java/com/pingcap/bulkDelete/BatchDeleteExample.java
index 9d31dfe..b57e1e5 100644
--- a/plain-java-batch-delete/src/main/java/com/pingcap/bulkDelete/BatchDeleteExample.java
+++ b/plain-java-batch-delete/src/main/java/com/pingcap/bulkDelete/BatchDeleteExample.java
@@ -14,6 +14,7 @@
package com.pingcap.bulkDelete;
+import com.mysql.cj.conf.PropertyDefinitions;
import com.mysql.cj.jdbc.MysqlDataSource;
import java.sql.Connection;
@@ -25,18 +26,9 @@
public class BatchDeleteExample
{
- public static void main(String[] args) throws InterruptedException {
- // Configure the example database connection.
-
+ public static void main(String[] args) throws SQLException {
// Create a mysql data source instance.
- MysqlDataSource mysqlDataSource = new MysqlDataSource();
-
- // Set server name, port, database name, username and password.
- mysqlDataSource.setServerName("localhost");
- mysqlDataSource.setPortNumber(4000);
- mysqlDataSource.setDatabaseName("bookshop");
- mysqlDataSource.setUser("root");
- mysqlDataSource.setPassword("");
+ MysqlDataSource mysqlDataSource = getMysqlDataSourceByEnv();
Integer updateCount;
do {
@@ -46,7 +38,7 @@ public static void main(String[] args) throws InterruptedException {
public static Integer batchDelete (MysqlDataSource ds) {
try (Connection connection = ds.getConnection()) {
- String sql = "DELETE FROM `bookshop`.`ratings` WHERE `rated_at` >= ? AND `rated_at` <= ? LIMIT 1000";
+ String sql = "DELETE FROM `ratings` WHERE `rated_at` >= ? AND `rated_at` <= ? LIMIT 1000";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MILLISECOND, 0);
@@ -67,4 +59,33 @@ public static Integer batchDelete (MysqlDataSource ds) {
return -1;
}
+
+ private static MysqlDataSource getMysqlDataSourceByEnv() throws SQLException {
+ // 1.1 Create a mysql data source instance.
+ MysqlDataSource mysqlDataSource = new MysqlDataSource();
+
+ // 1.2 Get parameters from environment variables.
+ String tidbHost = System.getenv().getOrDefault("TIDB_HOST", "localhost");
+ int tidbPort = Integer.parseInt(System.getenv().getOrDefault("TIDB_PORT", "4000"));
+ String tidbUser = System.getenv().getOrDefault("TIDB_USER", "root");
+ String tidbPassword = System.getenv().getOrDefault("TIDB_PASSWORD", "");
+ String tidbDatabase = System.getenv().getOrDefault("TIDB_DATABASE", "test");
+ boolean useSSL = Boolean.parseBoolean(System.getenv().getOrDefault("USE_SSL", "false"));
+
+ // 1.3 Set server name, port, database name, username and password.
+ mysqlDataSource.setServerName(tidbHost);
+ mysqlDataSource.setPortNumber(tidbPort);
+ mysqlDataSource.setUser(tidbUser);
+ mysqlDataSource.setPassword(tidbPassword);
+ mysqlDataSource.setDatabaseName(tidbDatabase);
+ if (useSSL) {
+ mysqlDataSource.setSslMode(PropertyDefinitions.SslMode.VERIFY_IDENTITY.name());
+ mysqlDataSource.setEnabledTLSProtocols("TLSv1.2,TLSv1.3");
+ }
+
+ // Or you can use jdbc string instead.
+ // mysqlDataSource.setURL("jdbc:mysql://{host}:{port}/test?user={user}&password={password}");
+
+ return mysqlDataSource;
+ }
}
diff --git a/plain-java-batch-update/Makefile b/plain-java-batch-update/Makefile
index c02be43..4b723b2 100644
--- a/plain-java-batch-update/Makefile
+++ b/plain-java-batch-update/Makefile
@@ -15,14 +15,13 @@
.PHONY: all prepare build run
all:
- make prepare build run
+ . ../env.sh && make prepare build run
prepare:
- tiup demo bookshop prepare --drop-tables
- mysql --host 127.0.0.1 --port 4000 -u root
+ ${project.name}
org.apache.maven.plugins
diff --git a/plain-java-batch-update/src/main/java/com/pingcap/bulkUpdate/BatchUpdateExample.java b/plain-java-batch-update/src/main/java/com/pingcap/bulkUpdate/BatchUpdateExample.java
index 91454c0..fed159e 100644
--- a/plain-java-batch-update/src/main/java/com/pingcap/bulkUpdate/BatchUpdateExample.java
+++ b/plain-java-batch-update/src/main/java/com/pingcap/bulkUpdate/BatchUpdateExample.java
@@ -14,6 +14,7 @@
package com.pingcap.bulkUpdate;
+import com.mysql.cj.conf.PropertyDefinitions;
import com.mysql.cj.jdbc.MysqlDataSource;
import java.sql.Connection;
@@ -25,50 +26,13 @@
import java.util.concurrent.TimeUnit;
public class BatchUpdateExample {
- static class UpdateID {
- private Long bookID;
- private Long userID;
-
- public UpdateID(Long bookID, Long userID) {
- this.bookID = bookID;
- this.userID = userID;
- }
-
- public Long getBookID() {
- return bookID;
- }
-
- public void setBookID(Long bookID) {
- this.bookID = bookID;
- }
-
- public Long getUserID() {
- return userID;
- }
-
- public void setUserID(Long userID) {
- this.userID = userID;
- }
-
- @Override
- public String toString() {
- return "[bookID] " + bookID + ", [userID] " + userID ;
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
+ public static void main(String[] args) throws InterruptedException, SQLException {
// Configure the example database connection.
// Create a mysql data source instance.
- MysqlDataSource mysqlDataSource = new MysqlDataSource();
-
- // Set server name, port, database name, username and password.
- mysqlDataSource.setServerName("localhost");
- mysqlDataSource.setPortNumber(4000);
- mysqlDataSource.setDatabaseName("bookshop");
- mysqlDataSource.setUser("root");
- mysqlDataSource.setPassword("");
+ MysqlDataSource mysqlDataSource = getMysqlDataSourceByEnv();
+ addAttrTenPoint(mysqlDataSource);
UpdateID lastID = batchUpdate(mysqlDataSource, null);
System.out.println("first time batch update success");
@@ -79,7 +43,13 @@ public static void main(String[] args) throws InterruptedException {
}
}
- public static UpdateID batchUpdate (MysqlDataSource ds, UpdateID lastID) {
+ public static void addAttrTenPoint(MysqlDataSource ds) throws SQLException {
+ try (Connection connection = ds.getConnection()) {
+ connection.createStatement().executeUpdate(
+ "ALTER TABLE `ratings` ADD COLUMN `ten_point` BOOL NOT NULL DEFAULT FALSE");
+ }
+ }
+ public static UpdateID batchUpdate (MysqlDataSource ds, UpdateID lastID) throws SQLException {
try (Connection connection = ds.getConnection()) {
UpdateID updateID = null;
@@ -87,11 +57,11 @@ public static UpdateID batchUpdate (MysqlDataSource ds, UpdateID lastID) {
if (lastID == null) {
selectPs = connection.prepareStatement(
- "SELECT `book_id`, `user_id` FROM `bookshop`.`ratings` " +
+ "SELECT `book_id`, `user_id` FROM `ratings` " +
"WHERE `ten_point` != true ORDER BY `book_id`, `user_id` LIMIT 1000");
} else {
selectPs = connection.prepareStatement(
- "SELECT `book_id`, `user_id` FROM `bookshop`.`ratings` "+
+ "SELECT `book_id`, `user_id` FROM `ratings` "+
"WHERE `ten_point` != true AND `book_id` > ? AND `user_id` > ? "+
"ORDER BY `book_id`, `user_id` LIMIT 1000");
@@ -115,7 +85,7 @@ public static UpdateID batchUpdate (MysqlDataSource ds, UpdateID lastID) {
return null;
}
- String updateSQL = "UPDATE `bookshop`.`ratings` SET `ten_point` = true, "+
+ String updateSQL = "UPDATE `ratings` SET `ten_point` = true, "+
"`score` = `score` * 2 WHERE (`book_id`, `user_id`) IN (" +
placeHolder(idList.size() / 2) + ")";
PreparedStatement updatePs = connection.prepareStatement(updateSQL);
@@ -126,11 +96,7 @@ public static UpdateID batchUpdate (MysqlDataSource ds, UpdateID lastID) {
System.out.println("update " + count + " data");
return updateID;
- } catch (SQLException e) {
- e.printStackTrace();
}
-
- return null;
}
public static String placeHolder(int n) {
@@ -141,4 +107,33 @@ public static String placeHolder(int n) {
return sb.toString();
}
+
+ private static MysqlDataSource getMysqlDataSourceByEnv() throws SQLException {
+ // 1.1 Create a mysql data source instance.
+ MysqlDataSource mysqlDataSource = new MysqlDataSource();
+
+ // 1.2 Get parameters from environment variables.
+ String tidbHost = System.getenv().getOrDefault("TIDB_HOST", "localhost");
+ int tidbPort = Integer.parseInt(System.getenv().getOrDefault("TIDB_PORT", "4000"));
+ String tidbUser = System.getenv().getOrDefault("TIDB_USER", "root");
+ String tidbPassword = System.getenv().getOrDefault("TIDB_PASSWORD", "");
+ String tidbDatabase = System.getenv().getOrDefault("TIDB_DATABASE", "test");
+ boolean useSSL = Boolean.parseBoolean(System.getenv().getOrDefault("USE_SSL", "false"));
+
+ // 1.3 Set server name, port, database name, username and password.
+ mysqlDataSource.setServerName(tidbHost);
+ mysqlDataSource.setPortNumber(tidbPort);
+ mysqlDataSource.setUser(tidbUser);
+ mysqlDataSource.setPassword(tidbPassword);
+ mysqlDataSource.setDatabaseName(tidbDatabase);
+ if (useSSL) {
+ mysqlDataSource.setSslMode(PropertyDefinitions.SslMode.VERIFY_IDENTITY.name());
+ mysqlDataSource.setEnabledTLSProtocols("TLSv1.2,TLSv1.3");
+ }
+
+ // Or you can use jdbc string instead.
+ // mysqlDataSource.setURL("jdbc:mysql://{host}:{port}/test?user={user}&password={password}");
+
+ return mysqlDataSource;
+ }
}
diff --git a/plain-java-batch-update/src/main/java/com/pingcap/bulkUpdate/UpdateID.java b/plain-java-batch-update/src/main/java/com/pingcap/bulkUpdate/UpdateID.java
new file mode 100644
index 0000000..4b046c4
--- /dev/null
+++ b/plain-java-batch-update/src/main/java/com/pingcap/bulkUpdate/UpdateID.java
@@ -0,0 +1,52 @@
+// Copyright 2022 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.pingcap.bulkUpdate;
+
+/**
+ * UpdateID
+ *
+ * @author Icemap
+ * @date 2023/8/3
+ */
+public class UpdateID {
+ private Long bookID;
+ private Long userID;
+
+ public UpdateID(Long bookID, Long userID) {
+ this.bookID = bookID;
+ this.userID = userID;
+ }
+
+ public Long getBookID() {
+ return bookID;
+ }
+
+ public void setBookID(Long bookID) {
+ this.bookID = bookID;
+ }
+
+ public Long getUserID() {
+ return userID;
+ }
+
+ public void setUserID(Long userID) {
+ this.userID = userID;
+ }
+
+ @Override
+ public String toString() {
+ return "[bookID] " + bookID + ", [userID] " + userID ;
+ }
+}
\ No newline at end of file
diff --git a/plain-java-hibernate/Makefile b/plain-java-hibernate/Makefile
index 6b34ef6..bf57c8c 100644
--- a/plain-java-hibernate/Makefile
+++ b/plain-java-hibernate/Makefile
@@ -15,10 +15,10 @@
.PHONY: all build run
all:
- make build run
+ . ../env.sh && make build run
build:
mvn clean package
run:
- java -jar target/plain-java-hibernate-0.0.1-jar-with-dependencies.jar
+ java -jar target/plain-java-hibernate-jar-with-dependencies.jar
diff --git a/plain-java-hibernate/pom.xml b/plain-java-hibernate/pom.xml
index 81c67d8..9636ab9 100644
--- a/plain-java-hibernate/pom.xml
+++ b/plain-java-hibernate/pom.xml
@@ -26,17 +26,18 @@
mysql
mysql-connector-java
- 8.0.28
+ 8.0.33
org.hibernate.orm
hibernate-core
- 6.1.6.Final
+ 6.2.3.Final
+ ${project.name}
org.apache.maven.plugins
diff --git a/plain-java-hibernate/src/main/java/com/pingcap/HibernateExample.java b/plain-java-hibernate/src/main/java/com/pingcap/HibernateExample.java
index 1ce0ae3..499a2e0 100644
--- a/plain-java-hibernate/src/main/java/com/pingcap/HibernateExample.java
+++ b/plain-java-hibernate/src/main/java/com/pingcap/HibernateExample.java
@@ -14,10 +14,6 @@
package com.pingcap;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Id;
-import jakarta.persistence.Table;
import org.hibernate.JDBCException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
@@ -29,63 +25,90 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Properties;
import java.util.function.Function;
-@Entity
-@Table(name = "player_hibernate")
-class PlayerBean {
- @Id
- private String id;
- @Column(name = "coins")
- private Integer coins;
- @Column(name = "goods")
- private Integer goods;
-
- public PlayerBean() {
- }
- public PlayerBean(String id, Integer coins, Integer goods) {
- this.id = id;
- this.coins = coins;
- this.goods = goods;
- }
+/**
+ * Main class for the basic Hibernate example.
+ **/
+public class HibernateExample
+{
+ public static void main(String[] args) {
+ // 1. Create a SessionFactory based on our hibernate.cfg.xml configuration
+ // file, which defines how to connect to the database.
+ SessionFactory sessionFactory
+ = new Configuration()
+ .configure("hibernate.cfg.xml")
+ .setProperties(getTiDBProperties())
+ .addAnnotatedClass(PlayerBean.class)
+ .buildSessionFactory();
- public String getId() {
- return id;
- }
+ try (Session session = sessionFactory.openSession()) {
+ // 2. And then, create DAO to manager your data.
+ PlayerDAO playerDAO = new PlayerDAO();
- public void setId(String id) {
- this.id = id;
- }
+ // 3. Run some simple examples.
- public Integer getCoins() {
- return coins;
- }
+ // Create a player who has 1 coin and 1 goods.
+ playerDAO.runTransaction(session, playerDAO.createPlayers(Collections.singletonList(
+ new PlayerBean("test", 1, 1))));
- public void setCoins(Integer coins) {
- this.coins = coins;
- }
+ // Get a player.
+ PlayerBean testPlayer = (PlayerBean)playerDAO.runTransaction(session, playerDAO.getPlayerByID("test"));
+ System.out.printf("PlayerDAO.getPlayer:\n => id: %s\n => coins: %s\n => goods: %s\n",
+ testPlayer.getId(), testPlayer.getCoins(), testPlayer.getGoods());
- public Integer getGoods() {
- return goods;
- }
+ // Count players amount.
+ Long count = (Long)playerDAO.runTransaction(session, playerDAO.countPlayers());
+ System.out.printf("PlayerDAO.countPlayers:\n => %d total players\n", count);
- public void setGoods(Integer goods) {
- this.goods = goods;
+ // Print 3 players.
+ playerDAO.runTransaction(session, playerDAO.printPlayers(3));
+
+ // 4. Getting further.
+
+ // Player 1: id is "1", has only 100 coins.
+ // Player 2: id is "2", has 114514 coins, and 20 goods.
+ PlayerBean player1 = new PlayerBean("1", 100, 0);
+ PlayerBean player2 = new PlayerBean("2", 114514, 20);
+
+ // Create two players "by hand", using the INSERT statement on the backend.
+ int addedCount = (Integer)playerDAO.runTransaction(session,
+ playerDAO.createPlayers(Arrays.asList(player1, player2)));
+ System.out.printf("PlayerDAO.createPlayers:\n => %d total inserted players\n", addedCount);
+
+ // Player 1 wants to buy 10 goods from player 2.
+ // It will cost 500 coins, but player 1 cannot afford it.
+ System.out.println("\nPlayerDAO.buyGoods:\n => this trade will fail");
+ Integer updatedCount = (Integer)playerDAO.runTransaction(session,
+ playerDAO.buyGoods(player2.getId(), player1.getId(), 10, 500));
+ System.out.printf("PlayerDAO.buyGoods:\n => %d total update players\n", updatedCount);
+
+ // So player 1 has to reduce the incoming quantity to two.
+ System.out.println("\nPlayerDAO.buyGoods:\n => this trade will success");
+ updatedCount = (Integer)playerDAO.runTransaction(session,
+ playerDAO.buyGoods(player2.getId(), player1.getId(), 2, 100));
+ System.out.printf("PlayerDAO.buyGoods:\n => %d total update players\n", updatedCount);
+ } finally {
+ sessionFactory.close();
+ }
}
- @Override
- public String toString() {
- return String.format(" %-8s => %10s\n %-8s => %10s\n %-8s => %10s\n",
- "id", this.id, "coins", this.coins, "goods", this.goods);
+ public static Properties getTiDBProperties() {
+ // 1. Get TiDB connection properties from environment variables.
+ String tidbJDBCURL = System.getenv().getOrDefault("TIDB_JDBC_URL", "jdbc:mysql://localhost:4000/test");
+ String tidbUser = System.getenv().getOrDefault("TIDB_USER", "root");
+ String tidbPassword = System.getenv().getOrDefault("TIDB_PASSWORD", "");
+
+ Properties properties = new Properties();
+ properties.setProperty("hibernate.connection.url", tidbJDBCURL);
+ properties.setProperty("hibernate.connection.username", tidbUser);
+ properties.setProperty("hibernate.connection.password", tidbPassword);
+
+ return properties;
}
-}
-/**
- * Main class for the basic Hibernate example.
- **/
-public class HibernateExample
-{
public static class PlayerDAO {
public static class NotEnoughException extends RuntimeException {
public NotEnoughException(String message) {
@@ -94,7 +117,7 @@ public NotEnoughException(String message) {
}
// Run SQL code in a way that automatically handles the
- // transaction retry logic so we don't have to duplicate it in
+ // transaction retry logic, so we don't have to duplicate it in
// various places.
public Object runTransaction(Session session, Function fn) {
Object resultObject = null;
@@ -179,64 +202,4 @@ public Function countPlayers() throws JDBCException {
};
}
}
-
- public static void main(String[] args) {
- // 1. Create a SessionFactory based on our hibernate.cfg.xml configuration
- // file, which defines how to connect to the database.
- SessionFactory sessionFactory
- = new Configuration()
- .configure("hibernate.cfg.xml")
- .addAnnotatedClass(PlayerBean.class)
- .buildSessionFactory();
-
- try (Session session = sessionFactory.openSession()) {
- // 2. And then, create DAO to manager your data.
- PlayerDAO playerDAO = new PlayerDAO();
-
- // 3. Run some simple examples.
-
- // Create a player who has 1 coin and 1 goods.
- playerDAO.runTransaction(session, playerDAO.createPlayers(Collections.singletonList(
- new PlayerBean("test", 1, 1))));
-
- // Get a player.
- PlayerBean testPlayer = (PlayerBean)playerDAO.runTransaction(session, playerDAO.getPlayerByID("test"));
- System.out.printf("PlayerDAO.getPlayer:\n => id: %s\n => coins: %s\n => goods: %s\n",
- testPlayer.getId(), testPlayer.getCoins(), testPlayer.getGoods());
-
- // Count players amount.
- Long count = (Long)playerDAO.runTransaction(session, playerDAO.countPlayers());
- System.out.printf("PlayerDAO.countPlayers:\n => %d total players\n", count);
-
- // Print 3 players.
- playerDAO.runTransaction(session, playerDAO.printPlayers(3));
-
- // 4. Getting further.
-
- // Player 1: id is "1", has only 100 coins.
- // Player 2: id is "2", has 114514 coins, and 20 goods.
- PlayerBean player1 = new PlayerBean("1", 100, 0);
- PlayerBean player2 = new PlayerBean("2", 114514, 20);
-
- // Create two players "by hand", using the INSERT statement on the backend.
- int addedCount = (Integer)playerDAO.runTransaction(session,
- playerDAO.createPlayers(Arrays.asList(player1, player2)));
- System.out.printf("PlayerDAO.createPlayers:\n => %d total inserted players\n", addedCount);
-
- // Player 1 wants to buy 10 goods from player 2.
- // It will cost 500 coins, but player 1 cannot afford it.
- System.out.println("\nPlayerDAO.buyGoods:\n => this trade will fail");
- Integer updatedCount = (Integer)playerDAO.runTransaction(session,
- playerDAO.buyGoods(player2.getId(), player1.getId(), 10, 500));
- System.out.printf("PlayerDAO.buyGoods:\n => %d total update players\n", updatedCount);
-
- // So player 1 has to reduce the incoming quantity to two.
- System.out.println("\nPlayerDAO.buyGoods:\n => this trade will success");
- updatedCount = (Integer)playerDAO.runTransaction(session,
- playerDAO.buyGoods(player2.getId(), player1.getId(), 2, 100));
- System.out.printf("PlayerDAO.buyGoods:\n => %d total update players\n", updatedCount);
- } finally {
- sessionFactory.close();
- }
- }
}
diff --git a/plain-java-hibernate/src/main/java/com/pingcap/PlayerBean.java b/plain-java-hibernate/src/main/java/com/pingcap/PlayerBean.java
new file mode 100644
index 0000000..ea2cc45
--- /dev/null
+++ b/plain-java-hibernate/src/main/java/com/pingcap/PlayerBean.java
@@ -0,0 +1,76 @@
+// Copyright 2022 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.pingcap;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+
+/**
+ * PlayerBean
+ *
+ * @author Icemap
+ * @date 2023/8/3
+ */
+@Entity
+@Table(name = "player_hibernate")
+class PlayerBean {
+ @Id
+ private String id;
+ @Column(name = "coins")
+ private Integer coins;
+ @Column(name = "goods")
+ private Integer goods;
+
+ public PlayerBean() {
+ }
+
+ public PlayerBean(String id, Integer coins, Integer goods) {
+ this.id = id;
+ this.coins = coins;
+ this.goods = goods;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public Integer getCoins() {
+ return coins;
+ }
+
+ public void setCoins(Integer coins) {
+ this.coins = coins;
+ }
+
+ public Integer getGoods() {
+ return goods;
+ }
+
+ public void setGoods(Integer goods) {
+ this.goods = goods;
+ }
+
+ @Override
+ public String toString() {
+ return String.format(" %-8s => %10s\n %-8s => %10s\n %-8s => %10s\n",
+ "id", this.id, "coins", this.coins, "goods", this.goods);
+ }
+}
diff --git a/plain-java-hibernate/src/main/resources/hibernate.cfg.xml b/plain-java-hibernate/src/main/resources/hibernate.cfg.xml
index 5af32bc..9c3d766 100644
--- a/plain-java-hibernate/src/main/resources/hibernate.cfg.xml
+++ b/plain-java-hibernate/src/main/resources/hibernate.cfg.xml
@@ -8,9 +8,9 @@
com.mysql.cj.jdbc.Driver
org.hibernate.dialect.TiDBDialect
- jdbc:mysql://localhost:4000/test
- root
-
+
+
+
false
diff --git a/plain-java-jdbc/Makefile b/plain-java-jdbc/Makefile
index be3fef0..da67765 100644
--- a/plain-java-jdbc/Makefile
+++ b/plain-java-jdbc/Makefile
@@ -12,16 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-.PHONY: all mysql build run
+.PHONY: all build run
all:
- make build run
-
-mysql:
- mysql --host 127.0.0.1 --port 4000 -u root
mysql
mysql-connector-java
- 8.0.28
+ 8.0.33
+ ${project.name}
org.apache.maven.plugins
diff --git a/plain-java-jdbc/src/main/java/com/pingcap/JDBCExample.java b/plain-java-jdbc/src/main/java/com/pingcap/JDBCExample.java
index 3f20374..9a88845 100644
--- a/plain-java-jdbc/src/main/java/com/pingcap/JDBCExample.java
+++ b/plain-java-jdbc/src/main/java/com/pingcap/JDBCExample.java
@@ -14,6 +14,7 @@
package com.pingcap;
+import com.mysql.cj.conf.PropertyDefinitions;
import com.mysql.cj.jdbc.MysqlDataSource;
import java.sql.Connection;
@@ -27,366 +28,13 @@
**/
public class JDBCExample
{
- public static class PlayerBean {
- private String id;
- private Integer coins;
- private Integer goods;
-
- public PlayerBean() {
- }
-
- public PlayerBean(String id, Integer coins, Integer goods) {
- this.id = id;
- this.coins = coins;
- this.goods = goods;
- }
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public Integer getCoins() {
- return coins;
- }
-
- public void setCoins(Integer coins) {
- this.coins = coins;
- }
-
- public Integer getGoods() {
- return goods;
- }
-
- public void setGoods(Integer goods) {
- this.goods = goods;
- }
-
- @Override
- public String toString() {
- return String.format(" %-8s => %10s\n %-8s => %10s\n %-8s => %10s\n",
- "id", this.id, "coins", this.coins, "goods", this.goods);
- }
- }
-
- /**
- * Data access object used by 'ExampleDataSource'.
- * Example for CURD and bulk insert.
- */
- public static class PlayerDAO {
- private final MysqlDataSource ds;
- private final Random rand = new Random();
-
- PlayerDAO(MysqlDataSource ds) {
- this.ds = ds;
- }
-
- /**
- * Create players by passing in a List of PlayerBean.
- *
- * @param players Will create players list
- * @return The number of create accounts
- */
- public int createPlayers(List players){
- int rows = 0;
-
- Connection connection = null;
- PreparedStatement preparedStatement = null;
- try {
- connection = ds.getConnection();
- preparedStatement = connection.prepareStatement("INSERT INTO player (id, coins, goods) VALUES (?, ?, ?)");
- } catch (SQLException e) {
- System.out.printf("[createPlayers] ERROR: { state => %s, cause => %s, message => %s }\n",
- e.getSQLState(), e.getCause(), e.getMessage());
- e.printStackTrace();
-
- return -1;
- }
-
- try {
- for (PlayerBean player : players) {
- preparedStatement.setString(1, player.getId());
- preparedStatement.setInt(2, player.getCoins());
- preparedStatement.setInt(3, player.getGoods());
-
- preparedStatement.execute();
- rows += preparedStatement.getUpdateCount();
- }
- } catch (SQLException e) {
- System.out.printf("[createPlayers] ERROR: { state => %s, cause => %s, message => %s }\n",
- e.getSQLState(), e.getCause(), e.getMessage());
- e.printStackTrace();
- } finally {
- try {
- connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-
- System.out.printf("\n[createPlayers]:\n '%s'\n", preparedStatement);
- return rows;
- }
-
- /**
- * Buy goods and transfer funds between one player and another in one transaction.
- * @param sellId Sell player id.
- * @param buyId Buy player id.
- * @param amount Goods amount, if sell player has not enough goods, the trade will break.
- * @param price Price should pay, if buy player has not enough coins, the trade will break.
- *
- * @return The number of effected players.
- */
- public int buyGoods(String sellId, String buyId, Integer amount, Integer price) {
- int effectPlayers = 0;
-
- Connection connection = null;
- try {
- connection = ds.getConnection();
- } catch (SQLException e) {
- System.out.printf("[buyGoods] ERROR: { state => %s, cause => %s, message => %s }\n",
- e.getSQLState(), e.getCause(), e.getMessage());
- e.printStackTrace();
- return effectPlayers;
- }
-
- try {
- connection.setAutoCommit(false);
-
- PreparedStatement playerQuery = connection.prepareStatement("SELECT * FROM player WHERE id=? OR id=? FOR UPDATE");
- playerQuery.setString(1, sellId);
- playerQuery.setString(2, buyId);
- playerQuery.execute();
-
- PlayerBean sellPlayer = null;
- PlayerBean buyPlayer = null;
-
- ResultSet playerQueryResultSet = playerQuery.getResultSet();
- while (playerQueryResultSet.next()) {
- PlayerBean player = new PlayerBean(
- playerQueryResultSet.getString("id"),
- playerQueryResultSet.getInt("coins"),
- playerQueryResultSet.getInt("goods")
- );
-
- System.out.println("\n[buyGoods]:\n 'check goods and coins enough'");
- System.out.println(player);
-
- if (sellId.equals(player.getId())) {
- sellPlayer = player;
- } else {
- buyPlayer = player;
- }
- }
-
- if (sellPlayer == null || buyPlayer == null) {
- throw new SQLException("player not exist.");
- }
-
- if (sellPlayer.getGoods().compareTo(amount) < 0) {
- throw new SQLException(String.format("sell player %s goods not enough.", sellId));
- }
-
- if (buyPlayer.getCoins().compareTo(price) < 0) {
- throw new SQLException(String.format("buy player %s coins not enough.", buyId));
- }
-
- PreparedStatement transfer = connection.prepareStatement("UPDATE player set goods = goods + ?, coins = coins + ? WHERE id=?");
- transfer.setInt(1, -amount);
- transfer.setInt(2, price);
- transfer.setString(3, sellId);
- transfer.execute();
- effectPlayers += transfer.getUpdateCount();
-
- transfer.setInt(1, amount);
- transfer.setInt(2, -price);
- transfer.setString(3, buyId);
- transfer.execute();
- effectPlayers += transfer.getUpdateCount();
-
- connection.commit();
-
- System.out.println("\n[buyGoods]:\n 'trade success'");
- } catch (SQLException e) {
- System.out.printf("[buyGoods] ERROR: { state => %s, cause => %s, message => %s }\n",
- e.getSQLState(), e.getCause(), e.getMessage());
-
- try {
- System.out.println("[buyGoods] Rollback");
-
- connection.rollback();
- } catch (SQLException ex) {
- // do nothing
- }
- } finally {
- try {
- connection.close();
- } catch (SQLException e) {
- // do nothing
- }
- }
-
- return effectPlayers;
- }
-
- /**
- * Get the player info by id.
- *
- * @param id Player id.
- * @return The player of this id.
- */
- public PlayerBean getPlayer(String id) {
- PlayerBean player = null;
-
- try (Connection connection = ds.getConnection()) {
- PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM player WHERE id = ?");
- preparedStatement.setString(1, id);
- preparedStatement.execute();
-
- ResultSet res = preparedStatement.executeQuery();
- if(!res.next()) {
- System.out.printf("No players in the table with id %s", id);
- } else {
- player = new PlayerBean(res.getString("id"), res.getInt("coins"), res.getInt("goods"));
- }
- } catch (SQLException e) {
- System.out.printf("PlayerDAO.getPlayer ERROR: { state => %s, cause => %s, message => %s }\n",
- e.getSQLState(), e.getCause(), e.getMessage());
- }
-
- return player;
- }
-
- /**
- * Insert randomized account data (id, coins, goods) using the JDBC fast path for
- * bulk inserts. The fastest way to get data into TiDB is using the
- * TiDB Lightning(https://docs.pingcap.com/tidb/stable/tidb-lightning-overview).
- * However, if you must bulk insert from the application using INSERT SQL, the best
- * option is the method shown here. It will require the following:
- *
- * Add `rewriteBatchedStatements=true` to your JDBC connection settings.
- * Setting rewriteBatchedStatements to true now causes CallableStatements
- * with batched arguments to be re-written in the form "CALL (...); CALL (...); ..."
- * to send the batch in as few client/server round trips as possible.
- * https://dev.mysql.com/doc/relnotes/connector-j/5.1/en/news-5-1-3.html
- *
- * You can see the `rewriteBatchedStatements` param effect logic at
- * implement function: `com.mysql.cj.jdbc.StatementImpl.executeBatchUsingMultiQueries`
- *
- * @param total Add players amount.
- * @param batchSize Bulk insert size for per batch.
- *
- * @return The number of new accounts inserted.
- */
- public int bulkInsertRandomPlayers(Integer total, Integer batchSize) {
- int totalNewPlayers = 0;
-
- try (Connection connection = ds.getConnection()) {
- // We're managing the commit lifecycle ourselves, so we can
- // control the size of our batch inserts.
- connection.setAutoCommit(false);
-
- // In this example we are adding 500 rows to the database,
- // but it could be any number. What's important is that
- // the batch size is 128.
- try (PreparedStatement pstmt = connection.prepareStatement("INSERT INTO player (id, coins, goods) VALUES (?, ?, ?)")) {
- for (int i=0; i<=(total/batchSize);i++) {
- for (int j=0; j %s row(s) updated in this batch\n", count.length);
- }
- connection.commit();
- } catch (SQLException e) {
- System.out.printf("PlayerDAO.bulkInsertRandomPlayers ERROR: { state => %s, cause => %s, message => %s }\n",
- e.getSQLState(), e.getCause(), e.getMessage());
- }
- } catch (SQLException e) {
- System.out.printf("PlayerDAO.bulkInsertRandomPlayers ERROR: { state => %s, cause => %s, message => %s }\n",
- e.getSQLState(), e.getCause(), e.getMessage());
- }
- return totalNewPlayers;
- }
-
-
- /**
- * Print a subset of players from the data store by limit.
- *
- * @param limit Print max size.
- */
- public void printPlayers(Integer limit) {
- try (Connection connection = ds.getConnection()) {
- PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM player LIMIT ?");
- preparedStatement.setInt(1, limit);
- preparedStatement.execute();
-
- ResultSet res = preparedStatement.executeQuery();
- while (!res.next()) {
- PlayerBean player = new PlayerBean(res.getString("id"),
- res.getInt("coins"), res.getInt("goods"));
- System.out.println("\n[printPlayers]:\n" + player);
- }
- } catch (SQLException e) {
- System.out.printf("PlayerDAO.printPlayers ERROR: { state => %s, cause => %s, message => %s }\n",
- e.getSQLState(), e.getCause(), e.getMessage());
- }
- }
-
-
- /**
- * Count players from the data store.
- *
- * @return All players count
- */
- public int countPlayers() {
- int count = 0;
-
- try (Connection connection = ds.getConnection()) {
- PreparedStatement preparedStatement = connection.prepareStatement("SELECT count(*) FROM player");
- preparedStatement.execute();
-
- ResultSet res = preparedStatement.executeQuery();
- if(res.next()) {
- count = res.getInt(1);
- }
- } catch (SQLException e) {
- System.out.printf("PlayerDAO.countPlayers ERROR: { state => %s, cause => %s, message => %s }\n",
- e.getSQLState(), e.getCause(), e.getMessage());
- }
-
- return count;
- }
- }
-
- public static void main(String[] args) {
+ public static void main(String[] args) throws SQLException {
// 1. Configure the example database connection.
+ MysqlDataSource mysqlDataSource = getMysqlDataSourceByEnv();
- // 1.1 Create a mysql data source instance.
- MysqlDataSource mysqlDataSource = new MysqlDataSource();
-
- // 1.2 Set server name, port, database name, username and password.
- mysqlDataSource.setServerName("localhost");
- mysqlDataSource.setPortNumber(4000);
- mysqlDataSource.setDatabaseName("test");
- mysqlDataSource.setUser("root");
- mysqlDataSource.setPassword("");
-
- // Or you can use jdbc string instead.
- // mysqlDataSource.setURL("jdbc:mysql://{host}:{port}/test?user={user}&password={password}");
-
- // 2. And then, create DAO to manager your data.
+ // 2. And then, create DAO to manager your data. We recreate this table for test.
PlayerDAO dao = new PlayerDAO(mysqlDataSource);
+ dao.recreateTable();
// 3. Run some simple examples.
@@ -431,4 +79,33 @@ public static void main(String[] args) {
updatedCount = dao.buyGoods(player2.getId(), player1.getId(), 2, 100);
System.out.printf("PlayerDAO.buyGoods:\n => %d total update players\n", updatedCount);
}
+
+ private static MysqlDataSource getMysqlDataSourceByEnv() throws SQLException {
+ // 1.1 Create a mysql data source instance.
+ MysqlDataSource mysqlDataSource = new MysqlDataSource();
+
+ // 1.2 Get parameters from environment variables.
+ String tidbHost = System.getenv().getOrDefault("TIDB_HOST", "localhost");
+ int tidbPort = Integer.parseInt(System.getenv().getOrDefault("TIDB_PORT", "4000"));
+ String tidbUser = System.getenv().getOrDefault("TIDB_USER", "root");
+ String tidbPassword = System.getenv().getOrDefault("TIDB_PASSWORD", "");
+ String tidbDatabase = System.getenv().getOrDefault("TIDB_DATABASE", "test");
+ boolean useSSL = Boolean.parseBoolean(System.getenv().getOrDefault("USE_SSL", "false"));
+
+ // 1.3 Set server name, port, database name, username and password.
+ mysqlDataSource.setServerName(tidbHost);
+ mysqlDataSource.setPortNumber(tidbPort);
+ mysqlDataSource.setUser(tidbUser);
+ mysqlDataSource.setPassword(tidbPassword);
+ mysqlDataSource.setDatabaseName(tidbDatabase);
+ if (useSSL) {
+ mysqlDataSource.setSslMode(PropertyDefinitions.SslMode.VERIFY_IDENTITY.name());
+ mysqlDataSource.setEnabledTLSProtocols("TLSv1.2,TLSv1.3");
+ }
+
+ // Or you can use jdbc string instead.
+ // mysqlDataSource.setURL("jdbc:mysql://{host}:{port}/test?user={user}&password={password}");
+
+ return mysqlDataSource;
+ }
}
diff --git a/plain-java-jdbc/src/main/java/com/pingcap/PlayerBean.java b/plain-java-jdbc/src/main/java/com/pingcap/PlayerBean.java
new file mode 100644
index 0000000..8aab457
--- /dev/null
+++ b/plain-java-jdbc/src/main/java/com/pingcap/PlayerBean.java
@@ -0,0 +1,66 @@
+// Copyright 2022 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.pingcap;
+
+/**
+ * PlayerBean
+ *
+ * @author Icemap
+ * @date 2023/8/3
+ */
+public class PlayerBean {
+ private String id;
+ private Integer coins;
+ private Integer goods;
+
+ public PlayerBean() {
+ }
+
+ public PlayerBean(String id, Integer coins, Integer goods) {
+ this.id = id;
+ this.coins = coins;
+ this.goods = goods;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public Integer getCoins() {
+ return coins;
+ }
+
+ public void setCoins(Integer coins) {
+ this.coins = coins;
+ }
+
+ public Integer getGoods() {
+ return goods;
+ }
+
+ public void setGoods(Integer goods) {
+ this.goods = goods;
+ }
+
+ @Override
+ public String toString() {
+ return String.format(" %-8s => %10s\n %-8s => %10s\n %-8s => %10s\n",
+ "id", this.id, "coins", this.coins, "goods", this.goods);
+ }
+}
diff --git a/plain-java-jdbc/src/main/java/com/pingcap/PlayerDAO.java b/plain-java-jdbc/src/main/java/com/pingcap/PlayerDAO.java
new file mode 100644
index 0000000..8d59090
--- /dev/null
+++ b/plain-java-jdbc/src/main/java/com/pingcap/PlayerDAO.java
@@ -0,0 +1,338 @@
+// Copyright 2022 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.pingcap;
+
+import com.mysql.cj.jdbc.MysqlDataSource;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+
+/**
+ * PlayerDAO Data access object used by 'ExampleDataSource'.
+ * * Example for CURD and bulk insert.
+ *
+ * @author Icemap
+ * @date 2023/8/3
+ */
+public class PlayerDAO {
+ private final MysqlDataSource ds;
+ private final Random rand = new Random();
+
+ PlayerDAO(MysqlDataSource ds) {
+ this.ds = ds;
+ }
+
+ /**
+ * Recreate the table named 'player'.
+ */
+ public void recreateTable() {
+ try (Connection connection = ds.getConnection()) {
+ connection.prepareStatement("DROP TABLE IF EXISTS player").execute();
+ connection.prepareStatement("CREATE TABLE player (id VARCHAR(255) PRIMARY KEY, coins INT, goods INT)").execute();
+ } catch (SQLException e) {
+ System.out.printf("PlayerDAO ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+ }
+ }
+
+ /**
+ * Create players by passing in a List of PlayerBean.
+ *
+ * @param players Will create players list
+ * @return The number of create accounts
+ */
+ public int createPlayers(List players){
+ int rows = 0;
+
+ Connection connection = null;
+ PreparedStatement preparedStatement = null;
+ try {
+ connection = ds.getConnection();
+ preparedStatement = connection.prepareStatement("INSERT INTO player (id, coins, goods) VALUES (?, ?, ?)");
+ } catch (SQLException e) {
+ System.out.printf("[createPlayers] ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+ e.printStackTrace();
+
+ return -1;
+ }
+
+ try {
+ for (PlayerBean player : players) {
+ preparedStatement.setString(1, player.getId());
+ preparedStatement.setInt(2, player.getCoins());
+ preparedStatement.setInt(3, player.getGoods());
+
+ preparedStatement.execute();
+ rows += preparedStatement.getUpdateCount();
+ }
+ } catch (SQLException e) {
+ System.out.printf("[createPlayers] ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+ e.printStackTrace();
+ } finally {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ System.out.printf("\n[createPlayers]:\n '%s'\n", preparedStatement);
+ return rows;
+ }
+
+ /**
+ * Buy goods and transfer funds between one player and another in one transaction.
+ * @param sellId Sell player id.
+ * @param buyId Buy player id.
+ * @param amount Goods amount, if sell player has not enough goods, the trade will break.
+ * @param price Price should pay, if buy player has not enough coins, the trade will break.
+ *
+ * @return The number of effected players.
+ */
+ public int buyGoods(String sellId, String buyId, Integer amount, Integer price) {
+ int effectPlayers = 0;
+
+ Connection connection = null;
+ try {
+ connection = ds.getConnection();
+ } catch (SQLException e) {
+ System.out.printf("[buyGoods] ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+ e.printStackTrace();
+ return effectPlayers;
+ }
+
+ try {
+ connection.setAutoCommit(false);
+
+ PreparedStatement playerQuery = connection.prepareStatement("SELECT * FROM player WHERE id=? OR id=? FOR UPDATE");
+ playerQuery.setString(1, sellId);
+ playerQuery.setString(2, buyId);
+ playerQuery.execute();
+
+ PlayerBean sellPlayer = null;
+ PlayerBean buyPlayer = null;
+
+ ResultSet playerQueryResultSet = playerQuery.getResultSet();
+ while (playerQueryResultSet.next()) {
+ PlayerBean player = new PlayerBean(
+ playerQueryResultSet.getString("id"),
+ playerQueryResultSet.getInt("coins"),
+ playerQueryResultSet.getInt("goods")
+ );
+
+ System.out.println("\n[buyGoods]:\n 'check goods and coins enough'");
+ System.out.println(player);
+
+ if (sellId.equals(player.getId())) {
+ sellPlayer = player;
+ } else {
+ buyPlayer = player;
+ }
+ }
+
+ if (sellPlayer == null || buyPlayer == null) {
+ throw new SQLException("player not exist.");
+ }
+
+ if (sellPlayer.getGoods().compareTo(amount) < 0) {
+ throw new SQLException(String.format("sell player %s goods not enough.", sellId));
+ }
+
+ if (buyPlayer.getCoins().compareTo(price) < 0) {
+ throw new SQLException(String.format("buy player %s coins not enough.", buyId));
+ }
+
+ PreparedStatement transfer = connection.prepareStatement("UPDATE player set goods = goods + ?, coins = coins + ? WHERE id=?");
+ transfer.setInt(1, -amount);
+ transfer.setInt(2, price);
+ transfer.setString(3, sellId);
+ transfer.execute();
+ effectPlayers += transfer.getUpdateCount();
+
+ transfer.setInt(1, amount);
+ transfer.setInt(2, -price);
+ transfer.setString(3, buyId);
+ transfer.execute();
+ effectPlayers += transfer.getUpdateCount();
+
+ connection.commit();
+
+ System.out.println("\n[buyGoods]:\n 'trade success'");
+ } catch (SQLException e) {
+ System.out.printf("[buyGoods] ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+
+ try {
+ System.out.println("[buyGoods] Rollback");
+
+ connection.rollback();
+ } catch (SQLException ex) {
+ // do nothing
+ }
+ } finally {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ // do nothing
+ }
+ }
+
+ return effectPlayers;
+ }
+
+ /**
+ * Get the player info by id.
+ *
+ * @param id Player id.
+ * @return The player of this id.
+ */
+ public PlayerBean getPlayer(String id) {
+ PlayerBean player = null;
+
+ try (Connection connection = ds.getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM player WHERE id = ?");
+ preparedStatement.setString(1, id);
+ preparedStatement.execute();
+
+ ResultSet res = preparedStatement.executeQuery();
+ if(!res.next()) {
+ System.out.printf("No players in the table with id %s", id);
+ } else {
+ player = new PlayerBean(res.getString("id"), res.getInt("coins"), res.getInt("goods"));
+ }
+ } catch (SQLException e) {
+ System.out.printf("PlayerDAO.getPlayer ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+ }
+
+ return player;
+ }
+
+ /**
+ * Insert randomized account data (id, coins, goods) using the JDBC fast path for
+ * bulk inserts. The fastest way to get data into TiDB is using the
+ * TiDB Lightning(https://docs.pingcap.com/tidb/stable/tidb-lightning-overview).
+ * However, if you must bulk insert from the application using INSERT SQL, the best
+ * option is the method shown here. It will require the following:
+ *
+ * Add `rewriteBatchedStatements=true` to your JDBC connection settings.
+ * Setting rewriteBatchedStatements to true now causes CallableStatements
+ * with batched arguments to be re-written in the form "CALL (...); CALL (...); ..."
+ * to send the batch in as few client/server round trips as possible.
+ * https://dev.mysql.com/doc/relnotes/connector-j/5.1/en/news-5-1-3.html
+ *
+ * You can see the `rewriteBatchedStatements` param effect logic at
+ * implement function: `com.mysql.cj.jdbc.StatementImpl.executeBatchUsingMultiQueries`
+ *
+ * @param total Add players amount.
+ * @param batchSize Bulk insert size for per batch.
+ *
+ * @return The number of new accounts inserted.
+ */
+ public int bulkInsertRandomPlayers(Integer total, Integer batchSize) {
+ int totalNewPlayers = 0;
+
+ try (Connection connection = ds.getConnection()) {
+ // We're managing the commit lifecycle ourselves, so we can
+ // control the size of our batch inserts.
+ connection.setAutoCommit(false);
+
+ // In this example we are adding 500 rows to the database,
+ // but it could be any number. What's important is that
+ // the batch size is 128.
+ try (PreparedStatement pstmt = connection.prepareStatement("INSERT INTO player (id, coins, goods) VALUES (?, ?, ?)")) {
+ for (int i=0; i<=(total/batchSize);i++) {
+ for (int j=0; j %s row(s) updated in this batch\n", count.length);
+ }
+ connection.commit();
+ } catch (SQLException e) {
+ System.out.printf("PlayerDAO.bulkInsertRandomPlayers ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+ }
+ } catch (SQLException e) {
+ System.out.printf("PlayerDAO.bulkInsertRandomPlayers ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+ }
+ return totalNewPlayers;
+ }
+
+
+ /**
+ * Print a subset of players from the data store by limit.
+ *
+ * @param limit Print max size.
+ */
+ public void printPlayers(Integer limit) {
+ try (Connection connection = ds.getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM player LIMIT ?");
+ preparedStatement.setInt(1, limit);
+ preparedStatement.execute();
+
+ ResultSet res = preparedStatement.executeQuery();
+ while (!res.next()) {
+ PlayerBean player = new PlayerBean(res.getString("id"),
+ res.getInt("coins"), res.getInt("goods"));
+ System.out.println("\n[printPlayers]:\n" + player);
+ }
+ } catch (SQLException e) {
+ System.out.printf("PlayerDAO.printPlayers ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+ }
+ }
+
+
+ /**
+ * Count players from the data store.
+ *
+ * @return All players count
+ */
+ public int countPlayers() {
+ int count = 0;
+
+ try (Connection connection = ds.getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement("SELECT count(*) FROM player");
+ preparedStatement.execute();
+
+ ResultSet res = preparedStatement.executeQuery();
+ if(res.next()) {
+ count = res.getInt(1);
+ }
+ } catch (SQLException e) {
+ System.out.printf("PlayerDAO.countPlayers ERROR: { state => %s, cause => %s, message => %s }\n",
+ e.getSQLState(), e.getCause(), e.getMessage());
+ }
+
+ return count;
+ }
+}
diff --git a/plain-java-jdbc/src/main/resources/dbinit.sql b/plain-java-jdbc/src/main/resources/dbinit.sql
deleted file mode 100644
index 6e70f2a..0000000
--- a/plain-java-jdbc/src/main/resources/dbinit.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-USE test;
-DROP TABLE IF EXISTS player;
-
-CREATE TABLE player (
- `id` VARCHAR(36),
- `coins` INTEGER,
- `goods` INTEGER,
- PRIMARY KEY (`id`)
-);
\ No newline at end of file
diff --git a/plain-java-mybatis/Makefile b/plain-java-mybatis/Makefile
index 2d0e5e1..692969d 100644
--- a/plain-java-mybatis/Makefile
+++ b/plain-java-mybatis/Makefile
@@ -12,23 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-.PHONY: all gen build run
+.PHONY: all build run
all:
- make mysql gen build run
-
-mysql:
- mysql --host 127.0.0.1 --port 4000 -u root
junit
junit
- 4.11
+ 4.13.1
test
@@ -28,14 +28,14 @@
mysql
mysql-connector-java
- 5.1.49
+ 8.0.33
org.mybatis
mybatis
- 3.5.9
+ 3.5.13
@@ -61,27 +61,8 @@
+ ${project.name}
-
- org.mybatis.generator
- mybatis-generator-maven-plugin
- 1.4.1
-
- src/main/resources/mybatis-generator.xml
- true
- true
-
-
-
-
-
- mysql
- mysql-connector-java
- 5.1.49
-
-
-
-
org.apache.maven.plugins
maven-assembly-plugin
diff --git a/plain-java-mybatis/src/main/java/com/pingcap/MybatisExample.java b/plain-java-mybatis/src/main/java/com/pingcap/MybatisExample.java
index c151eb8..7359c53 100644
--- a/plain-java-mybatis/src/main/java/com/pingcap/MybatisExample.java
+++ b/plain-java-mybatis/src/main/java/com/pingcap/MybatisExample.java
@@ -24,34 +24,35 @@
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Properties;
public class MybatisExample {
public static void main( String[] args ) throws IOException {
// 1. Create a SqlSessionFactory based on our mybatis-config.xml configuration
// file, which defines how to connect to the database.
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
- SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
+ SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream, getTiDBProperties());
// 2. And then, create DAO to manager your data
- PlayerDAO playerDAO = new PlayerDAO();
+ PlayerDAO playerDAO = new PlayerDAO(sessionFactory);
+ playerDAO.recreateTable();
// 3. Run some simple examples.
// Create a player who has 1 coin and 1 goods.
- playerDAO.runTransaction(sessionFactory, playerDAO.createPlayers(
- Collections.singletonList(new Player("test", 1, 1))));
+ playerDAO.createPlayers(Collections.singletonList(new Player("test", 1, 1)));
// Get a player.
- Player testPlayer = (Player)playerDAO.runTransaction(sessionFactory, playerDAO.getPlayerByID("test"));
+ Player testPlayer = playerDAO.getPlayerByID("test");
System.out.printf("PlayerDAO.getPlayer:\n => id: %s\n => coins: %s\n => goods: %s\n",
testPlayer.getId(), testPlayer.getCoins(), testPlayer.getGoods());
// Count players amount.
- Integer count = (Integer)playerDAO.runTransaction(sessionFactory, playerDAO.countPlayers());
+ Integer count = playerDAO.countPlayers();
System.out.printf("PlayerDAO.countPlayers:\n => %d total players\n", count);
// Print 3 players.
- playerDAO.runTransaction(sessionFactory, playerDAO.printPlayers(3));
+ playerDAO.printPlayers(3);
// 4. Getting further.
@@ -61,21 +62,36 @@ public static void main( String[] args ) throws IOException {
Player player2 = new Player("2", 114514, 20);
// Create two players "by hand", using the INSERT statement on the backend.
- int addedCount = (Integer)playerDAO.runTransaction(sessionFactory,
- playerDAO.createPlayers(Arrays.asList(player1, player2)));
+ int addedCount = playerDAO.createPlayers(Arrays.asList(player1, player2));
System.out.printf("PlayerDAO.createPlayers:\n => %d total inserted players\n", addedCount);
// Player 1 wants to buy 10 goods from player 2.
// It will cost 500 coins, but player 1 cannot afford it.
System.out.println("\nPlayerDAO.buyGoods:\n => this trade will fail");
- Integer updatedCount = (Integer)playerDAO.runTransaction(sessionFactory,
- playerDAO.buyGoods(player2.getId(), player1.getId(), 10, 500));
+ Integer updatedCount = playerDAO.buyGoods(player2.getId(), player1.getId(), 10, 500);
System.out.printf("PlayerDAO.buyGoods:\n => %d total update players\n", updatedCount);
// So player 1 has to reduce the incoming quantity to two.
System.out.println("\nPlayerDAO.buyGoods:\n => this trade will success");
- updatedCount = (Integer)playerDAO.runTransaction(sessionFactory,
- playerDAO.buyGoods(player2.getId(), player1.getId(), 2, 100));
+ updatedCount = playerDAO.buyGoods(player2.getId(), player1.getId(), 2, 100);
System.out.printf("PlayerDAO.buyGoods:\n => %d total update players\n", updatedCount);
}
+
+ /**
+ * Get TiDB connection properties from environment variables.
+ * @return Properties
+ */
+ public static Properties getTiDBProperties() {
+ // 1. Get TiDB connection properties from environment variables.
+ String tidbJDBCURL = System.getenv().getOrDefault("TIDB_JDBC_URL", "jdbc:mysql://localhost:4000/test");
+ String tidbUser = System.getenv().getOrDefault("TIDB_USER", "root");
+ String tidbPassword = System.getenv().getOrDefault("TIDB_PASSWORD", "");
+
+ Properties properties = new Properties();
+ properties.setProperty("TIDB_URL", tidbJDBCURL);
+ properties.setProperty("TIDB_USER", tidbUser);
+ properties.setProperty("TIDB_PASSWORD", tidbPassword);
+
+ return properties;
+ }
}
diff --git a/plain-java-mybatis/src/main/java/com/pingcap/dao/PlayerDAO.java b/plain-java-mybatis/src/main/java/com/pingcap/dao/PlayerDAO.java
index b00ce91..2dd8f0a 100644
--- a/plain-java-mybatis/src/main/java/com/pingcap/dao/PlayerDAO.java
+++ b/plain-java-mybatis/src/main/java/com/pingcap/dao/PlayerDAO.java
@@ -15,7 +15,7 @@
package com.pingcap.dao;
import com.pingcap.model.Player;
-import com.pingcap.model.PlayerMapperEx;
+import com.pingcap.model.PlayerMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
@@ -29,6 +29,12 @@
* @date 2022/5/23
*/
public class PlayerDAO {
+ SqlSessionFactory sessionFactory;
+
+ public PlayerDAO(SqlSessionFactory sessionFactory) {
+ this.sessionFactory = sessionFactory;
+ }
+
public static class NotEnoughException extends RuntimeException {
public NotEnoughException(String message) {
super(message);
@@ -38,7 +44,7 @@ public NotEnoughException(String message) {
// Run SQL code in a way that automatically handles the
// transaction retry logic, so we don't have to duplicate it in
// various places.
- public Object runTransaction(SqlSessionFactory sessionFactory, Function fn) {
+ private Object runTransaction(SqlSessionFactory sessionFactory, Function fn) {
Object resultObject = null;
SqlSession session = null;
@@ -47,9 +53,9 @@ public Object runTransaction(SqlSessionFactory sessionFactory, Function createPlayers(List players) {
- return playerMapperEx -> {
+ /**
+ * Recreate Table Schema
+ */
+ public void recreateTable() {
+ runTransaction(sessionFactory, recreateTableFunction());
+ }
+
+ private Function recreateTableFunction() {
+ return PlayerMapper -> {
+ PlayerMapper.dropTableIfExist();
+ PlayerMapper.createTable();
+ System.out.println("APP: recreateTable()");
+ return null;
+ };
+ }
+
+ /**
+ * Create players
+ * @param players player list
+ * @return affect rows
+ */
+ public Integer createPlayers(List players) {
+ return (Integer)runTransaction(sessionFactory, createPlayersFunction(players));
+ }
+
+ private Function createPlayersFunction(List players) {
+ return PlayerMapper -> {
Integer addedPlayerAmount = 0;
for (Player player: players) {
- playerMapperEx.insert(player);
+ PlayerMapper.insert(player);
addedPlayerAmount ++;
}
System.out.printf("APP: createPlayers() --> %d\n", addedPlayerAmount);
@@ -83,10 +114,22 @@ public Function createPlayers(List players) {
};
}
- public Function buyGoods(String sellId, String buyId, Integer amount, Integer price) {
- return playerMapperEx -> {
- Player sellPlayer = playerMapperEx.selectByPrimaryKeyWithLock(sellId);
- Player buyPlayer = playerMapperEx.selectByPrimaryKeyWithLock(buyId);
+ /**
+ * Get player amount
+ * @param sellId sell player id
+ * @param buyId buy player id
+ * @param amount goods amount
+ * @param price goods price
+ * @return affect rows
+ */
+ public Integer buyGoods(String sellId, String buyId, Integer amount, Integer price) {
+ return (Integer)runTransaction(sessionFactory, buyGoodsFunction(sellId, buyId, amount, price));
+ }
+
+ private Function buyGoodsFunction(String sellId, String buyId, Integer amount, Integer price) {
+ return PlayerMapper -> {
+ Player sellPlayer = PlayerMapper.selectByPrimaryKeyWithLock(sellId);
+ Player buyPlayer = PlayerMapper.selectByPrimaryKeyWithLock(buyId);
if (buyPlayer == null || sellPlayer == null) {
throw new NotEnoughException("sell or buy player not exist");
@@ -99,33 +142,58 @@ public Function buyGoods(String sellId, String buyId, In
int affectRows = 0;
buyPlayer.setGoods(buyPlayer.getGoods() + amount);
buyPlayer.setCoins(buyPlayer.getCoins() - price);
- affectRows += playerMapperEx.updateByPrimaryKey(buyPlayer);
+ affectRows += PlayerMapper.updateByPrimaryKey(buyPlayer);
sellPlayer.setGoods(sellPlayer.getGoods() - amount);
sellPlayer.setCoins(sellPlayer.getCoins() + price);
- affectRows += playerMapperEx.updateByPrimaryKey(sellPlayer);
+ affectRows += PlayerMapper.updateByPrimaryKey(sellPlayer);
System.out.printf("APP: buyGoods --> sell: %s, buy: %s, amount: %d, price: %d\n", sellId, buyId, amount, price);
return affectRows;
};
}
- public Function getPlayerByID(String id) {
- return playerMapperEx -> playerMapperEx.selectByPrimaryKey(id);
+ /**
+ * Get player by id
+ * @param id player id
+ * @return player
+ */
+ public Player getPlayerByID(String id) {
+ return (Player)runTransaction(sessionFactory, getPlayerByIDFunction(id));
}
- public Function printPlayers(Integer limit) {
- return playerMapperEx -> {
- List players = playerMapperEx.selectByLimit(limit);
+ private Function getPlayerByIDFunction(String id) {
+ return PlayerMapper -> PlayerMapper.selectByPrimaryKey(id);
+ }
+
+ /**
+ * Print players
+ * @param limit number of players limit
+ */
+ public void printPlayers(Integer limit) {
+ runTransaction(sessionFactory, printPlayersFunction(limit));
+ }
+
+ private Function printPlayersFunction(Integer limit) {
+ return PlayerMapper -> {
+ List players = PlayerMapper.selectByLimit(limit);
for (Player player: players) {
System.out.println("\n[printPlayers]:\n" + player);
}
- return 0;
+ return null;
};
}
- public Function countPlayers() {
- return PlayerMapperEx::count;
+ /**
+ * Count players
+ * @return number of players
+ */
+ public Integer countPlayers() {
+ return (Integer)runTransaction(sessionFactory, countPlayersFunction());
+ }
+
+ private Function countPlayersFunction() {
+ return PlayerMapper::count;
}
}
diff --git a/plain-java-mybatis/src/main/java/com/pingcap/model/PlayerMapper.java b/plain-java-mybatis/src/main/java/com/pingcap/model/PlayerMapper.java
index ee17bca..8b02844 100644
--- a/plain-java-mybatis/src/main/java/com/pingcap/model/PlayerMapper.java
+++ b/plain-java-mybatis/src/main/java/com/pingcap/model/PlayerMapper.java
@@ -2,6 +2,8 @@
import com.pingcap.model.Player;
+import java.util.List;
+
public interface PlayerMapper {
int deleteByPrimaryKey(String id);
@@ -14,4 +16,14 @@ public interface PlayerMapper {
int updateByPrimaryKeySelective(Player row);
int updateByPrimaryKey(Player row);
+
+ Player selectByPrimaryKeyWithLock(String id);
+
+ List selectByLimit(Integer limit);
+
+ Integer count();
+
+ void dropTableIfExist();
+
+ void createTable();
}
\ No newline at end of file
diff --git a/plain-java-mybatis/src/main/java/com/pingcap/model/PlayerMapperEx.java b/plain-java-mybatis/src/main/java/com/pingcap/model/PlayerMapperEx.java
deleted file mode 100644
index ce1dd88..0000000
--- a/plain-java-mybatis/src/main/java/com/pingcap/model/PlayerMapperEx.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2022 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.pingcap.model;
-
-import java.util.List;
-
-/**
- * PlayerMapperEx
- *
- * @author Icemap
- * @date 2022/5/23
- */
-public interface PlayerMapperEx extends PlayerMapper {
- Player selectByPrimaryKeyWithLock(String id);
-
- List selectByLimit(Integer limit);
-
- Integer count();
-}
diff --git a/plain-java-mybatis/src/main/resources/dbinit.sql b/plain-java-mybatis/src/main/resources/dbinit.sql
deleted file mode 100644
index 6e70f2a..0000000
--- a/plain-java-mybatis/src/main/resources/dbinit.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-USE test;
-DROP TABLE IF EXISTS player;
-
-CREATE TABLE player (
- `id` VARCHAR(36),
- `coins` INTEGER,
- `goods` INTEGER,
- PRIMARY KEY (`id`)
-);
\ No newline at end of file
diff --git a/plain-java-mybatis/src/main/resources/log4j.properties b/plain-java-mybatis/src/main/resources/log4j.properties
index 6ff86ce..ebbe359 100644
--- a/plain-java-mybatis/src/main/resources/log4j.properties
+++ b/plain-java-mybatis/src/main/resources/log4j.properties
@@ -1,5 +1,5 @@
-log4j.rootLogger=DEBUG,stdout
-log4j.logger.org.mybatis=DEBUG
+log4j.rootLogger=INFO,stdout
+log4j.logger.org.mybatis=INFO
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n
\ No newline at end of file
diff --git a/plain-java-mybatis/src/main/resources/mapper/PlayerMapper.xml b/plain-java-mybatis/src/main/resources/mapper/PlayerMapper.xml
index 6108651..c89e300 100644
--- a/plain-java-mybatis/src/main/resources/mapper/PlayerMapper.xml
+++ b/plain-java-mybatis/src/main/resources/mapper/PlayerMapper.xml
@@ -70,4 +70,34 @@
goods = #{goods,jdbcType=INTEGER}
where id = #{id,jdbcType=VARCHAR}
+
+
+
+
+
+
+
+ DROP TABLE IF EXISTS player;
+
+
+ CREATE TABLE player (
+ `id` VARCHAR(36),
+ `coins` INTEGER,
+ `goods` INTEGER,
+ PRIMARY KEY (`id`)
+ );
+
\ No newline at end of file
diff --git a/plain-java-mybatis/src/main/resources/mapper/PlayerMapperEx.xml b/plain-java-mybatis/src/main/resources/mapper/PlayerMapperEx.xml
deleted file mode 100644
index ff42fac..0000000
--- a/plain-java-mybatis/src/main/resources/mapper/PlayerMapperEx.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- id, coins, goods
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plain-java-mybatis/src/main/resources/mybatis-config.xml b/plain-java-mybatis/src/main/resources/mybatis-config.xml
index 78fe435..e95dada 100644
--- a/plain-java-mybatis/src/main/resources/mybatis-config.xml
+++ b/plain-java-mybatis/src/main/resources/mybatis-config.xml
@@ -38,17 +38,16 @@
-
-
-
-
+
+
+
+
-
\ No newline at end of file
diff --git a/plain-java-mybatis/src/main/resources/mybatis-generator.xml b/plain-java-mybatis/src/main/resources/mybatis-generator.xml
deleted file mode 100644
index 2bab89f..0000000
--- a/plain-java-mybatis/src/main/resources/mybatis-generator.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plain-java-txn-optimistic/Makefile b/plain-java-txn-optimistic/Makefile
index a66d565..e469457 100644
--- a/plain-java-txn-optimistic/Makefile
+++ b/plain-java-txn-optimistic/Makefile
@@ -15,19 +15,13 @@
.PHONY: all prepare re-prepare build not-oversell oversell
all:
- make build prepare not-oversell re-prepare oversell
-
-prepare:
- tiup demo bookshop prepare --drop-tables --books 0 --authors 0 --orders 0 --ratings 0 --users 0
-
-re-prepare:
- tiup demo bookshop prepare --drop-tables --books 0 --authors 0 --orders 0 --ratings 0 --users 0
+ . ../env.sh && make build not-oversell oversell
build:
mvn clean package
not-oversell:
- java -jar target/plain-java-txn-optimistic-0.0.1-jar-with-dependencies.jar ALICE_NUM=4 BOB_NUM=6
+ export ALICE_NUM=4 && export BOB_NUM=6 && java -jar target/plain-java-txn-optimistic-jar-with-dependencies.jar
oversell:
- java -jar target/plain-java-txn-optimistic-0.0.1-jar-with-dependencies.jar ALICE_NUM=4 BOB_NUM=7
\ No newline at end of file
+ export ALICE_NUM=4 && export BOB_NUM=7 && java -jar target/plain-java-txn-optimistic-jar-with-dependencies.jar
\ No newline at end of file
diff --git a/plain-java-txn-optimistic/pom.xml b/plain-java-txn-optimistic/pom.xml
index a30f8a8..51c2c39 100644
--- a/plain-java-txn-optimistic/pom.xml
+++ b/plain-java-txn-optimistic/pom.xml
@@ -57,6 +57,7 @@
+ ${project.name}
org.apache.maven.plugins
diff --git a/plain-java-txn-optimistic/src/main/java/com/pingcap/txn/OptimisticTxnExample.java b/plain-java-txn-optimistic/src/main/java/com/pingcap/txn/OptimisticTxnExample.java
index 87f96c8..6439ec3 100644
--- a/plain-java-txn-optimistic/src/main/java/com/pingcap/txn/OptimisticTxnExample.java
+++ b/plain-java-txn-optimistic/src/main/java/com/pingcap/txn/OptimisticTxnExample.java
@@ -1,38 +1,31 @@
package com.pingcap.txn;
import com.zaxxer.hikari.HikariDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.sql.*;
-import java.util.Arrays;
+import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class OptimisticTxnExample {
- public static void main(String[] args) throws SQLException, InterruptedException {
- System.out.println(Arrays.toString(args));
- int aliceQuantity = 0;
- int bobQuantity = 0;
-
- for (String arg: args) {
- if (arg.startsWith("ALICE_NUM")) {
- aliceQuantity = Integer.parseInt(arg.replace("ALICE_NUM=", ""));
- }
+ private static final Logger LOGGER = LoggerFactory.getLogger(OptimisticTxnExample.class);
- if (arg.startsWith("BOB_NUM")) {
- bobQuantity = Integer.parseInt(arg.replace("BOB_NUM=", ""));
- }
- }
+ public static void main(String[] args) throws SQLException, InterruptedException {
+ int aliceQuantity = Integer.parseInt(System.getenv().getOrDefault("ALICE_NUM", "4"));
+ int bobQuantity = Integer.parseInt(System.getenv().getOrDefault("BOB_NUM", "6"));
- HikariDataSource ds = new HikariDataSource();
- ds.setJdbcUrl("jdbc:mysql://localhost:4000/bookshop?useServerPrepStmts=true&cachePrepStmts=true");
- ds.setUsername("root");
- ds.setPassword("");
+ HikariDataSource ds = createHikariDataSourceByEnv();
// prepare data
Connection connection = ds.getConnection();
+ recreateUsersTable(connection);
+ recreateBooksTable(connection);
+ recreateOrdersTable(connection);
createBook(connection, 1L, "Designing Data-Intensive Application", "Science & Technology",
Timestamp.valueOf("2018-09-01 00:00:00"), new BigDecimal(100), 10);
createUser(connection, 1L, "Bob", new BigDecimal(10000));
@@ -57,38 +50,20 @@ public static void main(String[] args) throws SQLException, InterruptedException
System.exit(0);
}
- public static void createUser(Connection connection, Long id, String nickname, BigDecimal balance) throws SQLException {
- PreparedStatement insert = connection.prepareStatement(
- "INSERT INTO `users` (`id`, `nickname`, `balance`) VALUES (?, ?, ?)");
- insert.setLong(1, id);
- insert.setString(2, nickname);
- insert.setBigDecimal(3, balance);
- insert.executeUpdate();
- }
-
- public static void createBook(Connection connection, Long id, String title, String type, Timestamp publishedAt, BigDecimal price, Integer stock) throws SQLException {
- PreparedStatement insert = connection.prepareStatement(
- "INSERT INTO `books` (`id`, `title`, `type`, `published_at`, `price`, `stock`) values (?, ?, ?, ?, ?, ?)");
- insert.setLong(1, id);
- insert.setString(2, title);
- insert.setString(3, type);
- insert.setTimestamp(4, publishedAt);
- insert.setBigDecimal(5, price);
- insert.setInt(6, stock);
-
- insert.executeUpdate();
- }
-
public static void buy (HikariDataSource ds, Integer threadID, Long orderID, Long bookID,
Long userID, Integer quantity, Integer retryTimes) {
- String txnComment = "/* txn " + threadID + " */ ";
+ String txnComment = "/* txn {} */ ";
+ if (threadID != 1) {
+ txnComment = " " + txnComment;
+ }
+ LOGGER.info("user {} try to buy {} books, book id: {}", userID, quantity, bookID);
- System.out.printf("\nuser %d try to buy %d books(id: %d)\n", userID, quantity, bookID);
try (Connection connection = ds.getConnection()) {
try {
connection.setAutoCommit(false);
- connection.createStatement().executeUpdate(txnComment + "begin optimistic");
+ connection.createStatement().executeUpdate("begin optimistic");
+ LOGGER.info(txnComment + "begin optimistic", threadID);
// waiting for other thread ran the 'begin optimistic' statement
TimeUnit.SECONDS.sleep(1);
@@ -96,9 +71,10 @@ public static void buy (HikariDataSource ds, Integer threadID, Long orderID, Lon
BigDecimal price = null;
// read price of book
- PreparedStatement selectBook = connection.prepareStatement(txnComment + "select * from books where id = ? for update");
+ PreparedStatement selectBook = connection.prepareStatement("select * from books where id = ? for update");
selectBook.setLong(1, bookID);
ResultSet res = selectBook.executeQuery();
+ LOGGER.info(txnComment + "select * from books where id = {} for update", threadID, bookID);
if (!res.next()) {
throw new RuntimeException("book not exist");
} else {
@@ -111,20 +87,24 @@ public static void buy (HikariDataSource ds, Integer threadID, Long orderID, Lon
// update book
String updateBookSQL = "update `books` set stock = stock - ? where id = ? and stock - ? >= 0";
- PreparedStatement updateBook = connection.prepareStatement(txnComment + updateBookSQL);
+ PreparedStatement updateBook = connection.prepareStatement(updateBookSQL);
updateBook.setInt(1, quantity);
updateBook.setLong(2, bookID);
updateBook.setInt(3, quantity);
updateBook.executeUpdate();
+ LOGGER.info(txnComment + "update `books` set stock = stock - {} where id = {} and stock - {} >= 0",
+ threadID, quantity, bookID, quantity);
// insert order
String insertOrderSQL = "insert into `orders` (`id`, `book_id`, `user_id`, `quality`) values (?, ?, ?, ?)";
- PreparedStatement insertOrder = connection.prepareStatement(txnComment + insertOrderSQL);
+ PreparedStatement insertOrder = connection.prepareStatement(insertOrderSQL);
insertOrder.setLong(1, orderID);
insertOrder.setLong(2, bookID);
insertOrder.setLong(3, userID);
insertOrder.setInt(4, quantity);
insertOrder.executeUpdate();
+ LOGGER.info(txnComment + "insert into `orders` (`id`, `book_id`, `user_id`, `quality`) values ({}, {}, {}, {})",
+ threadID, orderID, bookID, userID, quantity);
// update user
String updateUserSQL = "update `users` set `balance` = `balance` - ? where id = ?";
@@ -132,12 +112,16 @@ public static void buy (HikariDataSource ds, Integer threadID, Long orderID, Lon
updateUser.setBigDecimal(1, price.multiply(new BigDecimal(quantity)));
updateUser.setLong(2, userID);
updateUser.executeUpdate();
+ LOGGER.info(txnComment + "update `users` set `balance` = `balance` - {} where id = {}",
+ threadID, price.multiply(new BigDecimal(quantity)), userID);
- connection.createStatement().executeUpdate(txnComment + "commit");
- System.out.printf("\nuser %d buy %d books(id: %d) successfully\n", userID, quantity, bookID);
+ connection.createStatement().executeUpdate("commit");
+ LOGGER.info(txnComment + "commit", threadID);
+ LOGGER.info("user {} buy {} books(id: {}) successfully", userID, quantity, bookID);
} catch (Exception e) {
connection.createStatement().executeUpdate(txnComment + "rollback");
- System.out.printf("\nuser %d fail to buy %d books(id: %d) because %s error\n", userID, quantity, bookID, e.getMessage());
+ LOGGER.info(txnComment + "rollback", threadID);
+ LOGGER.info("user {} fail to buy {} books(id: {}) because {} error", userID, quantity, bookID, e.getMessage());
if (e instanceof SQLException sqlException) {
switch (sqlException.getErrorCode()) {
@@ -147,7 +131,7 @@ public static void buy (HikariDataSource ds, Integer threadID, Long orderID, Lon
case 8002: // "SELECT FOR UPDATE" commit conflict
case 8022: // The transaction commit fails and has been rolled back
if (retryTimes != 0) {
- System.out.println("rest " + retryTimes + " times. retry for " + e.getMessage());
+ LOGGER.info("rest {} times. retry for {}", retryTimes, e.getMessage());
buy(ds, threadID, orderID, bookID, userID, quantity, retryTimes - 1);
}
}
@@ -157,4 +141,83 @@ public static void buy (HikariDataSource ds, Integer threadID, Long orderID, Lon
e.printStackTrace();
}
}
+
+ public static HikariDataSource createHikariDataSourceByEnv() {
+ // 1. Get TiDB connection properties from environment variables.
+ String tidbJDBCURL = System.getenv().getOrDefault("TIDB_JDBC_URL", "jdbc:mysql://localhost:4000/test");
+ String tidbUser = System.getenv().getOrDefault("TIDB_USER", "root");
+ String tidbPassword = System.getenv().getOrDefault("TIDB_PASSWORD", "");
+
+ HikariDataSource ds = new HikariDataSource();
+ ds.setJdbcUrl(tidbJDBCURL);
+ ds.setUsername(tidbUser);
+ ds.setPassword(tidbPassword);
+
+ return ds;
+ }
+
+ public static void recreateOrdersTable(Connection connection) throws SQLException {
+ connection.prepareStatement("DROP TABLE IF EXISTS `orders`").execute();
+ connection.prepareStatement("""
+ CREATE TABLE `orders` (
+ `id` bigint(20) NOT NULL,
+ `book_id` bigint(20) NOT NULL,
+ `user_id` bigint(20) NOT NULL,
+ `quality` tinyint(4) NOT NULL,
+ `ordered_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
+ KEY `orders_book_id_idx` (`book_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+ """).execute();
+ }
+
+ public static void recreateUsersTable(Connection connection) throws SQLException {
+ connection.prepareStatement("DROP TABLE IF EXISTS `users`").execute();
+ connection.prepareStatement("""
+ CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL,
+ `balance` decimal(15,2) DEFAULT '0.0',
+ `nickname` varchar(100) NOT NULL,
+ PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
+ UNIQUE KEY `nickname` (`nickname`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+ """).execute();
+ }
+
+ public static void recreateBooksTable(Connection connection) throws SQLException {
+ connection.prepareStatement("DROP TABLE IF EXISTS `books`").execute();
+ connection.prepareStatement("""
+ CREATE TABLE `books` (
+ `id` bigint(20) NOT NULL,
+ `title` varchar(100) NOT NULL,
+ `type` enum('Magazine','Novel','Life','Arts','Comics','Education & Reference','Humanities & Social Sciences','Science & Technology','Kids','Sports') NOT NULL,
+ `published_at` datetime NOT NULL,
+ `stock` int(11) DEFAULT '0',
+ `price` decimal(15,2) DEFAULT '0.0',
+ PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+ """).execute();
+ }
+
+ public static void createUser(Connection connection, Long id, String nickname, BigDecimal balance) throws SQLException {
+ PreparedStatement insert = connection.prepareStatement(
+ "INSERT INTO `users` (`id`, `nickname`, `balance`) VALUES (?, ?, ?)");
+ insert.setLong(1, id);
+ insert.setString(2, nickname);
+ insert.setBigDecimal(3, balance);
+ insert.executeUpdate();
+ }
+
+ public static void createBook(Connection connection, Long id, String title, String type, Timestamp publishedAt, BigDecimal price, Integer stock) throws SQLException {
+ PreparedStatement insert = connection.prepareStatement(
+ "INSERT INTO `books` (`id`, `title`, `type`, `published_at`, `price`, `stock`) values (?, ?, ?, ?, ?, ?)");
+ insert.setLong(1, id);
+ insert.setString(2, title);
+ insert.setString(3, type);
+ insert.setTimestamp(4, publishedAt);
+ insert.setBigDecimal(5, price);
+ insert.setInt(6, stock);
+
+ insert.executeUpdate();
+ }
}
diff --git a/plain-java-txn-optimistic/src/main/resources/logback.xml b/plain-java-txn-optimistic/src/main/resources/logback.xml
new file mode 100644
index 0000000..e5a1799
--- /dev/null
+++ b/plain-java-txn-optimistic/src/main/resources/logback.xml
@@ -0,0 +1,11 @@
+
+
+
+ %d{HH:mm:ss.SSS} %-5level %logger{80} - %msg%n
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plain-java-txn-pessimistic/Makefile b/plain-java-txn-pessimistic/Makefile
index da097ce..b14a53c 100644
--- a/plain-java-txn-pessimistic/Makefile
+++ b/plain-java-txn-pessimistic/Makefile
@@ -12,22 +12,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-.PHONY: all prepare re-prepare build not-oversell oversell
+.PHONY: all build not-oversell oversell
all:
- make build prepare not-oversell re-prepare oversell
-
-prepare:
- tiup demo bookshop prepare --drop-tables --books 0 --authors 0 --orders 0 --ratings 0 --users 0
-
-re-prepare:
- tiup demo bookshop prepare --drop-tables --books 0 --authors 0 --orders 0 --ratings 0 --users 0
+ . ../env.sh && make build not-oversell oversell
build:
mvn clean package
not-oversell:
- java -jar target/plain-java-txn-pessimistic-0.0.1-jar-with-dependencies.jar ALICE_NUM=4 BOB_NUM=6
+ export ALICE_NUM=4 && export BOB_NUM=6 && java -jar target/plain-java-txn-pessimistic-jar-with-dependencies.jar
oversell:
- java -jar target/plain-java-txn-pessimistic-0.0.1-jar-with-dependencies.jar ALICE_NUM=4 BOB_NUM=7
\ No newline at end of file
+ export ALICE_NUM=4 && export BOB_NUM=7 && java -jar target/plain-java-txn-pessimistic-jar-with-dependencies.jar
\ No newline at end of file
diff --git a/plain-java-txn-pessimistic/pom.xml b/plain-java-txn-pessimistic/pom.xml
index 2a675b2..3340090 100644
--- a/plain-java-txn-pessimistic/pom.xml
+++ b/plain-java-txn-pessimistic/pom.xml
@@ -57,6 +57,7 @@
+ ${project.name}
org.apache.maven.plugins
diff --git a/plain-java-txn-pessimistic/src/main/java/com/pingcap/txn/PessimisticTxnExample.java b/plain-java-txn-pessimistic/src/main/java/com/pingcap/txn/PessimisticTxnExample.java
index a4f4316..66d329d 100644
--- a/plain-java-txn-pessimistic/src/main/java/com/pingcap/txn/PessimisticTxnExample.java
+++ b/plain-java-txn-pessimistic/src/main/java/com/pingcap/txn/PessimisticTxnExample.java
@@ -1,35 +1,29 @@
package com.pingcap.txn;
import com.zaxxer.hikari.HikariDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.sql.*;
import java.util.Arrays;
+import java.util.Properties;
import java.util.concurrent.*;
public class PessimisticTxnExample {
- public static void main(String[] args) throws SQLException, InterruptedException {
- System.out.println(Arrays.toString(args));
- int aliceQuantity = 0;
- int bobQuantity = 0;
-
- for (String arg: args) {
- if (arg.startsWith("ALICE_NUM")) {
- aliceQuantity = Integer.parseInt(arg.replace("ALICE_NUM=", ""));
- }
+ private static final Logger LOGGER = LoggerFactory.getLogger(PessimisticTxnExample.class);
- if (arg.startsWith("BOB_NUM")) {
- bobQuantity = Integer.parseInt(arg.replace("BOB_NUM=", ""));
- }
- }
+ public static void main(String[] args) throws SQLException, InterruptedException {
+ int aliceQuantity = Integer.parseInt(System.getenv().getOrDefault("ALICE_NUM", "4"));
+ int bobQuantity = Integer.parseInt(System.getenv().getOrDefault("BOB_NUM", "6"));
- HikariDataSource ds = new HikariDataSource();
- ds.setJdbcUrl("jdbc:mysql://localhost:4000/bookshop?useServerPrepStmts=true&cachePrepStmts=true");
- ds.setUsername("root");
- ds.setPassword("");
+ HikariDataSource ds = createHikariDataSourceByEnv();
// prepare data
Connection connection = ds.getConnection();
+ recreateUsersTable(connection);
+ recreateBooksTable(connection);
+ recreateOrdersTable(connection);
createBook(connection, 1L, "Designing Data-Intensive Application", "Science & Technology",
Timestamp.valueOf("2018-09-01 00:00:00"), new BigDecimal(100), 10);
createUser(connection, 1L, "Bob", new BigDecimal(10000));
@@ -53,37 +47,19 @@ public static void main(String[] args) throws SQLException, InterruptedException
System.exit(0);
}
- public static void createUser(Connection connection, Long id, String nickname, BigDecimal balance) throws SQLException {
- PreparedStatement insert = connection.prepareStatement(
- "INSERT INTO `users` (`id`, `nickname`, `balance`) VALUES (?, ?, ?)");
- insert.setLong(1, id);
- insert.setString(2, nickname);
- insert.setBigDecimal(3, balance);
- insert.executeUpdate();
- }
-
- public static void createBook(Connection connection, Long id, String title, String type, Timestamp publishedAt, BigDecimal price, Integer stock) throws SQLException {
- PreparedStatement insert = connection.prepareStatement(
- "INSERT INTO `books` (`id`, `title`, `type`, `published_at`, `price`, `stock`) values (?, ?, ?, ?, ?, ?)");
- insert.setLong(1, id);
- insert.setString(2, title);
- insert.setString(3, type);
- insert.setTimestamp(4, publishedAt);
- insert.setBigDecimal(5, price);
- insert.setInt(6, stock);
-
- insert.executeUpdate();
- }
-
public static void buy (HikariDataSource ds, Integer threadID,
Long orderID, Long bookID, Long userID, Integer quantity) {
- String txnComment = "/* txn " + threadID + " */ ";
- System.out.printf("\nuser %d try to buy %d books, book id: %d\n", userID, quantity, bookID);
+ String txnComment = "/* txn {} */ ";
+ if (threadID != 1) {
+ txnComment = " " + txnComment;
+ }
+ LOGGER.info("user {} try to buy {} books, book id: {}", userID, quantity, bookID);
try (Connection connection = ds.getConnection()) {
try {
connection.setAutoCommit(false);
- connection.createStatement().executeUpdate(txnComment + "begin pessimistic");
+ connection.createStatement().executeUpdate("begin pessimistic");
+ LOGGER.info(txnComment + "begin pessimistic", threadID);
// waiting for other thread ran the 'begin pessimistic' statement
TimeUnit.SECONDS.sleep(1);
@@ -91,9 +67,10 @@ public static void buy (HikariDataSource ds, Integer threadID,
BigDecimal price = null;
// read price of book
- PreparedStatement selectBook = connection.prepareStatement(txnComment + "select price from books where id = ? for update");
+ PreparedStatement selectBook = connection.prepareStatement("select price from books where id = ? for update");
selectBook.setLong(1, bookID);
ResultSet res = selectBook.executeQuery();
+ LOGGER.info(txnComment + "select price from books where id = {} for update", threadID, bookID);
if (!res.next()) {
throw new RuntimeException("book not exist");
} else {
@@ -102,43 +79,131 @@ public static void buy (HikariDataSource ds, Integer threadID,
// update book
String updateBookSQL = "update `books` set stock = stock - ? where id = ? and stock - ? >= 0";
- PreparedStatement updateBook = connection.prepareStatement(txnComment + updateBookSQL);
+ PreparedStatement updateBook = connection.prepareStatement(updateBookSQL);
updateBook.setInt(1, quantity);
updateBook.setLong(2, bookID);
updateBook.setInt(3, quantity);
int affectedRows = updateBook.executeUpdate();
+ LOGGER.info(txnComment + "update `books` set stock = stock - {} where id = {} and stock - {} >= 0",
+ threadID, quantity, bookID, quantity);
if (affectedRows == 0) {
// stock not enough, rollback
connection.createStatement().executeUpdate(txnComment + "rollback");
+ LOGGER.info(txnComment + "rollback", threadID);
return;
}
// insert order
String insertOrderSQL = "insert into `orders` (`id`, `book_id`, `user_id`, `quality`) values (?, ?, ?, ?)";
- PreparedStatement insertOrder = connection.prepareStatement(txnComment + insertOrderSQL);
+ PreparedStatement insertOrder = connection.prepareStatement(insertOrderSQL);
insertOrder.setLong(1, orderID);
insertOrder.setLong(2, bookID);
insertOrder.setLong(3, userID);
insertOrder.setInt(4, quantity);
insertOrder.executeUpdate();
+ LOGGER.info(txnComment + "insert into `orders` (`id`, `book_id`, `user_id`, `quality`) values ({}, {}, {}, {})",
+ threadID, orderID, bookID, userID, quantity);
// update user
String updateUserSQL = "update `users` set `balance` = `balance` - ? where id = ?";
- PreparedStatement updateUser = connection.prepareStatement(txnComment + updateUserSQL);
+ PreparedStatement updateUser = connection.prepareStatement(updateUserSQL);
updateUser.setBigDecimal(1, price.multiply(new BigDecimal(quantity)));
updateUser.setLong(2, userID);
updateUser.executeUpdate();
+ LOGGER.info(txnComment + "update `users` set `balance` = `balance` - {} where id = {}",
+ threadID, price.multiply(new BigDecimal(quantity)), userID);
- connection.createStatement().executeUpdate(txnComment + "commit");
- System.out.printf("\nuser %d buy %d books(id: %d) successfully\n", userID, quantity, bookID);
+ connection.createStatement().executeUpdate("commit");
+ LOGGER.info(txnComment + "commit", threadID);
+ LOGGER.info("user {} buy {} books(id: {}) successfully", userID, quantity, bookID);
} catch (Exception e) {
- connection.createStatement().executeUpdate(txnComment + "rollback");
- System.out.printf("\nuser %d fail to buy %d books(id: %d) because %s error\n", userID, quantity, bookID, e.getMessage());
- e.printStackTrace();
+ connection.createStatement().executeUpdate("rollback");
+ LOGGER.info(txnComment + "rollback", threadID);
+ LOGGER.info("user {} fail to buy {} books(id: {}) because {} error", userID, quantity, bookID, e.getMessage());
}
} catch (SQLException e) {
e.printStackTrace();
}
}
+
+ public static HikariDataSource createHikariDataSourceByEnv() {
+ // 1. Get TiDB connection properties from environment variables.
+ // 1. Get TiDB connection properties from environment variables.
+ String tidbJDBCURL = System.getenv().getOrDefault("TIDB_JDBC_URL", "jdbc:mysql://localhost:4000/test");
+ String tidbUser = System.getenv().getOrDefault("TIDB_USER", "root");
+ String tidbPassword = System.getenv().getOrDefault("TIDB_PASSWORD", "");
+
+ HikariDataSource ds = new HikariDataSource();
+ ds.setJdbcUrl(tidbJDBCURL);
+ ds.setUsername(tidbUser);
+ ds.setPassword(tidbPassword);
+
+ return ds;
+ }
+
+ public static void recreateOrdersTable(Connection connection) throws SQLException {
+ connection.prepareStatement("DROP TABLE IF EXISTS `orders`").execute();
+ connection.prepareStatement("""
+ CREATE TABLE `orders` (
+ `id` bigint(20) NOT NULL,
+ `book_id` bigint(20) NOT NULL,
+ `user_id` bigint(20) NOT NULL,
+ `quality` tinyint(4) NOT NULL,
+ `ordered_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
+ KEY `orders_book_id_idx` (`book_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+ """).execute();
+ }
+
+ public static void recreateUsersTable(Connection connection) throws SQLException {
+ connection.prepareStatement("DROP TABLE IF EXISTS `users`").execute();
+ connection.prepareStatement("""
+ CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL,
+ `balance` decimal(15,2) DEFAULT '0.0',
+ `nickname` varchar(100) NOT NULL,
+ PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
+ UNIQUE KEY `nickname` (`nickname`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+ """).execute();
+ }
+
+ public static void recreateBooksTable(Connection connection) throws SQLException {
+ connection.prepareStatement("DROP TABLE IF EXISTS `books`").execute();
+ connection.prepareStatement("""
+ CREATE TABLE `books` (
+ `id` bigint(20) NOT NULL,
+ `title` varchar(100) NOT NULL,
+ `type` enum('Magazine','Novel','Life','Arts','Comics','Education & Reference','Humanities & Social Sciences','Science & Technology','Kids','Sports') NOT NULL,
+ `published_at` datetime NOT NULL,
+ `stock` int(11) DEFAULT '0',
+ `price` decimal(15,2) DEFAULT '0.0',
+ PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+ """).execute();
+ }
+
+ public static void createUser(Connection connection, Long id, String nickname, BigDecimal balance) throws SQLException {
+ PreparedStatement insert = connection.prepareStatement(
+ "INSERT INTO `users` (`id`, `nickname`, `balance`) VALUES (?, ?, ?)");
+ insert.setLong(1, id);
+ insert.setString(2, nickname);
+ insert.setBigDecimal(3, balance);
+ insert.executeUpdate();
+ }
+
+ public static void createBook(Connection connection, Long id, String title, String type, Timestamp publishedAt, BigDecimal price, Integer stock) throws SQLException {
+ PreparedStatement insert = connection.prepareStatement(
+ "INSERT INTO `books` (`id`, `title`, `type`, `published_at`, `price`, `stock`) values (?, ?, ?, ?, ?, ?)");
+ insert.setLong(1, id);
+ insert.setString(2, title);
+ insert.setString(3, type);
+ insert.setTimestamp(4, publishedAt);
+ insert.setBigDecimal(5, price);
+ insert.setInt(6, stock);
+
+ insert.executeUpdate();
+ }
}
\ No newline at end of file
diff --git a/plain-java-txn-pessimistic/src/main/resources/logback.xml b/plain-java-txn-pessimistic/src/main/resources/logback.xml
new file mode 100644
index 0000000..e5a1799
--- /dev/null
+++ b/plain-java-txn-pessimistic/src/main/resources/logback.xml
@@ -0,0 +1,11 @@
+
+
+
+ %d{HH:mm:ss.SSS} %-5level %logger{80} - %msg%n
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plain-java-write-skew/Makefile b/plain-java-write-skew/Makefile
index 83a3879..9488cb9 100644
--- a/plain-java-write-skew/Makefile
+++ b/plain-java-write-skew/Makefile
@@ -15,7 +15,7 @@
.PHONY: all build run
all:
- make build run
+ . ../env.sh && make build run
build:
mvn clean package
diff --git a/plain-java-write-skew/src/main/java/com/pingcap/EffectWriteSkew.java b/plain-java-write-skew/src/main/java/com/pingcap/EffectWriteSkew.java
index e1d32e4..34fd660 100644
--- a/plain-java-write-skew/src/main/java/com/pingcap/EffectWriteSkew.java
+++ b/plain-java-write-skew/src/main/java/com/pingcap/EffectWriteSkew.java
@@ -33,13 +33,11 @@
*/
public class EffectWriteSkew {
public static void main(String[] args) throws SQLException, InterruptedException {
- HikariDataSource ds = new HikariDataSource();
- ds.setJdbcUrl("jdbc:mysql://localhost:4000/test?useServerPrepStmts=true&cachePrepStmts=true");
- ds.setUsername("root");
+ HikariDataSource ds = createHikariDataSourceByEnv();
// prepare data
Connection connection = ds.getConnection();
- createDoctorTable(connection);
+ recreateDoctorTable(connection);
createDoctor(connection, 1, "Alice", true, 123);
createDoctor(connection, 2, "Bob", true, 123);
createDoctor(connection, 3, "Carol", false, 123);
@@ -63,7 +61,8 @@ public static void main(String[] args) throws SQLException, InterruptedException
System.exit(0);
}
- public static void createDoctorTable(Connection connection) throws SQLException {
+ public static void recreateDoctorTable(Connection connection) throws SQLException {
+ connection.createStatement().executeUpdate("DROP TABLE IF EXISTS `doctors`");
connection.createStatement().executeUpdate("CREATE TABLE `doctors` (" +
" `id` int(11) NOT NULL," +
" `name` varchar(255) DEFAULT NULL," +
@@ -135,4 +134,19 @@ public static void askForLeave(HikariDataSource ds, Semaphore txn1Pass, Integer
e.printStackTrace();
}
}
+
+ public static HikariDataSource createHikariDataSourceByEnv() {
+ // 1. Get TiDB connection properties from environment variables.
+ // 1. Get TiDB connection properties from environment variables.
+ String tidbJDBCURL = System.getenv().getOrDefault("TIDB_JDBC_URL", "jdbc:mysql://localhost:4000/test");
+ String tidbUser = System.getenv().getOrDefault("TIDB_USER", "root");
+ String tidbPassword = System.getenv().getOrDefault("TIDB_PASSWORD", "");
+
+ HikariDataSource ds = new HikariDataSource();
+ ds.setJdbcUrl(tidbJDBCURL);
+ ds.setUsername(tidbUser);
+ ds.setPassword(tidbPassword);
+
+ return ds;
+ }
}
diff --git a/plain-java-write-skew/src/main/resources/logback.xml b/plain-java-write-skew/src/main/resources/logback.xml
new file mode 100644
index 0000000..e5a1799
--- /dev/null
+++ b/plain-java-write-skew/src/main/resources/logback.xml
@@ -0,0 +1,11 @@
+
+
+
+ %d{HH:mm:ss.SSS} %-5level %logger{80} - %msg%n
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-jpa-hibernate/Makefile b/spring-jpa-hibernate/Makefile
index 49e6cbb..75b49dc 100644
--- a/spring-jpa-hibernate/Makefile
+++ b/spring-jpa-hibernate/Makefile
@@ -15,7 +15,7 @@
.PHONY: all build run stop
all:
- make build run
+ . ../env.sh && make build run
build:
mvn clean package
diff --git a/spring-jpa-hibernate/src/main/resources/application.yml b/spring-jpa-hibernate/src/main/resources/application.yml
index dee948f..f5fc3c5 100644
--- a/spring-jpa-hibernate/src/main/resources/application.yml
+++ b/spring-jpa-hibernate/src/main/resources/application.yml
@@ -1,8 +1,8 @@
spring:
datasource:
- url: jdbc:mysql://localhost:4000/test
- username: root
-# password: xxx
+ url: ${TIDB_JDBC_URL:jdbc:mysql://localhost:4000/test}
+ username: ${TIDB_USER:root}
+ password: ${TIDB_PASSWORD:}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true