成都网站建设设计

将想法与焦点和您一起共享

Java数据库常用操作-创新互联

一、JDBC驱动

创新互联公司主要从事成都网站设计、做网站、网页设计、企业做网站、公司建网站等业务。立足成都服务宽城,十年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:028-86922220

JDBC驱动的加载:

1、通过容器加载:

对于有容器的Java应用,可以直接将相应的驱动jar包放在容器的lib目录下,例如在Tomcat做容器的web应用,将驱动复制到tomcat的lib子目录下;

2、应用运行时加载:

如果希望应用自行加载相应的驱动,需要maven为应用打jar/war包时指定好搜寻驱动jar时的classpath,请参考:

https://maven.apache.org/shared/maven-archiver/examples/classpath.html

https://www.cnblogs.com/snaildev/p/8341610.html

示例一(可执行jar包下有lib目录存放依赖jar包):

        image                                       org.apache.maven.plugins                 maven-jar-plugin                 2.4                                                                                            true                             lib/                             some.package.MainClass                                                                                          

业务自行加载JDBC驱动时,需要在应用用JDBC之前执行如下操作加载驱动:

Class.forName("com.mysql.jdbc.Driver"); // Then the following begin to use jdbc

二、通过连接池(DataSource的一种)管理与数据库的连接

目前常用的连接池为Druid或Hikari,分别说明如下:

1、Druid连接池:

maven依赖:


    com.alibaba
    druid
    1.1.11

示例代码:

DruidDataSource createSource(String name, String jdbcUrl, String userName, String password,
        maxActive, minIdle, maxWait, scanInterval, minActiveTime) {
    DruidDataSource src = DruidDataSource();
    src.setName(name);
    src.setUrl(jdbcUrl);
    src.setUsername(userName);
    src.setPassword(password);
    src.setDriverClassName(); 
    src.setInitialSize(minIdle);
    src.setMaxActive(maxActive);
    src.setMinIdle(minIdle);
    src.setMaxWait(maxWait); 
    src.setTimeBetweenEvictionRunsMillis(scanInterval); 
    src.setMinEvictableIdleTimeMillis(minActiveTime);   
    src.setTestWhileIdle(); 
    src.setTestOnBorrow();  
    src.setTestOnReturn();
    src.setPoolPreparedStatements(); 
    src.setMaxPoolPreparedStatementPerConnectionSize(); 
    src.setValidationQuery(); 
    src.setRemoveAbandoned(); 
    src.setRemoveAbandonedTimeout(); 
    src.setKeepAlive(); 
    if(!isDataSourceOk(src)){
        LOGGER.error("Data source "+ name + "test failed");
    }
    return src;
}
private static boolean isDataSourceOk(DataSource source){
    try (Connection connection = source.getConnection();
         PreparedStatement stmt = connection.prepareStatement("select 1");
         ResultSet resultSet = stmt.executeQuery()){
        resultSet.next();
        return true;
    }catch (Throwable e){
        return false;
    }
}

2、Hikari连接池

maven依赖:


    com.zaxxer
    HikariCP
    3.2.0

示例代码:

HikariDataSource createSource(String name, String jdbcUrl, String userName, String password,
        connectionTimeout, idleTimeout, maxLifeTime, poolSize) {
    HikariDataSource src = HikariDataSource();
    src.setPoolName(name);
    src.setJdbcUrl(jdbcUrl);
    src.setUsername(userName);
    src.setPassword(password);
    src.setDriverClassName(); 
    src.setConnectionTimeout(connectionTimeout);
    src.setIdleTimeout(idleTimeout); 
    src.setMaxLifetime(maxLifeTime); 
    src.setMaximumPoolSize(poolSize);
    if(!isDataSourceOk(src)){
        LOGGER.error("Data source "+ name + "test failed");
    }
    return src;
}

三、处理连接

1、首先通过连接池获取连接,例如:

try(Connection getConnection() SQLException {
    assert DataSourceManager.getDataSource() != null;
    return DataSourceManager.getDataSource().getConnection();
}

2、连接的SQL请求提交方式

从连接池(无轮DruidDataSource还是HirakiDataSource)申请到Connection对象拿到后,默认的提交方式为自动提交,即此时调用connection.getAutoCommit()返回的一定是true;

Connection对象归还连接池后,下次再从连接池申请一个Connection,默认的提交方式还是自动提交。需要清楚什时候用自动提交、什么时候适合手工提交。

概况起来就是,看申请到Connection对象到归还Connection对象这期间使用同一个Connection对象做了什么操作:

(1)只有读操作,没有任何写操作:用自动提交;

(2)只有一次对单个表的单条记录有进行写操作:用自动提交;

自动提交的代码示例如下

try(Connection connection = ()) {
    block.apply(connection); // Do all query or only one update for only one record
}

(3)对同一张表的多条记录进行了写操作,或者对不同表的记录分别进行了写操作:根据是否需要回滚、性能要求,确定是否需要支持事务性;如果要支持事物性,必须采用手动提交;

手动提交的操作示例:

try(Connection connection = ()) {
    boolean success = false;
    try{
        T t = block.apply(connection); // Use this connection process one transaction
        doCommit(connection);
        success = true;
        return t;
    }finally{
        if(!success) {
            doRollback(connection); // If possible, support rollback when failed
        }
    }
}

上述复杂过程的block中可能对connection的提交模式进行了修改,为了保持代码的兼容性,上述doCommit()及doRollback()的设计如下:

public static void doCommit(Connection connection) throws SQLException {
    if (!connection.getAutoCommit()) {
        connection.commit();
    }
}
private static void doRollback(Connection connection) throws SQLException {
    if (SUPPORT_ROLLBACK && !connection.getAutoCommit()) {
        connection.rollback();
    }
}

(4)耗时的操作,数据量比较大,这时依赖数据库的事物性及回滚已经没法达到;这种情况下应该分多次提交,并有应用层提供回滚;

示例如下:

try(Connection connection = ()) {
    boolean success = false;
    try{
        block1.accept(connection);
        doCommit(connection);
        block2.accept(connection);
        doCommit(connection);
        success = true;
    }finally{
        if(!success) {
            block2.clear(connection);
            block1.clear(connection);
        }
    }
}

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


名称栏目:Java数据库常用操作-创新互联
当前链接:http://chengdu.cdxwcx.cn/article/pdjoi.html