来自与之前的分布式项目,之前有
1.sprinboot单体项目升级成springcloud项目
2.分布式权限 shiro + jwt + redis
3.人人fast项目相关技术
4.给为服务添加运维模块 统一管理(第四期)
1.展示不同的数据库使用的是不同数据源的技术,
2.展示当前数据库所有的表结构,这块是对MySQL表的一些理解。第3.下载sql脚本 ,使用的是vecelity技术,方便快速的构建项目中锁需要的增删改查
4. 执行sql 脚本。可以使用网页端直接执行sql脚本。
5. shardingsphere 读写分离 主从库(主从复制 待完善)
6.项目中使用不同的数据库类型 oracle 和MySQL两种数据类型。从dao层注入改变。
7.不同的数据库设计到的操作数据库的框架(hibernate mybatis)(待完善)
二、第一个技术点 :
使用不同的技术源
@Component
@Primary
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* 当前使用数据源标识
*/
public static ThreadLocal<String> name = new ThreadLocal<String>();
@Autowired
DataSource datasource1;
@Autowired
DataSource datasource2;
@Override
protected Object determineCurrentLookupKey() {
return name.get();
}
@Override
public void afterPropertiesSet(){
Map<Object, Object> properties = new HashMap<Object, Object>();
properties.put("w",datasource1);
properties.put("r",datasource2);
super.setTargetDataSources(properties);
//设置默认的数据源
super.setDefaultTargetDataSource(datasource1);
super.afterPropertiesSet();
}
}
private void selectDynamicDatasource(@RequestParam Map<String, Object> params) {
String dataSource = (String) params.get("dataSource");
//这个也是需要动态的设置一下的
if(dataSource.equals("0")){
DynamicDataSource.name.set("r");
}
if(dataSource.equals("1")){
DynamicDataSource.name.set("w");
}
}
动态数据源
多数据源目前使用的代码
二、生成代码
<select id="queryList" resultType="map">
select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables
where table_schema = (select database())
<if test="tableName != null and tableName.trim() != ''">
and table_name like concat('%', #{tableName}, '%')
if>
order by create_time desc
select>
mysql涉及的表
information_schema详解。是MySQL自带的,它提供了访问数据库 元数据 的方式。什么是 元数据 呢?元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。
有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。
在MySQL中,把【INFORMATION_SCHEMA】 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。
在 【INFORMATION_SCHEMA 】中,有数个 只读 表。它们实际上是 视图 ,而不是基本表,因此,你将无法看到与之相关的任何文件。
注意:原因很简单information_schema是只读表,不能修改!
Oracle涉及的表
在工作中有时需要对现有数据库进行清理,统计,分析,这就需要知道库里有那些表,都有多少数据,在Oracle中,可用使用视图USER_TABLES:
SELECT * FROM USER_TABLES;
USER_TABLES提供了丰富的信息,其中较为重要的就是表中的数据行数(列NUM_ROWS),但这个列行数并不是准确的行数,可能与查询具体表的COUNT结果一致
这是因为num_rows是根据分析表后取得数据行数,必须先Analyze Table才能取得准确的数据行数。
如果想查询所有用户表中的列,可以使用USER_TAB_COLUMNS,可查询某个列都在哪些表中出现。
SELECT * FROM USER_TAB_COLUMNS;
另外,使用user_tables可查询当前用户的表;all_tables可查询所有用户的表;dba_tables查询包括系统表的所有表
三、生成代码的技术(之前写过)
利用java模板也是后台定义好的;
对于各种模板可以管理起来。要不然不方便
四、执行sql脚本
@Component
public class SystemConfig
{
@Autowired
SqlScriptRunner runner;
@Autowired
ActiveRecordPlugin arp;
/**
* 使用mysql数据库
* 使用者不需关注数据库配置的初始化过程,本demo是借助jfinal框架初始化的数据库配置,
* 使用者完全可以用其他方式代替
*/
public void initMysqlDruid()
{
arp.setDialect(new MysqlDialect());
arp.setDevMode(true);
arp.setShowSql(true);
arp.setContainerFactory(new CaseInsensitiveContainerFactory());
arp.start();
}
/**
* 表结构初始化
*/
public void initTableDesign()
{
Connection conn = null;
try
{
conn = Db.use().getConfig().getConnection();
URL systemResource = ClassLoader.getSystemResource("");
// E:\lang\project\git\micro_service_yan\yan\rose-modules\database\target\classes\sql
File file = new File("E:\\lang\\project\\git\\micro_service_yan\\yan\\rose-modules\\database\\target\\classes\\sql");
File[] files = file.listFiles();
if (files.length == 0)
{
return;
}
List<File> fileList = Arrays.asList(file.listFiles());
fileList.sort(Comparator.comparing(File::getName));
for (File requestFile : fileList)
{
// 如下代码是读者需要关注的
// SqlScriptRunner runner = new SqlScriptRunner(conn);
runner.setConnection(conn);
runner.setEscapeProcessing(false);
runner.setSendFullScript(false);
runner.setDelimiter(";;");
runner.runScript(new InputStreamReader(new FileInputStream(requestFile), "UTF-8"));
}
}
catch (Exception ex)
{
throw new RuntimeException("initTableDesign error!");
}
finally
{
Db.use().getConfig().close(conn);
}
}
}
执行的文件在
E:\\lang\\project\\git\\micro_service_yan\\yan\\rose-modules\\database\\target\\classes\\sql
自己的本地,后续改为可以传递参数。
五 、读写分离
shardingsphere 的使用方式
<dependency>
<groupId>org.apache.shardingspheregroupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starterartifactId>
<version>5.1.1version>
dependency>
目前来说使用了这些配置
shardingsphere:
props:
sql-show: true
mode:
type: Memory
datasource: # 配置数据源
names: yan,slave1,slave2 # 分库的逻辑库名,可配置多个
yan: # 逻辑库名
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/yan?characterEncoding=utf-8&useSSL=false&useUnicode=true&serverTimezone=UTC
username: root
password: 1942951600
slave1: # 逻辑库名
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/yan_slave?characterEncoding=utf-8&useSSL=false&useUnicode=true&serverTimezone=UTC
username: root
password: 1942951600
slave2: # 逻辑库名
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/yan_slave?characterEncoding=utf-8&useSSL=false&useUnicode=true&serverTimezone=UTC
username: root
password: 1942951600
master-slave-rules:
myds:
master-data-source-name: yan
slave-data-source-names: slave1,slave2
rules:
readwrite-splitting:
# replica-query:
data-sources:
# myds 定义的是上层的数据源
myds:
type: Static
props:
write-data-source-name: yan
# read-data-source-names: slave1,slave2
read-data-source-names: yan
# primary-data-source-name: yan
# replica-data-source-names: slave1,slave2
load-balancer-name: alg_round
load-balancers:
alg_round:
type: ROUND_ROBIN
六、从dao层改变连接;可以改变当下正在使用的数据库。设计到spring的技术。可以好好的研究一下。
/**
* 数据库配置
*
* @author Mark [email protected]
*/
@Configuration
public class DbConfig {
@Value("${renren.database: mysql}")
private String database;
@Autowired
private MySQLGeneratorDao mySQLGeneratorDao;
@Autowired
private OracleGeneratorDao oracleGeneratorDao;
@Autowired
private SQLServerGeneratorDao sqlServerGeneratorDao;
@Autowired
private PostgreSQLGeneratorDao postgreSQLGeneratorDao;
private static boolean mongo = false;
@Bean
@Primary
@Conditional(MongoNullCondition.class)
public GeneratorDao getGeneratorDao() {
if ("mysql".equalsIgnoreCase(database)) {
return mySQLGeneratorDao;
} else if ("oracle".equalsIgnoreCase(database)) {
return oracleGeneratorDao;
} else if ("sqlserver".equalsIgnoreCase(database)) {
return sqlServerGeneratorDao;
} else if ("postgresql".equalsIgnoreCase(database)) {
return postgreSQLGeneratorDao;
} else {
throw new RRException("不支持当前数据库:" + database);
}
}
@Bean
@Primary
@Conditional(MongoCondition.class)
public GeneratorDao getMongoDBDao(MongoDBGeneratorDao mongoDBGeneratorDao) {
mongo = true;
return mongoDBGeneratorDao;
}
public static boolean isMongo() {
return mongo;
}
}