3.JDBC操作

本文介绍了JDBC的使用,包括常见错误、SQL注入问题、PreparedStatement的使用,以及封装工具类、事务处理、三层架构等内容。重点讲解了如何避免SQL注入,通过PreparedStatement预编译SQL以提高效率和安全性。此外,还探讨了DAO层的设计和Druid连接池的使用,以及Apache DaoUtils在简化JDBC操作中的作用。
摘要由CSDN通过智能技术生成

 回顾之前连接数据库的方式
    DOS指令方式,图形化方式
    缺点:
    只能是简单地SQL语句的测试,无法在项目中操作数据库
    
    引出通过java代码方式连接数据库---JDBC
    概述:JDBC是一套连接数据库的标准;具体的实现是由不同的数据库提供的    
 

 

JDBC核心思想:
    Java 中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式。由数据库厂商提供驱动实现类(Driver 数据库驱动)。


    JDBC操作步骤:

1、加载驱动

2、获取连接对象

3、获取执行对象

4、执行CRUD操作

5、获取执行结果

6、关闭数据库资源

  常见的异常问题:
  ClassNotFoundException   驱动加载失败
  MySQLSyntaxErrorException: 数据库或SQL语句异常
  SQLException: Access denied   账户或密码出错
  MySQLIntegrityConstraintViolationException  主键冲突

DML操作

//案例:给岗位表添加一条数据
public class DMLTest {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.通过驱动管理器获取连接对象   alt+enter弹出异常与赋值变量
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1", "root", "123");
        //3.通过连接对象获取执行对象
        Statement st = conn.createStatement();
        //4.进行增删改查操作  增删改:executeUpdate
        //String sql = "insert into t_jobs(job_id,job_title,min_salary,max_salary) values('QF_PRA','PRA',13000,18000)";
        //String sql = "update t_jobs set min_salary=20000,max_salary=30000 where job_id='QF_PRA'";
        String sql = "delete from t_jobs where job_id='QF_PRA'";
        //5.反馈结果
        int result = st.executeUpdate(sql);
        System.out.println("影响的条数:"+result);

        //6.关闭资源,先关小的再关大的
        DBUtils.closeAll(st,conn);
    }
}

DQL操作

//查询学生表的数据
public class DQLTest {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb1", "root", "123");
        Statement st = conn.createStatement();
        //获取结果集
        ResultSet rs = st.executeQuery("select * from student");
        List<Student> list = new ArrayList<>();
        //循环遍历,获取所有记录(每次循环,都是一条记录
        while(rs.next()){
            //int id = rs.getInt(1); //1代表第1列;应用场景:聚合查询反馈
            int id = rs.getInt("id");  //id:字段名获取值
            String name = rs.getString("name");
            int age = rs.getInt("age");
            System.out.println(id+"-->"+name+"-->"+age);
            //应用场景:反馈零散的内容,应该需要对象封装,
                    list.add(new Student(id,name,age));
        }

        System.out.println("集合中存储的数据:"+list);
        DBUtils.closeAll(rs,st,conn);  //关闭资源
    }
}

遍历 ResultSet 中的数据

ResultSet 以表(table)结构进行临时结果的存储,需要通过 JDBC API 将其中数据进行依次获取。

  • 数据行指针:初始位置在第一行数据前,每调用一次 boolean next()方法ResultSet 的指针向下移动一行,结果为 true,表示当前行有数据。

  • rs.getXxx(整数);代表根据列的编号顺序获得,从 1 开始。

  • rs.getXxx("列名");代表根据列名获得。

常见错误


SQL注入问题


 什么是 SQL 注入

用户输入的数据中有 SQL 关键字或语法并且参与了 SQL 语句的编译,导致 SQL 语句编译后的条件含义为 true,一直得到正确的结果。这种现象称为 SQL 注入。

 如何避免 SQL 注入

由于编写的 SQL 语句是在用户输入数据,整合后再进行编译。所以为了避免 SQL 注入的问题,我们要使 SQL 语句在用户输入数据前就已进行编译成完整的 SQL 语句,再进行填充数据。

PreparedStatement【重点


PreparedStatement 继承了 Statement 接口,执行 SQL 语句的方法无异。

PreparedStatement的应用

作用:

  • 预编译SQL 语句,效率高。

  • 安全,避免SQL注入 。

  • 可以动态的填充数据,执行多个同构的 SQL 语句。

private static boolean login2(String username, String password) {
        Connection conn = null;
        PreparedStatement prst   = null;
        ResultSet rs    = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///mydb1", "root", "123");
            //PreparedStatement:预处理执行对象    ?为占位符
            //好处: 1.安全性高,解决了sql注入问题
                  //2. 执行性能会更高
                  //3. 方便进行批处理操作
            prst = conn.prepareStatement("select count(*) from user where username=? and password=?");
            //参数1:对应第一个占位符? 下标从1开始
            prst.setString(1,username);
       prst.setString(2,password);
            //获取结果集
            //sql注入的隐患
            rs = prst.executeQuery();
            if(rs.next()){
                int result = rs.getInt(1); //聚合函数只有一个字段
                return result>0;  //result不小于0,则返回true
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtils.closeAll(rs,prst,conn);
        }
        return false;
    }

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值