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

1.JDBC

1.1.概念

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

数据库连接池 ( 一 ) JDBC 简述_第1张图片

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,本参数值必须设置为true false
characterEncoding 当useUnicode设置为true时,指定字符编码。比如可设置为utf8
autoReconnect 当数据库连接异常中断时,是否自动重新连接? false
autoReconnectForPools 是否使用针对数据库连接池的重连策略 false
failOverReadOnly 自动重连成功后,连接是否设置为只读? true
maxReconnects autoReconnect设置为true时,重试连接的次数 3
initialTimeout autoReconnect设置为true时,两次重连之间的时间间隔,单位:秒 2
connectTimeout 和数据库服务器建立socket连接时的超时,单位:毫秒。 0表示永不超时
socketTimeout socket操作(读写)超时,单位:毫秒。 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>

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 ( ?,?,? )

你可能感兴趣的:(SQL与数据库,数据库,java,JDBC)