JDBC使用

使用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

数据库更改后数据
数据库更改后数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值