一、任务需求

        在java代码内和mapper.xml内获取当前数据库的连接类型,使得代码和sql语句可以同时兼容mysql和oracle数据库

二、实施

@Configuration
public class MyDatabaseIdProvider implements DatabaseIdProvider{
     /**
     * 参考mp的官方设置,sql的xml内使用_databaseId==oracle 来判断当前连接是什么类型的数据库
     * @param p
     */
    @Override
    public void setProperties(Properties p) {
        p.setProperty("Oracle", "oracle");
        p.setProperty("MySQL", "mysql");
    }

    /**
     * 根据mybatis最原始的配置方式,使用xml的那种,会有一个配置数据库圆的过程
     * 而所有的数据都在dataSource内,所以通过Connection获取getMetaData元数据库
     * 再获取name,也可以参照DatabaseIdProvider接口的默认实现方式
     * @param dataSource
     * @return
     * @throws SQLException
     */
    @Override
    public String getDatabaseId(DataSource dataSource) throws SQLException {
         Connection conn = null;
        String dbName = null;
        String dbAlias = "";
        try {
            conn = dataSource.getConnection();
            dbName = conn.getMetaData().getDatabaseProductName();
            switch (dbName) {
                case "MySQL":
                    dbAlias = "mysql";
                    break;
                case "Oracle":
                    dbAlias = "oracle";
                    break;
                default:
                    break;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
// 2024/5/17修改,线上发现占用数据库连接问题,
//导致其他sql在使用时造成数据库连接超时,这里需要释放Connection 连接
            if (conn != null) {
                conn.close();
            }
        }
        return dbAlias;
    }
     public String getDataBaseName(){
        DataSource dataSource = SpringUtil.getBean(DataSource.class);
        try {
            return this.getDatabaseId(dataSource);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return "";
    }
}

三、使用

  • 第一个重写的方法是用来判断当前数据库的类型,以便于在写SQL时,对于不同的数据库使用不同的语法。例如:
<select id="containsChild" resultType="com.xxx.entiry.user">
        <if test="_databaseId == 'oracle'">
            select *
            from A
            WHERE PERM_ID in
            (SELECT perm_id FROM A START
            WITH perm_id = #{permId}
            CONNECT BY perm_parent = PRIOR perm_id)
        </if>
        <if test="_databaseId == 'mysql'">
            WITH RECURSIVE Aa (
            SELECT * FROM
            A
            WHERE
            perm_id = #{permId}

            UNION ALL

            SELECT p.*
            FROM
            A p
            INNER JOIN
            Aa ON p.perm_parent = cte.perm_id
            )
            SELECT *
            FROM A;
        </if>

    </select>
  • 第二个方法是在代码层面判断当前连接的是什么数据库例如:
      
        String name =  myDatabaseIdProvider.getDataBaseName()
        System.out.println(name); //mysql或者oracle

Logo

一站式 AI 云服务平台

更多推荐