JDBC: PreparedStatement和Statement的区别

PreparedStatement注意:
(1)sql语句要给占位符?传值(第1个问号下标是1,第2个问号下标是2,JDBC所有下标从1开始。)
(2)PreparedStatement与Statement的第四步执行SQL语句不一样。

1.JDBC设计用户登录

使用PreparedStatement预编译接口:解决SQL注入问题

package com.jdbc;
import java.sql.*;
import java.util.*;
/**
* 解决SQL注入问题
*    --只要用户提供的信息不参与SQL语句的编译过程,问题就解决了。
*    --即使用户提供的信息中含有SQL语句的关键字,但是没有参与编译,不起作用。
*    --想要用户信息不参与SQL语句的编译,那么必须使用java.sql.PreparedStatement
*    --PreparedStatement接口继承了java.sql.Statement
*    --PreparedStatement是属于预编译的数据库操作对象。
*    --PreparedStatement的原理:预先对SQL语句的框架进行编译,然后再给SQL语句传“值"
* */
public class JDBCTest06{
    public static void main(String[] args) {
        //初始化一个界面
        Map<String,String> userLoginInfo=initUI();
        //验证用户名和密码
        boolean loginSuccess=login(userLoginInfo);
        //最后输出结果
        System.out.println(loginSuccess? "登陆成功":"登录失败");
    }

    /*
    * 用户登录
    * @param userLoginInfo 用户登录信息
    * @return false表示失败 , true表示成功
    * */
    private static boolean login(Map<String, String> userLoginInfo) {
        //打标记的意识
        boolean loginSuccess=false;
        //单独定义变量
        String loginName=userLoginInfo.get("loginName");
        String loginPwd=userLoginInfo.get("loginPwd");

        //JDBC代码
        Connection conn = null;
        PreparedStatement ps = null; //这里使用PreparedStatement(预编译的数据库操作对象)
        ResultSet rs= null;

        try{
            //1.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.获取连接对象
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=GMT%2B8", "root", "jh7851192");
            //3.获取预编译数据库操作对象
            //SQL语句的框子。其中一个?表示一个占位符,一个?号将来接收一个"值"。注意:占位符不能使用单引号括起来
            String sql="select * from t_user where loginName= ? and loginPwd= ? ";
            //程序执行到此处,会发送sql语句框子给DBMS,然后DBMS进行sql语句的预先编译。
            ps = conn.prepareStatement(sql);
            //给占位符?传值(第1个问号下标是1,第2个问号下标是2,JDBC所有下标从1开始。)
            ps.setString(1,loginName);
            ps.setString(2,loginPwd);
            //4.执行SQL语句
            rs=ps.executeQuery();
            //5.处理结果集
            if(rs.next()){
                //登录成功
                loginSuccess=true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
                //6.释放资源
                if (rs != null) {
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if (ps != null) {
                    try {
                        ps.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
        }
        return loginSuccess;
    }

    /*
    * 初始化用户界面
    * @return 用户输入的用户名和密码等登录信息
    * */
    private static Map<String, String> initUI() {
        Scanner s= new Scanner(System.in);

        System.out.println("用户名:");
        String loginName=s.nextLine();

        System.out.println("密码:");
        String loginPwd=s.nextLine();

        Map<String,String> userLoginInfo= new HashMap<>();
        userLoginInfo.put("loginName",loginName);
        userLoginInfo.put("loginPwd",loginPwd);
        return userLoginInfo;
    }
}

2.PreparedStatement和Statemen区别

PreparedStatement可以自动加单引号,而Statement不行,这个降升序例子只能用Statement。

package com.jdbc;
import java.util.*;
import java.sql.*;
/**
* PreparedStatement和Statement的区别:
* ---PreparedStatement用的较多,避免SQL注入问题,一次预编译可以执行多次;
* ---Statement每编译一次执行一次;
* ---PreparedStatement可以自动加单引号,而Statement不行,这个降升序例子只能用Statement。
 * */
public class JDBCTest07 {
    public static void main(String[] args) {
        //用户在控制台输入desc就是降序,输入asc就是升序
        Scanner s = new Scanner(System.in);
        System.out.println("输入desc或asc,desc表示降序,asc表示升序");
        System.out.println("请输入:");
        String keyWords=s.nextLine();

        /** PreparedStatement 运行报错
        //执行sql
        Connection conn = null;
        PreparedStatement ps= null;
        ResultSet rs = null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.获取连接
            conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=GMT%2B8","root","jh7851192");
            //3.获取预编译数据库操作对象
            String sql="select ename from emp order by ename ?";
            ps=conn.prepareStatement(sql);
            //给 ?号占位符传值
            ps.setString(1,keyWords);
            //4.执行SQL语句
            rs=ps.executeQuery();
            //5.处理查询结果集
            while(rs.next()){
                System.out.println(rs.getString("ename"));//报错,带了单引号 。use near ''desc''
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(rs !=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(ps !=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn !=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
         */

        //修改如下:Statement
        //执行sql
        Connection conn = null;
        Statement stmt= null;
        ResultSet rs = null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.获取连接
            conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=GMT%2B8","root","jh7851192");
            //3.获取预编译数据库操作对象
            stmt=conn.createStatement();
            //4.执行SQL语句
            String sql="select ename from emp order by ename "+keyWords;
            rs=stmt.executeQuery(sql);
            //5.处理查询结果集
            while(rs.next()){
                System.out.println(rs.getString("ename"));//报错,带了单引号 。use near ''desc''
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            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();
                }
            }
        }
    }
}

结果:
在这里插入图片描述

3.PreparedStatement对数据库进行insert、delete、update操作

package com.jdbc;
/**
* (1)用PreparedStatement对数据库进行insert、delete、update操作。
* (2)增、删、改操作不需要 第五步:处理查询结果集,也就用不到ResultSet接口
* */
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCTest08 {
    public static void main(String[] args) {
        Connection conn =null;
        PreparedStatement ps =null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.获取连接
            conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=GMT%2B8","root","jh7851192");

            //3.获取预编译数据库操作对象
            /**String sql="insert into dept(deptno,dname,loc) values(?,?,?)";
            ps=conn.prepareStatement(sql);
             //给占位符问号?传值, 3个问号代表3个下标: 1,2,3,类型根据数据库决定。
            ps.setInt(1,70);
            ps.setString(2,"财务部");
            ps.setString(3,"北京");*/

            /**String sql="update dept set dname=?,loc=? where deptno=?";
            ps=conn.prepareStatement(sql);
            ps.setString(1,"食堂部");
            ps.setString(2,"合肥");
            ps.setInt(3,112);*/

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

            //4.执行SQL语句
            int count=ps.executeUpdate();
            System.out.println(count==1?"成功":"失败");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //6.释放资源
            if(ps != null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
发布了42 篇原创文章 · 获赞 8 · 访问量 2444

猜你喜欢

转载自blog.csdn.net/JH39456194/article/details/103337753