莺时

东边日出西边雨,道是无晴却有晴

Open Source, Open Mind,
Open Sight, Open Future!
  menu
18 文章
3692 浏览
1 当前访客
ღゝ◡╹)ノ❤️

Java接口继承使用(什么?接口还能继承接口,好吧第一次见)

Java接口继承使用(多数据库源类似查询的封装)

场景描述

我是因为一个中间件的项目(由用户维护多个数据库链接信息,系统从多数据源中读取库中的全部表)发现的这个东西。为了让扩展数据库类型比较方便,所以这个地方需要抽象出一个数据库基类,每次新增数据库类型的时候,只是写新类继承基类就可以了,通过反射呀,或者简单的ifelse的方式调用就可以了。我就简单写一下实现需要哪几部分。

实现

Holder类

我比较懒,一个参数从controller传递到最内层是真的烦人呢,使用ThreadLocal就比较方便了,但是也别乱用呀。这个地方就是保存了数据库类型。ThreadLocal是每个线程独享的,所以不会出现多线程互相影响的问题。

 1import org.springframework.core.NamedThreadLocal;
 2
 3/**
 4 * 描述:
 5 * 数据库类型holder
 6 *
 7 * @author ludengke
 8 * @create 2020-07-21 16:18
 9 */
10public class DatabaseTypeHolder {
11    private static final ThreadLocal<String> DATABASE_TYPE_HOLDER = new NamedThreadLocal<>("DATABASE_TYPE");
12
13    public static String getDatabaseType() {
14        return DATABASE_TYPE_HOLDER.get();
15    }
16
17    public static void setDatabaseType(String databaseType) {
18        DATABASE_TYPE_HOLDER.set(databaseType);
19    }
20
21    public static void clearUserInfo() {
22        DATABASE_TYPE_HOLDER.remove();
23    }
24}

mapper层

mapper层分为mapper类和mapper xml

mapper类

 1/**
 2 * 描述:
 3 *	数据库操作基类,不加Mapper注解,不加Mapper注解
 4 * @author ludengke
 5 * @create 2020-07-21 16:22
 6 */
 7public interface DatabaseOptMapper {
 8
 9    /**
10     * 查询数据库表信息
11     * @return 返回表信息
12     */
13    List<TableInfo> queryTableInfo();
14}
 1/**
 2 * 描述:
 3 *	mysql操作类,加Mapper注解
 4
 5 * @author ludengke
 6 * @create 2020-07-21 16:22
 7 */
 8@Mapper
 9public interface MysqlOptMapper extends DatabaseOptMapper{
10}
1/**
2 * 描述:
3 *	PGSQL操作类
4 * @author ludengke
5 * @create 2020-07-21 16:22
6 */
7@Mapper
8public interface PgsqlOptMapper extends DatabaseOptMapper{
9}

mysql操作类的mapper.xml用于查询,当前连接的所有表

 1<?xml version="1.0" encoding="UTF-8"?>
 2<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3<mapper namespace="com.MysqlOptMapper">
 4    <select id="queryTableInfo" resultType="com.TableInfo">
 5        SELECT
 6            `table_name`,
 7            table_comment
 8        FROM
 9            information_schema.`TABLES`
10        WHERE
11            table_schema = (SELECT DATABASE ())
12    </select>
13</mapper>

PGSQL操作类的mapper.xml用于查询,当前连接的所有表

 1<?xml version="1.0" encoding="UTF-8"?>
 2<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3<mapper namespace="com.PgsqlOptMapper">
 4    <select id="queryTableInfo" resultType="com.TableInfo">
 5        with tmp_tab as (
 6            select pc.oid as ooid,pn.nspname,pc.*
 7              from pg_class pc
 8                   left join pg_namespace pn on pc.relnamespace = pn.oid
 9              where pc.relkind in ('r')
10               and pc.relnamespace in (select pn.oid from pg_namespace pn where pn.nspname in (select CURRENT_SCHEMA))
11               and pc.oid not in (select inhrelid from pg_inherits )
12            order by pc.relname
13        ),tmp_desc as (
14           select pd.*
15             from pg_description pd
16            where pd.objsubid = 0
17        )
18        select tab.relname as table_name, de.description as table_commit
19            from tmp_tab tab
20                     left join tmp_desc de on tab.ooid = de.objoid
21    </select>
22</mapper>

service层

服务方:负责处理不同数据库操作

 1package com.wangdian.bigdata.biserver.dataset.service.imlp;
 2
 3import com.TableInfo;
 4import com.DatabaseTypeHolder;
 5import com.DatabaseOptMapper;
 6import com.MysqlOptMapper;
 7import com.PgsqlOptMapper;
 8import com.IDatabaseOptService;
 9import org.springframework.stereotype.Service;
10
11import javax.annotation.Resource;
12import java.util.List;
13
14/**
15 * 描述:
16 * 不同数据源操作调用
17 *
18 * @author ludengke
19 * @create 2020-07-21 16:14
20 */
21@Service
22public class DatabaseOptServiceImpl implements IDatabaseOptService {
23
24    @Resource
25    private MysqlOptMapper mysqlOptMapper;
26
27    @Resource
28    private PgsqlOptMapper pgsqlOptMapper;
29
30    @Override
31    public List<TableInfo> queryTableInfoFromOutSideLink(){
32        return this.getDatabaseOptMapper().queryTableInfo();
33    }
34
35    private DatabaseOptMapper getDatabaseOptMapper() {
36        DatabaseOptMapper result = null;
37        switch (DatabaseTypeHolder.getDatabaseType()){
38            case "mysql":
39                result = mysqlOptMapper;break;
40            case "pgsql":
41                result = pgsqlOptMapper;break;
42            default:
43                result = mysqlOptMapper;break;
44        }
45        return result;
46    }
47}
 1package com.service;
 2
 3import com.TableInfo;
 4
 5import java.util.List;
 6
 7/**
 8 * 描述:
 9 *
10 * @author ludengke
11 * @create 2020-07-21 16:36
12 */
13public interface IDatabaseOptService {
14
15    /**
16     * 查询目标库的表的绑定情况
17     * @return
18     */
19    List<TableInfo> queryTableInfoFromOutSideLink();
20}

设计

这样的设计方便以后的扩展,扩展新的数据库类型的时候步骤比较清晰了。

  1. 增加DatabaseOptMapper的实现类,
  2. 增加实现类的mapper xml。
  3. 在DatabaseOptServiceImpl中增加switch的内容。
  4. 如果想做更多的数据库操作,在DatabaseOptMapper增加方法即可,xml记得实现哟。

标题:Java接口继承使用(什么?接口还能继承接口,好吧第一次见)
作者:ludengke95
地址:http://xvhi.ludengke95.xyz/articles/2020/07/21/1595328860306.html