使用JDBC有以下操作
1、加载驱动
// 第一种加载方式
Driver driver = new com.mysql.cj.jdbc.Driver();
DriverManager.registerDriver(driver);
// 第二种加载方式
Class.forName("com.mysql.cj.jdbc.Driver")
// 通过forName反射机制加载Driver的时候,会执行Driver类的静态代码块,加载DriverManager
Driver类的静态代码块
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
通过DriverManager对象获取连接对象Connection
String mysqlConn = "jdbc:mysql://localhost:3306/work?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"
Connection connection = DriverManager.getConnection(mysqlConn,"root","123456"); // 第一个参数为mysql数据库地址,第二个参数为用户名,第三个参数为密码
通过连接对象获取会话,有2种方式Statement、PreparedStatement,
Statement允许字段拼接,会有被sql注入的风险
String name = null;
String sqlUrl = null;
name = "aaa";
sqlUrl = "select * from user where name='"+name+"' order by name;"
// 结果:sqlUrl = "select * from user where name='aaa' order by name;"
// 这个语句会搜索出所有name值为aaa的数据并以name排序;
name = "' or '1'='1"
sqlUrl = "select * from user where name='"+name+"' order by name;"
// 结果:sqlUrl = "select * from user where name='' or '1'='1' order by name;"
/*这个语句会找到所有name值为空或者满足'1'='1'的数据,由于'1'='1'是恒成立的,所以会返回数据库
所有用户信息,这样就很危险,但是Statement也并非一无是处,在某些特殊需求的情况下,也能发挥特别的作用*/
String key = "name";
sqlUrl = "select * from user where "+key+"='"+name+"' order by name;"
// 结果:sqlUrl = "select * from user where name='aaa' order by name;"
// 这时候可以拼接sql字段名,实现动态搜索key的功能
PreparedStatement使用预编译,不允许字段拼接,可以防止sql注入,安全性高
// 使用占位符?代替我们需要传入的参数
String username = "aaa";
int age = 22;
String sqlUrl = "select * from test where username=? and age=?";
// 将语句传入prepareStatement中预编译
PreparedStatement ps= connection.prepareStatement(sqlUrl);
// 将字段值传入ps中
ps.setString(1,username);
ps.setInt(2,age);
通过会话进行数据的增删改查,封装对象,添加事务
connection.setAutoCommit(false); // 关闭自动提交
connection.commit(); // 事务提交
// 设置事务
int resNum = preparedStatement.executeUpdate(sqlUrl);
// 如果是更新,插入,删除操作使用executeUpdate,返回的是操作影响的行数
ResultSet resultSet = preparedStatement.executeQuery(sqlUrl)
// 在每次赋值后将preparedStatement对象加入batch中
ps1.addBatch();
// 然后用executeBatch执行,返回Batch每个对象的运行结果
int [] resBatchNum = preparedStatement.executeBatch();
// 如果是查询操作使用executeQuery,返回的是一个结果集
while (resultSet.next()) {
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
String password = resultSet.getString(3);
System.out.println(id+name+password);
}
// 通过next方法可以遍历出所有的数据,通过getString或者getInt等方法获取对应类型的数据
关闭资源、关闭会话、关闭连接。
connection.close();
preparedStatement.close();
resultSet.close();
完整演示
数据库内容
代码
package org.example;
import java.sql.*;
public class App
{
public static void main( String[] args )
{
Connection connection = null;
PreparedStatement ps1 = null;
PreparedStatement ps2 = null;
ResultSet resultSet = null;
try {
// 数据库连接地址
String sqlUrl = "jdbc:mysql://localhost:3306/work?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
// 添加占位符的sql语句
String selectWord = "select * from test where username=?";
String insertWord = "insert into test (username,password) values(?,?)";
// 通过反射机制加载DriverManage
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取Connection对象
connection = DriverManager.getConnection(sqlUrl,"root","123456");
// 关闭自动提交,添加事务管理
connection.setAutoCommit(false);
// 创建PreparedStatement对象,编译sql语句
ps1 = connection.prepareStatement(insertWord);
ps2= connection.prepareStatement(selectWord);
// 遍历添加数据,调用addBatch
for(int i=0;i<3;i++){
ps1.setString(1,"lisi"+i);
ps1.setString(2,"password"+i);
ps1.addBatch();
}
// 执行executeBatch,返回结果数组
int [] resBatchNum = ps1.executeBatch();
for (int i:resBatchNum){
System.out.println("batch结果"+i);
}
// 单独添加数据
ps1.setString(1,"lisi");
ps1.setString(2,"456");
int resNum = ps1.executeUpdate();
System.out.println("update插入了"+resNum+"条数据");
// 向PreparedStatement中传入占位符的值
ps2.setString(1,"lisi");
// 执行语句,返回一个ResultSet集合
resultSet = ps2.executeQuery();
// 通过next方法,遍历集合
while (resultSet.next()) {
// 逐个获取值
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
String password = resultSet.getString(3);
System.out.println("id是"+id+"名字是"+name+"密码是"+password);
}
// 提交事务
connection.commit()
} catch (ClassNotFoundException | SQLException classNotFoundException) {
classNotFoundException.printStackTrace();
}
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
}
if (ps1 != null) {
try {
ps1.close();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
}
if (ps2 != null) {
try {
ps2.close();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
}
}
}
结果
batch结果1
batch结果1
batch结果1
update插入了1条数据
id是1名字是lisi密码是123
id是7名字是lisi密码是456
数据库更改后数据