数据库(七)——JDBC编程

JDBC:

Java提供的一套操作数据库数据的应用编程接口,作用在于通过Java代码操作数据库;dk所提供的相应的编程接口;

JDBC组件:

  1. DriverManager:一系列的数据驱动程序,匹配连接使用通信协议从Java应用程序中获取合适的数据库驱动;
  2. Connection:所有和数据库相关的上下文操作通过该接口提供,提供数据库的事务操作,Statment对象等接口方法;
  3. Statment:使用创建该接口的对象来进行SQL语句的提交到数据库;
  4. ResultSet:存放使用SQL查询数据库返回的结果,本身是一个Set集合,多条数据是需要遍历才能拿到对应结果的;
  5. SQLException:所有JDBC操作异常的同意处理类;

JDBC编程步骤:

数据库连接的4个核心配置:

  1. 提供JDBC连接MySQL数据库,需要MySQL的驱动包;
  2. 请求数据库的URL;
  3. 数据库账号;
  4. 数据库密码;

数据库编程:

  1. 加载数据库驱动;
  2. 获取数据库的连接;
  3. 创建Statement对象;
  4. 执行SQL语句;
  5. 处理结果集 ;

代码:
在这里插入图片描述

public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test4", "root", "123456");
            Statement statement = connection.createStatement();
            String sql = "select * from student";
            ResultSet resultSet = statement.executeQuery(sql);

            while (resultSet.next()) {
                int sid = resultSet.getInt("sid");
                String sname = resultSet.getString("sname");
                int sage = resultSet.getInt("sage");
                String ssex = resultSet.getString("ssex");
                System.out.println(sid+"\t"+sname+"\t"+sage+"\t"+ssex);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

运行结果:

1	赵雷	20	男
2	前殿	20	男
3	孙风	21	男
4	吴兰	18	女
5	孙兰	17	女

注意:
getString()、getInt()等这些方法会将数据一次性装入内存,所以数据量过大的时候,内存会装不下就会抛出异常,而getObject()方法是每次调用就去数据库获取数据,不会将数据一次性全部装入内存;

SQL注入问题

SQL注入问题::
由于dao层中执行的SQL语句是拼接出来的,其中一部分内容是用户从客户端输入的,当传入的数据中包含SQL关键字,就有可能通过这些关键字来改变SQL语句,从而执行一些特殊的操作,这种就称为SQL注入问题;

比如,有如下这样一张user表:
在这里插入图片描述

public class TestDemo4 {
    public static void main(String[] args) {
        //前端输入  用户名和秘密
        String name = "zhangsan";
        String passwd = "1=1 or 2345";
        boolean login = login(name, passwd);
        if (login) System.out.println("登陆成功");
        else System.out.println("登陆失败");
    }

    /**
     * 模拟前后台交互接口
     *
     * @param userName:用户名
     * @param passwd:秘密
     * @return true:登陆成功  false:登陆失败
     */
    public static boolean login(String userName, String passwd) {
        boolean result = false;
        try {
            //加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取Connection连接
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test5", "root", "123456");
            //获取Statement对象
            Statement statement = connection.createStatement();
            String sql = " select * from user where name='"+userName+"' and passwd="+passwd+"";
            boolean b = statement.execute(sql);
            if(b) {
                result = true;
            }
           /*
            String sql = "select * from user where name = ? and passwd=?";
            PreparedStatement statement = connection.prepareStatement(sql);
            statement.setString(1, userName);
            statement.setString(2, passwd);

           //执行SQL
            ResultSet resultSet = statement.executeQuery();

            //结果处理
            if (resultSet.next()) {
                result = true;
            }*/
        } catch (ClassNotFoundException e) {
            e.printStackTrace();

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return result;
    }
}

运行结果:
在这里插入图片描述
密码明明是错的,但是因为SQL语句的改变1=1是成立的,所以它也能登陆成功,这就是SQL的注入问题,解决办法就是用PreparedStatement(屏蔽的那部分代码);

如何解决SQL注入问题:

  1. 采用预编译的Statement对象;PreparedStatement采用预编译机制将SQL语句的主干和参数分别传输给数据库,数据库是可以分辨SQL语句中的主干和参数,这样即使SQL中带有关键字,数据库也仅仅是将其当作参数使用,关键字就不起作用;

与Statement语句一样,PreparedStatement语句同样可以完成向数据库发送SQL语句,获取数据库操作结果的功能。PreparedStatement语句习惯地称为预处理语句。
Statement对象在每次执行SQL语句时都将该语句传送给数据库,然后数据库解释器负责将SQL语句转换成内部命令,并执行该命令,完成相应的数据库操作,这种机制,每次向数据库发送一条SQL语句时,都要先转化成内部命令,如果不断的执行程序,就会加重解释器的负担,影响执行的速度。
而PreparedStatement对象,将SQL语句传送给数据库进行预编译,以后需要执行同一条语句时就不再需要重新编译,直接执行就可以了,这样就大大提高了数据库的执行速度。

尽量使用预编译的PreparedStatement,PreparedStatement的主要优势如下:

  • 防止SQL注入问题;
  • 使用预编译机制可以提高执行效率(执行前已经完成解析,到时候直接运行即可);
  • SQL语句中的参数值是通过?的形式来代替参数,再使用PreparedStatement方法的set方法来设置参数值,相对于SQL直接拼接更加优雅;

PreparedStatement和Statement的区别:

  • 语法不同:PreparedStatement使用预编译的SQL,Statement使用静态的SQL;
  • 效率不同:PreparedStatement执行效率较高;
  • 安全性不同:PreparedStatement可以防止SQL注入;

JDBC提供的事务相关的操作:

通过Connection接口下的方法提供的,比如设置手动、自动提交、事务的提交、回滚等等;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值