数据库连接池 ( 一 ) JDBC 简述

1.JDBC

1.1.概念

JDBC(Java DataBase Connectivity)
它由用Java语言编写的类和接口组成,可以为多种关系数据库提供统一访问,是一种用于执行SQL语句的Java API 。
本质上 是将SQL语句传递到数据库,由数据库来执行返回结果

在这里插入图片描述

1.2.操作步骤

1.2.1.创建连接

需要 4 个参数 : 驱动类名, 连接url , 账号 , 密码

返回 1 个对象 : 数据库连接对象

String className = "com.mysql.cj.jdbc.Driver";
// 加载驱动 
Class.forName(className );
// 协议 地址 端口 数据库名
String url = "jdbc:mysql://127.0.0.1:3306/数据库名?serverTimezone=UTC";
// 建立连接
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url , username, password);

1.2.2.url 的属性列表

&
参数名称参数说明缺省值
useUnicode是否使用Unicode字符集,如果参数characterEncoding设置为gb2312或gbk,本参数值必须设置为truefalse
characterEncoding当useUnicode设置为true时,指定字符编码。比如可设置为utf8
autoReconnect当数据库连接异常中断时,是否自动重新连接?false
autoReconnectForPools是否使用针对数据库连接池的重连策略false
failOverReadOnly自动重连成功后,连接是否设置为只读?true
maxReconnectsautoReconnect设置为true时,重试连接的次数3
initialTimeoutautoReconnect设置为true时,两次重连之间的时间间隔,单位:秒2
connectTimeout和数据库服务器建立socket连接时的超时,单位:毫秒。0表示永不超时
socketTimeoutsocket操作(读写)超时,单位:毫秒。0表示永不超时
allowMultiQueries可以在sql语句后携带分号,实现多语句执行
可以执行批处理,同时发出多个SQL语句。
true
useSSL与服务器通信时使用ssl,
连接到MySQL5.5.45+、5.6.26+或5.7.6+时默认为“true”,否则默认为“false”
false/true
serverTimezone覆盖时区的检测/映射.当服务器的时区未映射到Java时区时使用UTC
allowPublicKeyRetrieval允许客户端从服务器获取公钥true

当数据库时区未映射到Java时区时可能导致Java代码中Date类型插入到mysql中datetime类型出现时间不一致的问题。例如:

上海:serverTimezone=Asia/Shanghai

简写:serverTimezone=CTT

北京:serverTimezone=UTC+8

或者:serverTimezone=GMT+8

关于时区UTC和GMT

举例:

jdbc:mysql://127.0.0.1:3306/数据库名?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false&autoReconnect=true&serverTimezone=GMT%2B8

1.2.3.持久化操作

需要 2 个参数 : SQL 语句 , 参数

返回 1 个对象 : 增/删/改 返回 影响条数 int 类型, 查询 返回 ResultSet 结果集

得到 句柄Statement

// 用于发送简单的SQL语句(不带参数)
Statement stmt = conn.createStatement();

// 预编译声明 ,可以使用点位符,防止SQL注入
PreparedStatement pstmt = conn.prepareStatement( sql );

//继承自PreparedStatement接口,用于调用存储过程
CallableStatement cstmt = conn.prepareCall( sql );

执行

// 用于执行 增加,删除,修改 SQL语句的方法,返回更新的行数。
int count = stmt.executeUpdate( sql );
// 运行select语句,返回ResultSet结果集。
ResultSet rs = stmt.executeQuery( sql );
// 运行语句,返回是否有结果集
boolean flag = stmt.execute( sql );
//关闭声明
stmt.close();

1.2.4.封装结果集

返回指定的 Java 常用类型 如: List<Map<String, Object>>

String sql = "select ct_id, ct_name, ct_begin_date, ct_count from class_team";
// 结果集  从1 开始 
ResultSet rs = stmt.executeQuery(sql);
// 封装结果集
// 结果集元数据
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();

List<Map<String, Object>> list = new ArrayList<>();

while (rs.next()) {
    Map<String, Object> map = new HashMap<>();
    for (int i = 1; i <= count; i++) {
        String colname = rsmd.getColumnName(i); //  从 1 开始
        int colType = rsmd.getColumnType(i);
        System.out.println(colname+"->"+colType);
        // byte int short char |   String
        switch (colType) {
            case Types.VARCHAR:
                map.put(colname, rs.getString(colname));
                break;
            case Types.DATE:
                map.put(colname, rs.getDate(colname));
                break;
            case Types.NUMERIC:
                map.put(colname, rs.getInt(colname));
                break;

            default:
                map.put(colname, rs.getObject(colname));
                break;
        }
    }
    list.add(map);
}

System.out.println(list);

1.2.5. // 释放资源

// 先入后出
rs.close();
stmt.close();
conn.close();

1.3.预编译

1.3.1.SQL 注入

String sql = " select ct_id, ct_count  from class_team  where ct_count < " + param ;

当一条Sql语句 要传入参数时, 如果传入的是

String param = " 50   or    1=1  ";  

得到的结果集就不是我们想要的, 而是查询条件失效

这种问题叫SQL注入问题

JDBC的预编译声明可以解决这类问题的

1.3.2.预编译声明

PreparedStatement pstmt = conn.prepareStatement(sql);

与Statement对象的不同

1.对象不同 PreparedStatement vs Statement

2.创建时传入SQL语句

3.传入的SQL语句 可以使用 ? 占位符

4.使用对象的set方法 为占位符 赋值, 指明点位符的类型 , 序号以及值

5.执行时不用传入SQL语句

String sql=" select ct_id , ct_count from class_team where ct_count <  ? "; 
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 50);
ResultSet rs = pstmt.executeQuery();

类型 : 根据在数据库中对应字段的类型

序号 : SQL语句中 ? 的序号, 注意:从1开始

值 : 要值到SQL语句中的值, 注意:要与类型对应

1.3.3.其它预编译SQL

-- 插入
insert into class_team (ct_id, ct_name, ct_begin_date, ct_count)
values  (?, ?, ?, ?)

-- 修改
update class_team
set
 	ct_name = ?,
	ct_begin_date = ?,
	ct_count = ?
where ct_id = ?

-- 删除
delete class_team   where ct_id = ?
delete class_team   where ct_id  in ( ?,?,? )

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据库连接池是一种用于管理数据库连接的技术。它通过创建一组预先初始化的数据库连接,并将这些连接存储在一个池中供应用程序使用。当应用程序需要与数据库交互时,它可以从连接池中获取一个可用的连接,使用完毕后再将连接返回到连接池中,以便其他应用程序重复利用。 在Tomcat下建立数据库连接池的方法如下: 1. 导入数据库驱动:将数据库驱动的jar文件放置在Tomcat的lib目录下。 2. 配置数据源:在Tomcat的conf目录下的context.xml文件中添加数据源的配置。例如,可以使用以下配置来创建一个基于Apache DBCP的数据库连接池: ```xml <Resource name="jdbc/myDB" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="your_username" password="your_password" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/myDB"/> ``` 这个配置指定了连接池的一些属性,如最大活动连接数(maxActive)、最大空闲连接数(maxIdle)、最大等待时间(maxWait)等。 3. 在应用程序中使用连接池:在应用程序的代码中通过JNDI(Java命名和目录接口)查找数据源,并从中获取连接。例如,可以使用以下代码获取连接: ```java Context initContext = new InitialContext(); Context envContext = (Context) initContext.lookup("java:/comp/env"); DataSource dataSource = (DataSource) envContext.lookup("jdbc/myDB"); Connection connection = dataSource.getConnection(); ``` 这样,就可以通过连接池获取到数据库连接,进行数据库操作。 通过使用数据库连接池,可以有效地管理数据库连接资源,提高应用程序的性能和可伸缩性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值