微服务数据库模块(第五期)

来自与之前的分布式项目,之前有
1.sprinboot单体项目升级成springcloud项目
2.分布式权限 shiro + jwt + redis
3.人人fast项目相关技术
4.给为服务添加运维模块 统一管理(第四期)

一、梳理功能和基本页面
微服务数据库模块(第五期)_第1张图片

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;
    }

}

你可能感兴趣的:(数据库,微服务,数据库,java)