JDBC和连接池
Posted Al_tair
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC和连接池相关的知识,希望对你有一定的参考价值。
JDBC和连接池
大家好,我是小笙,我们学习了JavaSe基础和mysql基础,自然而然我们需要通过JDBC和连接池来连接数据库和优化java程序操作数据库,以下是我的学习笔记
JDBC和连接池
JDBC
JDBC概述
java程序代码通过使用JDBC可以连接任何提供了JDBC驱动的数据库,从而完成对数据库的操作
JDBC基本原理图
JDBC API就是图中的接口规范,它统一了java应用程序和数据库的连接等操作
JDBC程序编写
- 注册驱动 - 加载Driver类
- Driver :每个驱动程序类必须实现的接口
- DriverManage :用于管理一组JDBC驱动程序的基本服务。
- 获取连接 - 得到Connection
- 执行增删改查 - 发送SQL语句给mysql数据库执行
- 释放资源 - 关闭相关的连接
连接数据库代码实现
// 方式一:静态加载
public static void main(String[] args) throws SQLException
// 1. 注册驱动 - 加载Driver类
Driver driver = new Driver();
// 2. 获取连接 - 得到Connection
String url = "jdbc:mysql://localhost:3308/al_tair";
// 将用户名和密码放入到Properties对象中
Properties properties = new Properties();
properties.setProperty("user","XXX"); // 用户
properties.setProperty("password","XXXXXX"); // 密码
Connection connect = driver.connect(url, properties);
// 3. 执行增删改查 - 发送SQL语句给mysql数据库执行
String sql = "insert into dog values(2,'steven')";
// statement用于执行静态sql语句并返回其生成的结果对象,后面具体详讲
Statement statement = connect.createStatement();
int rows = statement.executeUpdate(sql); // 返回是否添加成功
System.out.println(rows>0? "添加成功" : "添加失败");
// 4. 释放资源 - 关闭相关的连接
statement.close();
connect.close();
// 方式二:动态加载
// 1. 注册驱动 - 使用反射加载Driver类
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException
// 1. 注册驱动 - 使用反射加载Driver类
Class cls = Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver) cls.newInstance();
// 2. 获取连接 - 得到Connection
String url = "jdbc:mysql://localhost:3308/al_tair";
// 将用户名和密码放入到Properties对象中
Properties properties = new Properties();
properties.setProperty("user","XXX"); // 用户
properties.setProperty("password","XXXXXX"); // 密码
Connection connect = driver.connect(url, properties);
// 3. 执行增删改查 - 发送SQL语句给mysql数据库执行
String sql = "insert into dog values(3,'marry')";
// statement用于执行静态sql语句并返回其生成的结果对象
Statement statement = connect.createStatement();
int rows = statement.executeUpdate(sql); // 返回是否添加成功
System.out.println(rows>0? "添加成功" : "添加失败");
// 4. 释放资源 - 关闭相关的连接
statement.close();
connect.close();
// 方式三:DriverManage
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException
// 1. 注册驱动 - 加载Driver类 - DriverManage :用于管理一组JDBC驱动程序的基本服务
Class cls = Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver) cls.newInstance();
String url = "jdbc:mysql://localhost:3308/al_tair";
String root = "XXX";
String pwd = "XXXXXX";
// 注册驱动
DriverManager.registerDriver(driver);
// 2. 获取连接 - 得到Connection
Connection connection = DriverManager.getConnection(url, root, pwd);
// 3. 执行增删改查 - 发送SQL语句给mysql数据库执行
String sql = "insert into dog values(4,'tony')";
// statement用于执行静态sql语句并返回其生成的结果对象
Statement statement = connection.createStatement();
int rows = statement.executeUpdate(sql); // 返回是否添加成功
System.out.println(rows>0? "添加成功" : "添加失败");
// 4. 释放资源 - 关闭相关的连接
statement.close();
connection.close();
// 方式四:方式三的简化版(推荐)
/*
Driver 原码分析:注册Driver在静态代码块中已经实现
public class Driver extends NonRegisteringDriver implements java.sql.Driver
public Driver() throws SQLException
static
try
DriverManager.registerDriver(new Driver());
catch (SQLException var1)
throw new RuntimeException("Can't register driver!");
*/
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException, SQLException
Class cls = Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3308/al_tair";
String root = "XXX";
String pwd = "XXXXXX";
// 1. 获取连接 - 得到Connection
Connection connection = DriverManager.getConnection(url, root, pwd);
// 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
String sql = "insert into dog values(5,'jack')";
// statement用于执行静态sql语句并返回其生成的结果对象
Statement statement = connection.createStatement();
int rows = statement.executeUpdate(sql); // 返回是否添加成功
System.out.println(rows > 0 ? "添加成功" : "添加失败");
// 3. 释放资源 - 关闭相关的连接
statement.close();
connection.close();
// 方式五:mysql5.1.6可以无需手动反射Driver类,会自动调用驱动jar下的驱动包
public static void main(String[] args) throws SQLException
String url = "jdbc:mysql://localhost:3308/al_tair";
String root = "root";
String pwd = "luo1234567";
// 1. 获取连接 - 得到Connection
Connection connection = DriverManager.getConnection(url, root, pwd);
// 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
String sql = "insert into dog values(6,'son')";
// statement用于执行静态sql语句并返回其生成的结果对象
Statement statement = connection.createStatement();
int rows = statement.executeUpdate(sql); // 返回是否添加成功
System.out.println(rows > 0 ? "添加成功" : "添加失败");
// 3. 释放资源 - 关闭相关的连接
statement.close();
connection.close();
使用配置文件读入来连接数据库
// Properties.properties
root = root
pwd = XXXXXX
url = jdbc:mysql://localhost:3308/al_tair
driver = com.mysql.jdbc.Driver
// package com.Al_tair.connectMySql.myJDBC;
public class JdbcDemo6
public static void main(String[] args) throws IOException, SQLException
Properties properties = new Properties();
String filePath = "E:\\\\Java_training\\\\Java_code\\\\JavaIdea03\\\\java\\\\Javase_HSping\\\\src\\\\com\\\\Al_tair\\\\connectMySql\\\\myJDBC\\\\Properties.properties";
properties.load(new FileInputStream(filePath));
String url = properties.getProperty("url");
String root = properties.getProperty("root");
String pwd = properties.getProperty("pwd");
// 1. 获取连接 - 得到Connection
Connection connection = DriverManager.getConnection(url, root, pwd);
// 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
String sql = "insert into dog values(7,'Jason')";
// statement用于执行静态sql语句并返回其生成的结果对象
Statement statement = connection.createStatement();
int rows = statement.executeUpdate(sql); // 返回是否添加成功
System.out.println(rows > 0 ? "添加成功" : "添加失败");
// 3. 释放资源 - 关闭相关的连接
statement.close();
connection.close();
// 拓展:如果用idea编译器无法正确使用相对路径,检查:Run -> Edit Configurations -> 选中对应java程序修改Working directory,该地址就是相对位置的起点;如果不会就使用全路径
Statement
Statement对象用于执行静态SQL语句并返回其生成的结果对象
在业务中,我们一般不使用Statement对象对数据库(存在SQL注入的风险:利用某些系统没有对用户输入的数据及逆行充分的过滤,注入非法的SQL语句,恶意攻击数据库)
进而我们使用 PrepareStatement(预处理,主要使用这个),CallableSatement(可以处理数据库的存储过程)
// PrepareStatement 讲解
// ? 占位符 可以通过set语句填充,如下图
String sql = "SELECT *FROM emp WHERE username = ? AND password = ?";
// 预处理的好处
// 1. 不再使用 + 拼接sql语句,减少语法错误
// 2. 有效的解决了sql注入问题
// 3. 大大减少了编译次数,效率较高
// executeUpdate() 方法无需再填入sql语句
public static void main(String[] args) throws IOException, SQLException
String admin_name = "";
String admin_pwd = "";
// 读取配置文件
Properties properties = new Properties();
String filePath = "src\\\\com\\\\Al_tair\\\\connectMySql\\\\myJDBC\\\\Properties.properties";
properties.load(new FileInputStream(filePath));
String url = properties.getProperty("url");
String root = properties.getProperty("root");
String pwd = properties.getProperty("pwd");
// 1. 获取连接 - 得到Connection
Connection connection = DriverManager.getConnection(url, root, pwd);
// 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
String sql = "select `name`,pwd from admin where name = ? and pwd = ? ";
// preparedStatement用于执行静态sql语句并返回其生成的结果对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,admin_name);
preparedStatement.setString(2,admin_pwd);
int rows = preparedStatement.executeUpdate();
System.out.println(rows> 0 ? "成功" : "失败");
// 3. 释放资源 - 关闭相关的连接
preparedStatement.close();
connection.close();
ResultSet(结果集)
概念:表示数据库结果集的数据表(通常通过执行查询数据库语句执行)
ResultSet对象保持一个光标指向当前的数据行,光标从第一行开始向下遍历,如果没有更多行的时候将会返回false,迭代器的用法
public class ResultSetDemo1
public static void main(String[] args) throws IOException, SQLException \\
// 读取配置文件
Properties properties = new Properties();
String filePath = "src\\\\com\\\\Al_tair\\\\connectMySql\\\\myJDBC\\\\Properties.properties";
properties.load(new FileInputStream(filePath));
String url = properties.getProperty("url");
String root = properties.getProperty("root");
String pwd = properties.getProperty("pwd");
// 1. 获取连接 - 得到Connection
Connection connection = DriverManager.getConnection(url, root, pwd);
// 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
String sql = "select *from dog";
// statement用于执行静态sql语句并返回其生成的结果对象
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next())
int index = 1;
int id = resultSet.getInt(index++); // 获取第一列
String name = resultSet.getString(index); // 获取第二列
System.out.println("id: "+ id + " name: "+name);
// 3. 释放资源 - 关闭相关的连接
resultSet.close();
statement.close();
connection.close();
JDBC API梳理
JDBC自定义工具类
为了减少代码复用性,我们添加工具类来实现连接和关闭
public class JDBCUtils
private static String user; // 用户名
private static String password; // 密码
private static String url; // url
static
String filePath = "E:\\\\Java_training\\\\Java_code\\\\JavaIdea03\\\\java\\\\Javase_HSping" +
"\\\\src\\\\com\\\\Al_tair\\\\connectMySql\\\\utils\\\\Properties.properties";
Properties properties = new Properties();
try
properties.load(new FileInputStream(filePath));
user = properties.getProperty("root");
password = properties.getProperty("pwd");
url = properties.getProperty("url");
catch (IOException e)
throw new RuntimeException(e);
// 连接数据库
public static Connection getConnection()
try
return DriverManager.getConnection(url,user,password);
catch (SQLException throwables)
throw new RuntimeException(throwables);
// 查询语句关闭
public static void closeQueryConnection(ResultSet rst, Statement statement,Connection connection)
try
rst.close();
statement.close();
connection.close();
catch (SQLException throwables)
throw new RuntimeException(throwables);
// dml语句操作关闭
public static void closeDmlConnection(Statement statement,Connection connection)
try
statement.close();
connection.close();
catch (SQLException throwables)
throw new RuntimeException(throwables);
操作数据库的事务
概念:创建Connection默认是自动提交事务,每次执行sql语句都会默认自动提交commit,不能发生回滚
批处理
作用:用来一次性插入多条sql语句,提高插入效率
JDBC批量处理(PreparedStatement接口)方法如下
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.addBatch(); // 增加批处理数据
preparedStatement.executeBatch(); // 进行批处理
preparedStatement.clearBatch(); // 清空批处理
注意:JDBC连接Mysql时候,如果要使用批处理功能,必须在url路径中添加如下语句,并且往往和PreparedStatement一起使用,不仅减少编译次数,也可以减少运行次数,效率大大提高
// 添加?rewriteBatchedStatements=true语句
root = xxxx
pwd = xxxxxxxx
url = jdbc:mysql://localhost:3308/al_tair?rewriteBatchedStatements=true
测试代码(批量处理大大减少时间)
// 批处理底层数据就是存放在ArrayList集合中batchedArgs对象数组中
public class BatchDemo
public static void main(String[] args) throws SQLException
Connection connection = JDBCUtils.getConnection();
// ? 占位符
String sql = 04-JDBC-连接池