mybatis-plus3.5.3.1 支持不同数据源sql适配

mybatis-plus3.5.3.1 支持不同数据源sql适配

背景

最近公司要求支持国产数据库达梦,人大金仓,高斯等数据库,这些数据库与mysql的语法有一些差异,需要做一些兼容操作。

解决问题

1.不同数据库分页不同

2.支持通过参数控制执行不同的sql

3.没有特殊sql执行默认sql

实现流程

1.代码结构

mybatis-plus3.5.3.1 支持不同数据源sql适配_第1张图片

2.引入依赖

 
        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.5.3.1
        
        
        
            mysql
            mysql-connector-java
            5.1.47
        
        
            org.projectlombok
            lombok
            1.18.28
        



        
        
            org.opengauss
            opengauss-jdbc
            3.0.0
        
        
        
            cn.com.kingbase
            kingbase8
            8.6.0
        
        
        
            com.dameng
            DmJdbcDriver18
            8.1.1.193
        
        
            com.oracle.database.jdbc
            ojdbc8-production
            19.7.0.0
        

3.代码

MybatisAutoConfiguration
@Configuration
@MapperScan("com.liuhm.dao.mapper*")
public class MybatisAutoConfiguration {
	@Autowired
	private DataSource dataSource;
	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
		String driverClassName = ((HikariDataSource) dataSource).getDriverClassName();
		// 分页插件
		mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DatabaseIdEnums.getDbTypeByDriver(driverClassName)));

		return mybatisPlusInterceptor;
	}
	@Bean
	public DatabaseIdProvider databaseIdProvider() {
		VendorDatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
		Properties properties = new Properties();
		// 设置数据库厂商和databaseid别名
		for (DatabaseIdEnums databaseIdEnum : DatabaseIdEnums.values()) {
			// key=value
			// key     数据库厂商的databaseid
			// value   别名,和xml里面对应
			properties.put(databaseIdEnum.getName(),databaseIdEnum.getName());
		}
		databaseIdProvider.setProperties(properties);
		return databaseIdProvider;
	}
}


TestMapper
@Repository
@CacheNamespace
public interface TestMapper {
     /**
     * 需要兼容
     * @return
     */
    public List select();

    /**
     * 公共的方法 不兼容
     * @return
     */
    public List selectCommon();

    /**
     * 测试分页
     * @param page
     * @return
     */
    IPage selectPage(Page page);
}

DatabaseIdEnums
@AllArgsConstructor
@Getter
public enum DatabaseIdEnums {
    MYSQL("MySQL", "mysql", "com.mysql.jdbc.Driver",DbType.MYSQL),
    KINGBASEESV8("KingbaseES","kingbaseesv8","com.kingbase8.Driver", com.baomidou.mybatisplus.annotation.DbType.KINGBASE_ES),
    OPENGAUSS3("PostgreSQL", "opengauss3"," org.opengauss.Driver",DbType.OPENGAUSS),
    ORACLE("Oracle", "oracle","oracle.jdbc.driver.OracleDriver",DbType.ORACLE),
    DM("DM DBMS", "dm","dm.jdbc.driver.DmDriver",DbType.DM)
    ;

    /**
     * 数据库名
     */
    private String name;
    /**
     * 数据库名 别名
     */
    private String nameAlias;
    /**
     * 数据库名 别名
     */
    private String driver;
    /**
     * 分页插件名
     */
    private DbType dbType;

    /**
     * 通过数据名获取对应的分页插件
     * @param driver
     * @return
     */
    public static DbType getDbTypeByDriver(String driver) {
        for (DatabaseIdEnums databaseIdEnum : DatabaseIdEnums.values()) {
            if(Objects.equals(databaseIdEnum.getDriver(),driver)){
                return databaseIdEnum.dbType;
            }
        }
        return null;
    }
}
TestMapper.xml



    
    

    

    
    
    
    
    


4.测试

测试要求

  • 对应数据库导入测试sql

  • 测试公共的方法是否正确

  • 分页测试是否正确

  • 特殊兼容sql测试是否正确

测试代码:

    @Test
	public void Test(){
		testMapper.selectCommon();
		System.out.println("------------------------------");
		testMapper.selectPage(new Page<>(1,5));
		System.out.println("------------------------------");
		testMapper.selectPage(new Page<>(2,5));
		System.out.println("------------------------------");
		testMapper.select();
	}
4.1.mysql测试

使用yml配置

    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: Cobbler1234!
    url: jdbc:mysql://192.168.0.229:43306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false

运行结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5a05dd30] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1590202270 wrapping com.mysql.jdbc.JDBC4Connection@7a04f730] will not be managed by Spring
==>  Preparing: SELECT * FROM test;
==> Parameters: 
<==    Columns: name
<==        Row: 测试数据mysql 1
<==        Row: 测试数据mysql 2
<==        Row: 测试数据mysql 3
<==        Row: 测试数据mysql 4
<==        Row: 测试数据mysql 5
<==        Row: 测试数据mysql 6
<==        Row: 测试数据mysql 7
<==      Total: 7
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5a05dd30]
------------------------------
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@353e6389] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@11646065 wrapping com.mysql.jdbc.JDBC4Connection@7a04f730] will not be managed by Spring
==>  Preparing: SELECT COUNT(*) AS total FROM test
==> Parameters: 
<==    Columns: total
<==        Row: 7
<==      Total: 1
==>  Preparing: select * from test LIMIT ?
==> Parameters: 5(Long)
<==    Columns: name
<==        Row: 测试数据mysql 1
<==        Row: 测试数据mysql 2
<==        Row: 测试数据mysql 3
<==        Row: 测试数据mysql 4
<==        Row: 测试数据mysql 5
<==      Total: 5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@353e6389]
------------------------------
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@62cbc478] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1413020227 wrapping com.mysql.jdbc.JDBC4Connection@7a04f730] will not be managed by Spring
==>  Preparing: SELECT COUNT(*) AS total FROM test
==> Parameters: 
<==    Columns: total
<==        Row: 7
<==      Total: 1
==>  Preparing: select * from test LIMIT ?,?
==> Parameters: 5(Long), 5(Long)
<==    Columns: name
<==        Row: 测试数据mysql 6
<==        Row: 测试数据mysql 7
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@62cbc478]
------------------------------
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@615db358] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@627815870 wrapping com.mysql.jdbc.JDBC4Connection@7a04f730] will not be managed by Spring
==>  Preparing: select * from test where 'mysql' = 'mysql'
==> Parameters: 
<==    Columns: name
<==        Row: 测试数据mysql 1
<==        Row: 测试数据mysql 2
<==        Row: 测试数据mysql 3
<==        Row: 测试数据mysql 4
<==        Row: 测试数据mysql 5
<==        Row: 测试数据mysql 6
<==        Row: 测试数据mysql 7
<==      Total: 7
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@615db358]

4.2.kingbaseesv8测试

使用yml配置

    driver-class-name: com.kingbase8.Driver
    username: system
    password: hcloud1234
    url: jdbc:kingbase8://192.168.0.248:54321/kingbase?currentSchema=mcp_manager

运行结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1a2ac487] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@629092599 wrapping com.kingbase8.jdbc.KbConnection@3fde2209] will not be managed by Spring
==>  Preparing: SELECT * FROM test;
==> Parameters: 
<==    Columns: name
<==        Row: 测试数据kingbaseesv8 1
<==        Row: 测试数据kingbaseesv8 2
<==        Row: 测试数据kingbaseesv8 3
<==        Row: 测试数据kingbaseesv8 4
<==        Row: 测试数据kingbaseesv8 5
<==        Row: 测试数据kingbaseesv8 6
<==        Row: 测试数据kingbaseesv8 7
<==      Total: 7
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1a2ac487]
------------------------------
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@496cc217] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@936544568 wrapping com.kingbase8.jdbc.KbConnection@3fde2209] will not be managed by Spring
==>  Preparing: SELECT COUNT(*) AS total FROM test
==> Parameters: 
<==    Columns: total
<==        Row: 7
<==      Total: 1
==>  Preparing: select * from test LIMIT ?
==> Parameters: 5(Long)
<==    Columns: name
<==        Row: 测试数据kingbaseesv8 1
<==        Row: 测试数据kingbaseesv8 2
<==        Row: 测试数据kingbaseesv8 3
<==        Row: 测试数据kingbaseesv8 4
<==        Row: 测试数据kingbaseesv8 5
<==      Total: 5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@496cc217]
------------------------------
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@723e2d08] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@7162498 wrapping com.kingbase8.jdbc.KbConnection@3fde2209] will not be managed by Spring
==>  Preparing: SELECT COUNT(*) AS total FROM test
==> Parameters: 
<==    Columns: total
<==        Row: 7
<==      Total: 1
==>  Preparing: select * from test LIMIT ? OFFSET ?
==> Parameters: 5(Long), 5(Long)
<==    Columns: name
<==        Row: 测试数据kingbaseesv8 6
<==        Row: 测试数据kingbaseesv8 7
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@723e2d08]
------------------------------
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@79df80a4] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@319618119 wrapping com.kingbase8.jdbc.KbConnection@3fde2209] will not be managed by Spring
==>  Preparing: select * from test where 'kingbaseesv8' = 'kingbaseesv8'
==> Parameters: 
<==    Columns: name
<==        Row: 测试数据kingbaseesv8 1
<==        Row: 测试数据kingbaseesv8 2
<==        Row: 测试数据kingbaseesv8 3
<==        Row: 测试数据kingbaseesv8 4
<==        Row: 测试数据kingbaseesv8 5
<==        Row: 测试数据kingbaseesv8 6
<==        Row: 测试数据kingbaseesv8 7
<==      Total: 7
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@79df80a4]

4.3.其余数据库自测

5.注意

5.1.查找对应的数据库名

通过查询 java.sql.DatabaseMetaData接口中getDatabaseProductName方法,找到对应是实现类

mybatis-plus3.5.3.1 支持不同数据源sql适配_第2张图片

mybatis-plus3.5.3.1 支持不同数据源sql适配_第3张图片

5.2.databaseId对应的是设置的别名
    @Bean
    public DatabaseIdProvider databaseIdProvider() {
        VendorDatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
        Properties properties = new Properties();
        properties.put("Oracle","oracle");
        properties.put("MySQL","mysql");
        databaseIdProvider.setProperties(properties);
        return databaseIdProvider;
    }

xml中

    <select id="select" resultType="java.lang.String" databaseId="mysql">
        select * from test where 'mysql' = 'mysql'
    select>
    <select id="select" resultType="java.lang.String" databaseId="oracle">
        select * from test where 'oracle' = 'oracle'
    select>
5.3.没有设置databaseId代表该xmlsql全部数据库都通用
5.4.分页插件设置

通过定义的驱动找到对应的DbType

	mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DatabaseIdEnums.getDbTypeByDriver(driverClassName)));

博客地址

代码下载

下面的mybatis-plus-demo3_5_3_1

你可能感兴趣的:(mysql,服务器,mybatis,sql,数据库)