栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDBC 接口总结(IDEA版本)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDBC 接口总结(IDEA版本)

一、关于SQL注入问题

问题代码:

Connection conn = null;
Statement stat = null;
ResultSet rs = null;

// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取数据库连接
String url = "jdbc:mysql://localhost:3306/数据库名";
String user = "用户";
String pwd = "密码";
conn = DriverManager.getConnection(url, user,pwd);
// 获取数据库操作对象
stat = conn.createStatement();
//执行sql语句
String sql = "select * from t_user where user = '"+userName+"' and pwd = '"+passwd+"'";
rs = stat.executeQuery(sql);
// 处理结果集
if (rs.next()){
    return true;
}

问题:

userName = sasas
passwd = sa' or '1' = '1
那么就会出现sql注入现象
语句就会成这样
String sql = "select * from t_user where user = 'sasas' and pwd = 'sa' or '1' = '1'";
那么select语句就会执行成功

怎么解决SQL注入现象?

解决sql注入问题
    使用:PreparedStatement(预编译数据库操作对象)
    原理:预先对sql语句的框架进行编译,再给sql语句传值

解决代码:

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取数据库连接
String url = "jdbc:mysql://localhost:3306/数据库名";
String user = "用户";
String pwd = "密码";
conn = DriverManager.getConnection(url, user,pwd);
// 获取预编译数据库操作对象
String sql = "select * from t_user where user = ? and pwd = ?"; // 问号代表占位符,一个"?"代表一个值,不能用单引号括起来
ps = conn.prepareStatement(sql);
//给?号传值 --> 在jdbc中索引是从1开始
ps.setString(1,userName);  // 1代表第一个问号
ps.setString(2,passwd);
//执行sql语句
rs = ps.executeQuery();
// 处理结果集
if (rs.next()){
    return true;
}
二、对PreparedStatement的"增删改"进行演示
Connection conn = null;
PreparedStatement ps = null;

// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库名","用户","密码");
// 获取数据库预编译对象
// 增 insert
String sql = "insert into dept values(?,?,?)";
ps = conn.prepareStatement(sql);
ps.setInt(1, 60);
ps.setString(2, "经理");
ps.setString(3, "广州");

// 改 update 
String sql = "update dept set deptno = ? where deptno = 60";
ps = conn.prepareStatement(sql);
ps.setInt(1, 80);

// 删 delete
String sql = "delete from dept where deptno = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1, 80);

// 执行sql语句
int count = ps.executeUpdate();
System.out.println(count);

// 关闭资源
ps.close();
conn.close();
三、演示事务机制
演示jdbc中的事务机制
    重点三行代码
        conn.setAutoCommit(false)
        conn.commit()
        conn.rollback()

void setAutoCommit(boolean autoCommit)
autoCommit - 为 true 表示启用自动提交模式;为 false 表示禁用自动提交模式
将此连接的自动提交模式设置为给定状态。如果连接处于自动提交模式下,则它的所有
SQL 语句将被执行并作为单个事务提交。否则,它的 SQL 语句将聚集到事务中,直到调用
commit 方法或 rollback 方法为止。默认情况下,新连接处于自动提交模式。

没有事务的情况:

// 没有事务的情况
public static void main(String[] args) {
    Connection conn = null;
    PreparedStatement ps = null;
    try {
        // 1、注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2、获取连接
        conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库","用户","密码");
        // 3、获取预编译数据库对象
        String sql = "update tbl_act set money = ? where no = ?";
        ps = conn.prepareStatement(sql);
        ps.setDouble(1, 10000);
        ps.setInt(2,111);
        int count = ps.executeUpdate();

        // 但抛出异常那么下面的语句不会执行,导致钱丢失,所以这里需要用到事务机制
        String s = null;
        s.toString();

        ps.setDouble(1,10000);
        ps.setInt(2,222);

        count += ps.executeUpdate();
        System.out.println(count == 2 ? "转账成功" : "转账失败");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }finally{
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

开启事务的情况:

// 有事务的情况
public static void main(String[] args) {
    Connection conn = null;
    PreparedStatement ps = null;
    try {
        // 1、注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2、获取连接
        conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库","用户","密码");
        // 设置为手动提交模式,手动提交sql语句
        conn.setAutoCommit(false);
        // 3、获取预编译数据库对象
        String sql = "update tbl_act set money = ? where no = ?";
        ps = conn.prepareStatement(sql);
        ps.setDouble(1, 10000);
        ps.setInt(2,111);
        int count = ps.executeUpdate();

        // 当抛出异常那么下面的语句不会执行,导致钱丢失,所以这里需要用到事务机制
        

        ps.setDouble(1,10000);
        ps.setInt(2,222);

        count += ps.executeUpdate();
        System.out.println(count == 2 ? "转账成功" : "转账失败");

        // 能执行到这里说明没有出现异常,就是说转账成功
        // 执行commit方法
        conn.commit();
    } catch (Exception e) {
        // 如果出现异常需要进行回滚操作,即是第一个转账成功之后进行回滚回到没有转账之前
        // 也就是上一次事务提交成功的位置
        if (conn != null){
            try {
                conn.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        e.printStackTrace();
    } finally{
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}
四、悲观锁的概念(行级锁)

语法:
select * from emp where job = ? for update

加了for update后只要当前事务不提交,那其他事务就无法对当前查询的行内容进行操作

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库","用户","密码");
conn.setAutoCommit(false);
// 获取预编译数据库操作对象
String sql = "select * from emp where job = ? for update";
ps = conn.prepareStatement(sql);
ps.setString(1, "manager");
// 执行sql语句
rs = ps.executeQuery();
while(rs.next()){
    System.out.println(rs.getString("ename"));
}
conn.commit();

不懂到时候在看代码。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/750342.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号