利用mybatis动态连接mysql

前言

不知到大家在开发中有没有遇到过需要动态连接数据库的问题,比如填写个数据库的账号密码和连接地址测试是否可以连接通、动态配置数据库取表格数据等等;我最近就遇到了这样一个问题需要动态配置连接数据库,并且能够在连接数据库时可以动态查询不同表格的数据。面对这个问题一般解决方案可以是直接利用jdbc连接并测试,但是面对容器化,orm框架的不断涌现,这种原生方案无疑是重复性造轮子,并且还未必有现有的框架好用,所以本文将介绍利用spring boot + mybatis-plus解决该问题。

解决思路

利用mybatis中SqlSessionFactoryBuilder这个类的方法动态构建SqlSessionFactory构建后通过该类不断创建SqlSession来实现sql语句的动态查询功能,为方便使用本文同时还根据前沿中所遇到的问题构建了一个mapper类。

具体实现

mapper构建工具类MySQLConnectUtil

/**
 * 数据库动态连接工具类
 * @author wsy
 */
public class MySQLConnectUtil {
    private static ThreadLocal<MySQLSession> currentSqlSession;

    static {
        currentSqlSession = new ThreadLocal<>();
    }

    /**
     * 获取session
     *
     * @param password 密码
     * @param url      地址
     * @param username 用户名
     * @param port     端口
     * @return MySQLLog
     */
    public static MySQLLogMapper getSession(String url, String username, String password, String databaseName, int port) {
        try {
            Properties properties = new Properties();
            properties.setProperty("jdbc.driver", "com.mysql.cj.jdbc.Driver");
            properties.setProperty("jdbc.url", String.format("jdbc:mysql://%s:%s/%s?useSSL=false",
                    url, port, databaseName));
            properties.setProperty("jdbc.username", username);
            properties.setProperty("jdbc.password", password);
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, properties);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            MySQLLogMapper mySQLLogMapper = sqlSession.getMapper(MySQLLogMapper.class);
            currentSqlSession.set(MySQLSession.build()
                    .setSqlSession(sqlSession).setSqlSessionFactory(sqlSessionFactory));
            return mySQLLogMapper;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取session
     * @param mySQLSession 会话对象
     * @return MySQLLog
     */
    public static MySQLLogMapper getSession(MySQLSession mySQLSession) {
        SqlSession sqlSession = mySQLSession.getSqlSessionFactory().openSession();
        mySQLSession.setSqlSession(sqlSession);
        return sqlSession.getMapper(MySQLLogMapper.class);
    }

    public static MySQLSession getMySQLSession() {
        return currentSqlSession.get();
    }


    /**
     * 关闭数据库连接
     * */
    public static void closeSqlSession() {
        currentSqlSession.get().getSqlSession().close();
    }

    /**
     * 关闭数据库连接
     * @param mySQLSession 会话对象
     * */
    public static void closeSqlSession(MySQLSession mySQLSession) {
        mySQLSession.getSqlSession().close();
    }
}

注:这里使用mapper接口时要留意sqlSession的一级缓存,如果不想受一级缓存影响导致脏数据的话,可以每次使用完关掉创建mapper对象的sqlSession类

mapper类MySQLLogMapper

/**
 * 通用数据查询mapper
 * @author wsy
 */
public interface MySQLLogMapper {
    /**
     * 根据表名统计数据
     * @param tableName 表名
     * @return int
     * */
    int count(@Param("tableName") String tableName);

    /**
     * 查询数据,最大为10w条
     * @param tableName 表名
     * @param cloum 表字段(一般用于查询游标)
     * @param cur 当前游标值
     * @return Map
     * */
    List<Map<String, Object>> selectData(@Param("tableName") String tableName, @Param("cloum") String cloum, @Param("cur") Object cur);

    /**
     * 获取某个表的主键
     * @param tableName 表名
     * @return List>
     * */
    List<Map<String, Object>> selectPrimaryKey(@Param("tableName") String tableName);
}

mapper类关联的xml


DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.purplestorm.sendemail.mapper.MySQLLogMapper">


    <select id="count" resultType="java.lang.Integer">
        select count(*) from ${tableName} <where>
            <if test="cur != null and cloum != null">
                ${cloum} > #{cur}
            if>
        where>;
    select>

    <select id="selectData" resultType="java.util.LinkedHashMap">
        select * from ${tableName}
            <where>
              <if test="cur != null and cloum != null">
                 ${cloum} > #{cur}
              if>
            where>
            limit <if test="cur != null and cloum == null">
                 #{cur},
            if>10000;
    select>
    <select id="selectPrimaryKey" resultType="java.util.LinkedHashMap">
        SHOW INDEX FROM ${tableName} where Key_name = 'PRIMARY';
    select>
mapper>

会话连接类MySQLSession

/**
 * 连接会话类
 * @author wsy
 */
public class MySQLSession {

    public static MySQLSession build() {
        return new MySQLSession();
    }

    /**
     * 会话连接
     * */
    private SqlSession sqlSession;

    public SqlSession getSqlSession() {
        return sqlSession;
    }

    public MySQLSession setSqlSession(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
        return this;
    }

    public SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }

    public MySQLSession setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
        return this;
    }

    /**
     * 会话连接生产工厂
     * */
    private SqlSessionFactory sqlSessionFactory;

    public void closeSession() {
        this.sqlSession.close();
    }
}

mybatis-config.xml配置文件


DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        
        <setting name="cacheEnabled" value="false"/>
        
        <setting name="localCacheScope" value="STATEMENT"/>
    settings>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            dataSource>
        environment>
    environments>

    <mappers>
        <mapper resource="mapper/MySQLLogMapper.xml"/>
    mappers>

configuration>

xml文件放置位置

利用mybatis动态连接mysql_第1张图片
注:如果mapper.xml未生效可以尝试clean后再install后启动项目,如果还未生效请检查mybatis-plus.mapper-locations配置是否为classpath:/mapper/*Mapper.xml

结语

对于如上解决方案可能并非最优解,仅供大家参考学习,如有不妥之处或问题欢迎评论区留言或私信。

你可能感兴趣的:(框架,mybatis,mysql,java)