0%

JDBC

视频资源:黑马程序员完整JavaWeb快速入门教程【收藏比赞多系列】_哔哩哔哩_bilibili

API详解

DriverManager

注册驱动

  • registerDriver(Driver driver) 一般不用这个;

  • DriverManager.registerDriver(new Driver()) 该方法中的代码块已经调用第一个方法,更常用;

开发中常用Class.forName("com.mysql.cj.jdbc.Driver");

获得连接

getConnection(url,user,password); 与数据库连接(即为数据库的用户和密码)

url详解

jdbc:mysql://localhost:3306/database

  • jdbc:连接数据库的协议;
  • mysql:jdbc的子协议;
  • localhost:连接的MySQL数据库服务器的主机地址,localhost表示本机,如果不是则写连接主机的IP地址;
  • 3306:MySQL数据库服务器的端口号;
  • database:数据库名称;

Connection

创建执行SQL语句的对象

Statement

执行SQL

CallableStatement

执行数据库中存储过程

PreparedStatement

执行SQL,对SQL进行预处理,可用来解决SQL漏洞

管理事务

  • setAutoCommit() 首先关掉自动提交;
  • commit() 提交事务;
  • rollback() 回滚事务;

Statement

执行SQL

execute(sql)

查询、修改、添加、删除;

返回boolean类型(如果有ResultSet对象返回就返回true);

executeQuery(sql)

查询(select)

返回一个ResultSet对象;

executeUpdate(sql)

修改、添加、删除;

返回int类型(表示对多少条记录进行了操作);

执行批处理

addBatch(sql)

将SQL命令添加到当前命令列表;

clearBatch(sql)

清空当前命令列表;

executeBatch()

执行批处理;

ResultSet

结果集,通过select才会有。

结果集遍历

next();指向下一条记录;

结果集获取

getxxx();方法重载中一般选择传入string参数的方法

资源释放

JDBC程序结束后,将与数据库进行交互的对象释放掉,通常是ResultSet,Statement,Connection。尤其是Connection尽量晚创建早释放。

书写规范

写到finally代码块中(try,catch,finally),表示一定会执行。

1
2
3
4
5
6
7
8
9
10
finally{
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
conn=null; //设置为null有助于更快被回收
}
}

CRUD操作

  • 保存:insert
  • 修改:update
  • 删除:delete

以上三个需要Statement和Connection对象

  • 查询:select 还需要ResultSet

抽取工具类

新建工具类

将对应重复语句写到方法中

配置信息提取

配置文件

  • 属性文件(.properties)(key=value)
  • XML文件

提取信息到配置文件

定义一个配置文件:在src下新建一个file(filename.properties),将所用到的信息如用户名密码等写入。
注意不用写双引号和分号

在工具类中解析属性文件

利用Properties类,获取文件中的值并为常量赋值

1
2
3
Properties properties = new Properties();
properties.load(new FileInputStream("src/db.properties"));
key=properties.getProperty("key");

SQL漏洞

两种基本输入漏洞

单引号闭合加or万能语句;

--space注释掉后面的

解决

不能在前端控制用户输入,因为攻击者可以直接绕过js事件到后端,因此关键在后端。
通过PreparedStatement对象将SQL进行预编译处理。

1
2
3
4
5
6
7
8
9
10
PreparedStatement prepared=null;
//用?作为占位符,传入参数时不再识别输入内容中的SQL关键字
String sql="select * from user where username=? and password=?";
//对sql语句进行预编译处理
prepared=connection.prepareStatement(sql);
//设置问号所代表的参数,1代表第一个问号,2代表第二个
prepare.setString(1,username);
prepare.setString(2,password);
//执行SQL语句,不用传参了
res=prepare.executeQuery();

批处理操作

addBatch();

executeBatch();

是否支持批处理

使用 DatabaseMetaData.supportsBatchUpdates() 方法来确定目标数据库是否支持批处理更新:

1
2
3
4
import java.sql.DatabaseMetaData;
//该对象不能通过new得到
DatabaseMetaData data = connection.getMetaData();
Boolean flag=data.supportsBatchUpdates();

JDBC的事务管理

1
2
3
4
5
6
7
8
9
10
try{
//事务开启之前
connection.setAutoCommit(false);
..........................
//事务结束后提交事务
connection.commit();
}catch(Exception e){
//如果出现异常则回滚事务
connection.rollback;
}

连接池

概念:创建和管理一个连接的缓冲池的技术(装有连接的容器),获取连接使用完之后将连接归还到连接池。
作用:提高效率/性能。

开源连接池

Druid

下载jar包并导入

下载:Central Repository: com/alibaba/druid (maven.org) 选择.jar下载

导入参照mysql-connector的导入(在文章“Java-web”中)

导入jar包后import显示not accessible:
在module-info写入require druid;

配置

在src下新建druid.properties,一般配置参照上文抽取工具类,在Java中代码实现:

1
2
3
4
Properties properties=new Properties();
properties.load(new java.io.FileInputStream("src/druid.properties"));
DataSource dataSource=DruidDataSourceFactory.createDataSource(properties);
connection=dataSource.getConnection();

其他配置:

1
2
3
4
5
initialSize=10	#<!--初始化连接-->
maxActive=50 #<!--最大连接数量-->
maxIdle=20 #<!--最大空闲连接-->
minIdle=5 #<!--最小空闲连接-->
maxWait=60000 #<!--超时等待(毫秒)-->

C3P0

改写工具类

一个应用应该只创建一个连接池。

DBUtils

对JDBC的简单封装。将类似的代码进行抽取,简化编程。

API

QueryRunner-核心运行类

构造方法

  • QueryRunner()
  • QueryRunner(DataSource ds) 传入连接池;

方法

  • update(String sql, Object... params) 可执行insert,update,delete语句;
  • update(Connection conn, String sql, Object... params)
  • query(String sql, ResultSetHandler<T> rsh, Object... params) 查询;
  • query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
  • batch(String sql, Object[][] params) 执行批处理;
  • batch(Connection conn, String sql, Object[][] params)
1
2
3
4
//一般情况下
QueryRunner(DataSource ds);
update(String sql, Object... params);
query(String sql, ResultSetHandler<T> rsh, Object... params)
1
2
3
4
//有事务管理时
QueryRunner();
update(Connection conn, String sql, Object... params);
query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)

ResultSetHandler的实现类

  • ArrayHandler/ArrayListHandler; 封装到数组;
  • BeanHandler/BeanListHandler; 封装到对象;
  • MapHandler/MapListHandler;
  • ColumnListHandler; 将某列封装到List集合;
  • ScalarHandler; 单值封装;
  • KeyedHandler;

DBUtils

API

  • commitAndCloseQuiety(Connection conn)
  • rollbackAndCloseQuietly(Connection conn)

quiet指默认将异常处理了。