34-jdbc各个类详解


        5. PreparedStatement:执行sql的对象


            1.以上问题是 SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
              1. 输入用户随便,输入密码:a' or 'a' = 'a
              2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a' 

 where username = 'fhdsjkf' and password = 'a' or 'a' = 'a' --》flase or true=true  所以这里会有bug

            2. 解决sql注入问题:使用PreparedStatement对象来解决  

与statement类似也是执行sql语句的方法

获取执行sql的对象
Statement stmt = conn.createStatement();

            3. 预编译的SQL:参数使用?作为占位符
            4. 步骤:
                1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
                2. 注册驱动
                3. 获取数据库连接对象 Connection
                4. 定义sql
                    * 注意:sql的参数使用?作为占位符。 如:select * from user where username =
? and password = ?;
                5. 获取执行sql语句的对象 PreparedStatement  Connection.prepareStatement(String sql) 
                6. 给?赋值:
                    * 方法: setXxx(参数1,参数2)
                        * 参数1:?的位置编号  从1 开始
                        * 参数2:?的值
                7. 执行sql,接受返回结果,不需要传递sql语句  获取对象时候就传递了sql语句
                8. 处理结果
                9. 释放资源

            5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
                1. 可以防止SQL注入
                2. 效率更高

注意这种方法是主要用的

后期都会使用PreparedStatement来完成增删改查的所有操作

增删改查 这里是查

package cn.itcast.jdbc;

import cn.itcast.utils.JdbcUtils;

import java.sql.*;
import java.util.Scanner;

/*

		* 需求:
			1. 通过键盘录入用户名和密码
			2. 判断用户是否登录成功
 */
public class JdbcDemo11 {
    public static void main(String[] args) {
        //1.键盘录入 接受用户名和密码
        Scanner sc= new Scanner(System.in);
        System.out.println("请输入用户名");
        String username = sc.nextLine();
        System.out.println("请输入密码");
        String password = sc.nextLine();
        //2.调用方法 返回Boolean
        boolean flag = new JdbcDemo11().login02(username,password);
        //3.判断结果 输出语句
        if (flag=true){
            System.out.println("登陆成功");
        }else{
            System.out.println("用户名或者密码错误");
        }
    }


    //登录方法
    public static boolean  login02(String username, String password){
        if (username==null&&password==null){
            return  false;
        }
        /*连接数据库来判断是否登陆成功
         * select * from user where username = '"+username+"' and password = '"+password+"';
         * 如果这个sql有查询结果,则成功,反之,则失败
         */
//1.获取数据库连接
        Connection conn=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        try {
             conn = JdbcUtils.getConnection();
            //2.定义sql
            String sql = "select * from user where username = ? and password = ?";
            //3.获取执行sql的对象
             pstmt = conn.prepareStatement(sql);
            //给问号赋值
            pstmt.setString(1,username);
            pstmt.setString(2,password);
            //4、执行查询  返回结果集resultSet对象
            rs = pstmt.executeQuery(); //这里不需要传递sql了
            //5.判断
            /*if (rs.next()){ //如果有下一行则返回true
                return  true;
            }else{
                return  false;  //
            }*/
            return rs.next();  //游标下移一行有数据true 无数据返回false
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            JdbcUtils.close(rs,pstmt,conn);
        }
        return false;  //这里的false相对与上面的如果出现了异常就返回这个false 因为之前的先判断
    }
}

jdbcutils工具类 

package cn.itcast.utils;

import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.sql.*;
import java.util.Properties;

/*
Jdbc工具类
 */
public class JdbcUtils {
    private static String url;  //把这三个本来是局部变量的变量作用域提升
    private static String user;
    private static String password;
    private static String driver;

    //这里为什么是静态的成员变量呢 因为只有静态的成员变量和成员方法才能被静态代码段所访问
    /*
    文件的读取,只需要读取一次即可拿到这些值"jdbc:mysql:///db3","root","root" 使用静态代码块
     */
    static {//静态代码块
        try {
            //读取资源文件 获取值  获取的值给getConnection()方法用
            //1.创建Properties集合类
            Properties pro = new Properties();
            //2.加载文件
            //pro.load(new FileReader("src/jdbc.properties"));
            //这里之前报错 解决方法一上面地址写绝对地址
            // 方法二是采用获取src路径下的文件的方式--》ClassLoader类加载器
            ClassLoader classLoader = JdbcUtils.class.getClassLoader(); //classloader类加载器
            URL res = classLoader.getResource("jdbc.properties"); //返回的Url是一个统一资源定位符 可以定位一个文件的绝对路径
            String path = res.getPath(); //使用getPath();方法获取到绝对路径  可以sout看一下路径 得到的就是绝对路径
            pro.load(new FileReader(path));
            //3.获取属性赋值
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            //4.注册驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //获取连接的方法
    public static Connection getConnection() throws SQLException {
        //成员方法 返回值是一个Connection类型的数据
        //获取连接的方法  返回的是连接对象
        // 工具类有一个特点所有的方法都是静态的方法方便来调用 所以这里做一个静态方法加static

        return DriverManager.getConnection(url,user,password);

    }


    //释放资源的方法

    /**
     * 定义释放资源的方法
     * 使用增删改要释放 connection和statement 对象
     * 使用查询时候还要释放一个 ResultSet对象
     * 所以这里写两个动作 使用重载的机制
     */
    public static void close(Statement stmt, Connection conn) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 重载close方法
     */
    public static void close(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值