当前位置: 首页 > news >正文

获取 Connection 对象的几种方式详解

获取 Connection 对象的几种方式详解

1. JDBC 原生方式

1.1 使用 DriverManager(最基础方式)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;public class DriverManagerExample {public static Connection getConnectionBasic() throws SQLException {// 1. 注册驱动(JDBC 4.0+ 可以省略,但显式注册更安全)try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {throw new SQLException("数据库驱动未找到", e);}// 2. 获取连接String url = "jdbc:mysql://localhost:3306/mydatabase";String username = "root";String password = "password";return DriverManager.getConnection(url, username, password);}public static Connection getConnectionWithParams() throws SQLException {String url = "jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8";String username = "root";String password = "password";// 可以添加连接属性java.util.Properties props = new java.util.Properties();props.setProperty("user", username);props.setProperty("password", password);props.setProperty("useUnicode", "true");props.setProperty("characterEncoding", "UTF-8");return DriverManager.getConnection(url, props);}
}

1.2 使用示例

public class JdbcExample {public void basicUsage() {Connection conn = null;try {// 获取连接conn = DriverManagerExample.getConnectionBasic();// 执行数据库操作Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT * FROM users");while (rs.next()) {System.out.println(rs.getString("username"));}} catch (SQLException e) {e.printStackTrace();} finally {// 关闭连接if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}// 使用 try-with-resources(推荐)public void modernUsage() {try (Connection conn = DriverManagerExample.getConnectionBasic();Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {while (rs.next()) {System.out.println(rs.getString("username"));}} catch (SQLException e) {e.printStackTrace();}// 自动关闭资源}
}

2. 连接池方式

2.1 HikariCP(性能最优)

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;public class HikariCPExample {private static HikariDataSource dataSource;static {// 配置 HikariCPHikariConfig config = new HikariConfig();config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");config.setUsername("root");config.setPassword("password");config.setDriverClassName("com.mysql.cj.jdbc.Driver");// 连接池配置config.setMaximumPoolSize(20);config.setMinimumIdle(5);config.setConnectionTimeout(30000); // 30秒config.setIdleTimeout(600000);      // 10分钟config.setMaxLifetime(1800000);     // 30分钟config.setAutoCommit(true);// 可选优化配置config.addDataSourceProperty("cachePrepStmts", "true");config.addDataSourceProperty("prepStmtCacheSize", "250");config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");dataSource = new HikariDataSource(config);}public static Connection getConnection() throws SQLException {return dataSource.getConnection();}public static DataSource getDataSource() {return dataSource;}public static void closeDataSource() {if (dataSource != null && !dataSource.isClosed()) {dataSource.close();}}
}

2.2 Apache DBCP2

import org.apache.commons.dbcp2.BasicDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;public class DBCP2Example {private static BasicDataSource dataSource;static {dataSource = new BasicDataSource();dataSource.setUrl("jdbc:mysql://localhost:3306/mydatabase");dataSource.setUsername("root");dataSource.setPassword("password");dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");// 连接池配置dataSource.setInitialSize(5);           // 初始连接数dataSource.setMaxTotal(20);             // 最大连接数dataSource.setMaxIdle(10);              // 最大空闲连接dataSource.setMinIdle(5);               // 最小空闲连接dataSource.setMaxWaitMillis(30000);     // 获取连接超时时间// 连接验证配置dataSource.setValidationQuery("SELECT 1");dataSource.setTestOnBorrow(true);dataSource.setTestWhileIdle(true);dataSource.setTimeBetweenEvictionRunsMillis(60000); // 60秒检测一次}public static Connection getConnection() throws SQLException {return dataSource.getConnection();}
}// 使用配置文件的版本
public class DBCP2WithProperties {public static DataSource createDataSourceFromProperties() {Properties props = new Properties();try (InputStream input = DBCP2WithProperties.class.getClassLoader().getResourceAsStream("dbcp.properties")) {props.load(input);} catch (IOException e) {throw new RuntimeException("无法加载数据库配置", e);}BasicDataSource dataSource = new BasicDataSource();dataSource.setDriverClassName(props.getProperty("driverClassName"));dataSource.setUrl(props.getProperty("url"));dataSource.setUsername(props.getProperty("username"));dataSource.setPassword(props.getProperty("password"));// 其他配置...return dataSource;}
}

2.3 C3P0

import com.mchange.v2.c3p0.ComboPooledDataSource;import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;public class C3P0Example {private static ComboPooledDataSource dataSource;static {try {dataSource = new ComboPooledDataSource();dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");dataSource.setUser("root");dataSource.setPassword("password");// 连接池配置dataSource.setInitialPoolSize(5);dataSource.setMinPoolSize(5);dataSource.setMaxPoolSize(20);dataSource.setAcquireIncrement(5);dataSource.setMaxIdleTime(1800); // 30分钟// 连接测试dataSource.setTestConnectionOnCheckin(true);dataSource.setTestConnectionOnCheckout(false);dataSource.setPreferredTestQuery("SELECT 1");} catch (PropertyVetoException e) {throw new RuntimeException("C3P0配置失败", e);}}public static Connection getConnection() throws SQLException {return dataSource.getConnection();}
}

3. MyBatis 集成方式

3.1 MyBatis 内置连接池

<!-- mybatis-config.xml -->
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mydatabase"/><property name="username" value="root"/><property name="password" value="password"/><!-- MyBatis 内置连接池配置 --><property name="poolMaximumActiveConnections" value="20"/><property name="poolMaximumIdleConnections" value="10"/><property name="poolMaximumCheckoutTime" value="20000"/><property name="poolTimeToWait" value="20000"/><property name="poolPingEnabled" value="true"/><property name="poolPingQuery" value="SELECT 1"/><property name="poolPingConnectionsNotUsedFor" value="3600000"/></dataSource></environment></environments>
</configuration>
// 通过 MyBatis 获取 Connection
public class MyBatisConnectionExample {public static Connection getConnectionFromMyBatis() throws SQLException {// 1. 创建 SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 2. 获取 SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 3. 从 SqlSession 获取 Connectionreturn sqlSession.getConnection();}// 推荐方式:让 MyBatis 管理连接public void letMyBatisManageConnection() {SqlSession sqlSession = null;try {SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();sqlSession = sqlSessionFactory.openSession();// 获取 Mapper 执行操作,MyBatis 自动管理连接UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.selectById(1L);sqlSession.commit(); // 提交事务} catch (Exception e) {if (sqlSession != null) {sqlSession.rollback();}throw e;} finally {if (sqlSession != null) {sqlSession.close(); // 自动关闭连接}}}
}

3.2 MyBatis 集成第三方连接池

<!-- 使用 HikariCP 作为 MyBatis 数据源 -->
<configuration><properties resource="db.properties"/><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="com.example.MyBatisHikariDataSourceFactory"><!-- HikariCP 配置 --><property name="jdbcUrl" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><property name="driverClassName" value="${jdbc.driver}"/><property name="maximumPoolSize" value="20"/><property name="minimumIdle" value="5"/></dataSource></environment></environments>
</configuration>
// 自定义 DataSourceFactory 集成 HikariCP
public class MyBatisHikariDataSourceFactory implements DataSourceFactory {private HikariDataSource dataSource;@Overridepublic void setProperties(Properties properties) {HikariConfig config = new HikariConfig(properties);dataSource = new HikariDataSource(config);}@Overridepublic DataSource getDataSource() {return dataSource;}
}

4. Spring 框架方式

4.1 Spring JDBC Template

@Configuration
@PropertySource("classpath:db.properties")
public class SpringJdbcConfig {@Value("${jdbc.driver}")private String driverClassName;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;@Beanpublic DataSource dataSource() {HikariDataSource dataSource = new HikariDataSource();dataSource.setDriverClassName(driverClassName);dataSource.setJdbcUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);dataSource.setMaximumPoolSize(20);return dataSource;}@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource) {return new JdbcTemplate(dataSource);}@Beanpublic TransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}// 使用方式
@Service
public class UserService {@Autowiredprivate JdbcTemplate jdbcTemplate;@Autowiredprivate DataSource dataSource;// 方式1:使用 JdbcTemplate(推荐)public List<User> getUsers() {return jdbcTemplate.query("SELECT * FROM users", (rs, rowNum) -> {User user = new User();user.setId(rs.getLong("id"));user.setUsername(rs.getString("username"));return user;});}// 方式2:直接从 DataSource 获取 Connectionpublic void useDirectConnection() {try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users");ResultSet rs = pstmt.executeQuery()) {while (rs.next()) {// 处理结果}} catch (SQLException e) {throw new RuntimeException("数据库操作失败", e);}}
}

4.2 Spring Boot 自动配置

# application.yml
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mydatabaseusername: rootpassword: passwordtype: com.zaxxer.hikari.HikariDataSourcehikari:maximum-pool-size: 20minimum-idle: 5connection-timeout: 30000idle-timeout: 600000max-lifetime: 1800000
// Spring Boot 中使用
@Service
@Transactional
public class UserService {@Autowiredprivate DataSource dataSource; // Spring Boot 自动配置的 DataSource@Autowiredprivate JdbcTemplate jdbcTemplate; // Spring Boot 自动配置的 JdbcTemplatepublic void businessMethod() {// 使用 JdbcTemplatejdbcTemplate.update("UPDATE users SET email = ? WHERE id = ?", "new@example.com", 1L);// 或者直接获取 Connection(不推荐,让 Spring 管理事务)try (Connection conn = DataSourceUtils.getConnection(dataSource)) {// 使用连接,Spring 会管理事务// ...} catch (SQLException e) {throw new RuntimeException("数据库操作失败", e);}}
}

5. JNDI 方式(Java EE 环境)

5.1 配置 JNDI 数据源

<!-- Tomcat context.xml -->
<Context><Resource name="jdbc/MyDB"auth="Container"type="javax.sql.DataSource"driverClassName="com.mysql.cj.jdbc.Driver"url="jdbc:mysql://localhost:3306/mydatabase"username="root"password="password"maxTotal="20"maxIdle="10"maxWaitMillis="10000"/>
</Context><!-- 或者在 web.xml 中配置 -->
<resource-ref><description>MySQL Datasource</description><res-ref-name>jdbc/MyDB</res-ref-name><res-type>javax.sql.DataSource</res-type><res-auth>Container</res-auth>
</resource-ref>

5.2 从 JNDI 获取连接

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;public class JNDIExample {public static Connection getJNDIConnection() throws SQLException, NamingException {Context initContext = new InitialContext();Context envContext = (Context) initContext.lookup("java:comp/env");DataSource dataSource = (DataSource) envContext.lookup("jdbc/MyDB");return dataSource.getConnection();}// 简化版本(在某些容器中)public static Connection getJNDIConnectionSimple() throws SQLException, NamingException {Context context = new InitialContext();DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/MyDB");return dataSource.getConnection();}
}

6. 工具类封装

6.1 通用数据库工具类

public class DBUtil {private static DataSource dataSource;private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();static {initDataSource();}private static void initDataSource() {// 根据环境选择数据源配置if (isProduction()) {dataSource = createHikariDataSource();} else {dataSource = createDevDataSource();}}private static HikariDataSource createHikariDataSource() {HikariConfig config = new HikariConfig();config.setJdbcUrl(getProperty("jdbc.url"));config.setUsername(getProperty("jdbc.username"));config.setPassword(getProperty("jdbc.password"));config.setMaximumPoolSize(20);return new HikariDataSource(config);}private static BasicDataSource createDevDataSource() {BasicDataSource ds = new BasicDataSource();ds.setUrl(getProperty("jdbc.url"));ds.setUsername(getProperty("jdbc.username"));ds.setPassword(getProperty("jdbc.password"));ds.setInitialSize(5);ds.setMaxTotal(10);return ds;}/*** 获取数据库连接*/public static Connection getConnection() throws SQLException {// 检查当前线程是否已有连接(用于事务)Connection conn = threadLocal.get();if (conn != null && !conn.isClosed()) {return conn;}// 从数据源获取新连接conn = dataSource.getConnection();return conn;}/*** 开启事务(绑定连接到当前线程)*/public static void beginTransaction() throws SQLException {Connection conn = threadLocal.get();if (conn != null) {throw new SQLException("事务已开启");}conn = getConnection();conn.setAutoCommit(false);threadLocal.set(conn);}/*** 提交事务*/public static void commitTransaction() throws SQLException {Connection conn = threadLocal.get();if (conn == null) {throw new SQLException("没有开启的事务");}conn.commit();conn.close();threadLocal.remove();}/*** 回滚事务*/public static void rollbackTransaction() throws SQLException {Connection conn = threadLocal.get();if (conn == null) {throw new SQLException("没有开启的事务");}conn.rollback();conn.close();threadLocal.remove();}/*** 释放连接(非事务情况下使用)*/public static void releaseConnection(Connection conn) throws SQLException {Connection threadConn = threadLocal.get();// 如果不是事务连接,可以关闭if (threadConn == null || threadConn != conn) {if (conn != null && !conn.isClosed()) {conn.close();}}}private static String getProperty(String key) {// 从配置文件读取属性return System.getProperty(key);}private static boolean isProduction() {return "prod".equals(System.getProperty("app.env"));}
}

7. 性能对比与选择建议

7.1 各种方式对比

方式性能易用性功能完整性适用场景
DriverManager简单基础测试、简单应用
HikariCP非常高中等完整生产环境首选
DBCP2中等完整传统项目
C3P0中等复杂完整老项目维护
MyBatis 内置中等简单基础小型项目
Spring 管理简单完整Spring 项目
JNDI复杂完整Java EE 环境

7.2 选择建议

  1. 新项目:Spring Boot + HikariCP
  2. 传统 Spring 项目:Spring + HikariCP/DBCP2
  3. Java EE 项目:JNDI 数据源
  4. 简单测试:DriverManager
  5. MyBatis 项目:MyBatis + HikariCP

7.3 最佳实践

// 生产环境推荐配置
public class ProductionDataSourceConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.hikari")public DataSource dataSource() {return DataSourceBuilder.create().type(HikariDataSource.class).build();}// 使用连接时的最佳实践@Service@Transactional // 让Spring管理事务public class BusinessService {@Autowiredprivate JdbcTemplate jdbcTemplate; // 推荐使用@Autowiredprivate DataSource dataSource;public void businessMethod() {// 方式1:使用JdbcTemplate(首选)jdbcTemplate.update("SQL语句", params);// 方式2:需要复杂操作时获取连接jdbcTemplate.execute((ConnectionCallback<Void>) conn -> {// 使用连接执行复杂操作// Spring会自动管理事务return null;});}}
}

通过理解这些获取 Connection 对象的方式,你可以根据项目需求选择最合适的方案。在生产环境中,推荐使用连接池(特别是 HikariCP)结合框架的事务管理,以获得最佳性能和可靠性。

http://www.dtcms.com/a/532897.html

相关文章:

  • 网站建设中 显示 虚拟机百合seo培训
  • 网上做任务的网站后端低代码平台
  • 【Linux指令3】
  • [sam2图像分割] MemoryEncoder.forward | MaskDownSampler | Fuser
  • Fluent Emoji Gallery,一款微软表情图库
  • 思源实时免费同步,插件推荐
  • 安庆市大观区城乡建设局网站猪八戒上面还是淘宝上做网站技术好
  • Objective-C 初阶 —— __bridge __bridge_retained __bridge_transfer
  • wordpress主题6企业优化网站
  • 最细Maven教程以及Maven私服搭建
  • wordpress网站打开速度学设计网站
  • UVa 1298 Triathlon
  • cuda编程笔记(33)--Thrust库的使用
  • Gorm(十一)事务
  • Ubuntu24.04安装好Mysql8后,检查mysql占用的内存和磁盘
  • 阿里云申请域名后网站海外网络加速器
  • Orleans ILifecycleParticipant 生命周期管理详细分析
  • 企业门户网站建设方案后台管理wordpress多级tree分类目录
  • Spring XML AOP配置实战指南
  • 什么人需要网站建设柳州网站开发公司
  • 做纯净系统的网站产品做国外网站有哪些
  • 商贸公司网站建设兴城泳装电子商务网站建设
  • 张祥前统一场论中的洛伦兹变换:多层次的应用与全新内涵
  • 网安面试题收集(4)
  • 高端上海网站设计公司价格wordpress 打赏
  • Yolo_lableimg_env
  • 【09】C语言中的格式输入函数scanf()详解
  • 鼠键共享工具
  • 个人网站备案 拍照装修网店
  • 投资,如何获得估值回归的收益?