build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.2.0.RELEASE"
id("io.spring.dependency-management") version "1.0.8.RELEASE"
kotlin("jvm") version "1.3.50"
kotlin("plugin.spring") version "1.3.50"
kotlin("plugin.jpa") version "1.3.50"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8
val developmentOnly by configurations.creating
configurations {
runtimeClasspath {
extendsFrom(developmentOnly)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.springframework.boot:spring-boot-starter-web")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test")
implementation("com.alibaba:druid:1.1.20")
implementation("com.dangdang:sharding-jdbc-core:1.5.4.1")
implementation("mysql:mysql-connector-java:8.0.18")
implementation("org.springframework.boot:spring-boot-starter-data-jpa:2.2.0.RELEASE")
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
core class
package com.example.blog.config
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm
import com.google.common.collect.Range
import org.springframework.stereotype.Component
@Component
class DatabaseShardingAlgorithm(val database0Config: Database0Config,
val database1Config: Database1Config) : SingleKeyDatabaseShardingAlgorithm<Long> {
override fun doInSharding(availableTargetNames: MutableCollection<String>?, shardingValue: ShardingValue<Long>?): MutableCollection<String> {
var result = mutableListOf<String>()
for ( value in shardingValue!!.values){
if(value <= 20L) result.add(database0Config.databaseName)
else result.add(database1Config.databaseName)
}
return result
}
override fun doEqualSharding(availableTargetNames: MutableCollection<String>?, shardingValue: ShardingValue<Long>?): String {
var value = shardingValue!!.value
var result = if(value <= 20L) database0Config.databaseName
else database1Config.databaseName
return result
}
override fun doBetweenSharding(availableTargetNames: MutableCollection<String>?, shardingValue: ShardingValue<Long>?): MutableCollection<String> {
var result = mutableListOf<String>()
var range : Range<Long> = shardingValue!!.valueRange
var lower = range.lowerEndpoint()
var upper = range.upperEndpoint()
for(value in lower..upper){
if(value <= 20L) result.add(database0Config.databaseName)
else result.add(database1Config.databaseName)
}
return result
}
}
@Component
class TableShardingAlgorithm(val database0Config: Database0Config,
val database1Config: Database1Config) : SingleKeyTableShardingAlgorithm<Long> {
override fun doInSharding(availableTargetNames: MutableCollection<String>?, shardingValue: ShardingValue<Long>?): MutableCollection<String> {
var result = mutableListOf<String>()
for(value in shardingValue!!.values){
for(tablename in availableTargetNames!!){
if(tablename.endsWith("${value%2}")){
result.add(tablename)
}
}
}
return result
}
override fun doEqualSharding(tablenames: MutableCollection<String>?, shardingValue: ShardingValue<Long>?): String {
tablenames!!.forEach {
if(it.endsWith("${shardingValue!!.value % 2}")) {
return it
}
}
throw IllegalArgumentException()
}
override fun doBetweenSharding(availableTargetNames: MutableCollection<String>?, shardingValue: ShardingValue<Long>?): MutableCollection<String> {
var result = mutableListOf<String>()
var range: Range<Long> = shardingValue!!.valueRange
var lower = range.lowerEndpoint()
var upper = range.upperEndpoint()
for(i in lower..upper){
for(name in availableTargetNames!!){
if(name.endsWith("${i%2}")){
result.add(name)
}
}
}
return result
}
}
package com.example.blog.config
import com.alibaba.druid.pool.DruidDataSource
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.stereotype.Component
import javax.sql.DataSource
@ConfigurationProperties(prefix = "database0")
@Component
class Database0Config {
var url: String = ""
var username: String = ""
var password: String = ""
var driverClassName: String = ""
var databaseName: String = ""
fun createDataSource(): DataSource {
var result = DruidDataSource()
result.url = this.url
result.username = this.username
result.password = this.password
result.driverClassName = this.driverClassName
return result
}
}
@ConfigurationProperties(prefix = "database1")
@Component
class Database1Config {
var url: String = ""
var username: String = ""
var password: String = ""
var driverClassName: String = ""
var databaseName: String = ""
fun createDataSource(): DataSource {
var result = DruidDataSource()
result.url = this.url
result.username = this.username
result.password = this.password
result.driverClassName = this.driverClassName
return result
}
}
package com.example.blog.config
import com.dangdang.ddframe.rdb.sharding.api.ShardingDataSourceFactory
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy
import com.dangdang.ddframe.rdb.sharding.keygen.DefaultKeyGenerator
import com.dangdang.ddframe.rdb.sharding.keygen.KeyGenerator
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import javax.sql.DataSource
@Configuration
open class DatasourceConfig(val database0Config: Database0Config,
val database1Config: Database1Config,
val databaseShardingAlgorithm: SingleKeyDatabaseShardingAlgorithm<Long>,
val tableShardingAlgorithm: SingleKeyTableShardingAlgorithm<Long>) {
@Bean
open fun getDataSource(): DataSource {
var map = mutableMapOf(
database0Config.databaseName to database0Config.createDataSource(),
database1Config.databaseName to database1Config.createDataSource())
var rule = DataSourceRule(map, database0Config.databaseName)
var table0: TableRule = TableRule.builder("goods")
.actualTables(listOf("goods_0", "goods_1"))
.dataSourceRule(rule).build()
var shardingRule = ShardingRule.builder()
.dataSourceRule(rule)
.tableRules(listOf(table0))
.databaseShardingStrategy(DatabaseShardingStrategy("goods_id", databaseShardingAlgorithm))
.tableShardingStrategy(TableShardingStrategy("goods_type", tableShardingAlgorithm))
.build()
return ShardingDataSourceFactory.createDataSource(shardingRule)
}
@Bean
open fun keyGenerator(): KeyGenerator {
return DefaultKeyGenerator()
}
}
package com.example.blog.entity
import javax.persistence.Entity
import javax.persistence.Id
import javax.persistence.Table
@Entity
@Table
class Goods {
@Id
var goodsId : Long = 0
var goodsName: String = ""
var goodsType: Long = 0
}
package com.example.blog.repository
import com.example.blog.entity.Goods
import org.springframework.data.jpa.repository.JpaRepository
interface GoodsRepository : JpaRepository<Goods,Long> {
fun findAllByGoodsIdBetween(goodsId1 : Long,goodsId2: Long) : List<Goods>
fun findAllByGoodsIdIn(goodsIds: List<Long>) : List<Goods>
}
package com.example.blog.rest
import com.example.blog.entity.Goods
import com.example.blog.repository.GoodsRepository
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class GoodsResouce(private val goodsRepository: GoodsRepository) {
@GetMapping("/save")
fun save() : String {
for(i in 0..40) {
var goods = Goods()
goods.goodsId = i.toLong()
goods.goodsName = "shangpin" + i
goods.goodsType = i.toLong() + 1
goodsRepository.save(goods)
}
return "Success"
}
@GetMapping("select")
fun select(): String = goodsRepository.findAll().toString()
@GetMapping("delete")
fun delete() = goodsRepository.deleteAll()
@GetMapping("query1")
fun query1() : Any = goodsRepository.findAllByGoodsIdBetween(10,30)
@GetMapping("query2")
fun query2() : Any = goodsRepository.findAllByGoodsIdIn(listOf(10,15,20,25))
}
package com.example.blog
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.runApplication
import org.springframework.transaction.annotation.EnableTransactionManagement
@SpringBootApplication(exclude = [DataSourceAutoConfiguration::class])
@EnableTransactionManagement(proxyTargetClass = true)
@EnableConfigurationProperties
open class BlogApplication
fun main(args: Array<String>) {
runApplication<BlogApplication>(*args)
}
##Jpa配置
spring.jpa.database: mysql
spring.jpa.show-sql: true
spring.jpa.hibernate.ddl-auto: none
##数据库配置
##数据库database0地址
database0.url: jdbc:mysql://localhost:3306/database0?characterEncoding=utf8&useSSL=false
##数据库database0用户名
database0.username: root
##数据库database0密码
database0.password: root
##数据库database0驱动
database0.driverClassName: com.mysql.cj.jdbc.Driver
##数据库database0名称
database0.databaseName: database0
##数据库database1地址
database1.url: jdbc:mysql://localhost:3306/database1?characterEncoding=utf8&useSSL=false
##数据库database1用户名
database1.username: root
##数据库database1密码
database1.password: root
##数据库database1驱动
database1.driverClassName: com.mysql.cj.jdbc.Driver
##数据库database1名称
database1.databaseName: database1
server.port: 8081