JDBC操作MySQL数据库

一、可用于操作数据库的三个接口

在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:

①Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
②PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。

③CallableStatement:用于执行 SQL 存储过程

二、使用Statement操作数据表

  • 通过调用 Connection 对象的 createStatement() 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返回执行结果。

  • Statement 接口中定义了下列方法用于执行 SQL 语句:

int excuteUpdate(String sql):执行更新操作INSERT、UPDATE、DELETE
ResultSet executeQuery(String sql):执行查询操作SELECT
复制代码
  • 但是使用Statement操作数据表存在弊端:

问题一:存在拼串操作,繁琐

问题二:存在SQL注入问题

  • SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令如SELECT name, password FROM user WHERE name='a' OR 1 = ' AND password = ' OR '1' ='1' 从而利用系统的 SQL 引擎完成恶意行为的做法。对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement(从Statement扩展而来) 取代 Statement 就可以了。

代码展示

statement测试类:简单模拟登陆操作

public class StatementTest {
    // 使用Statement的弊端:需要拼写sql语句,并且存在SQL注入的问题
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        System.out.print("用户名:");
        String username = scanner.nextLine();
        System.out.print("密码:");
        String password = scanner.nextLine();

        String sql = "select name,password from user where name = '"+username+
                "' AND password ='"+password+"'";
//        System.out.println(username);
//        "select * from sc where sno = '"+sno+"'"
        User user = get(sql);
        if(user!=null){
            System.out.println("登陆成功");
        }else{
            System.out.println("用户名不存在或密码错误");
        }

    }


    // 使用Statement实现对数据表的查询操作
    public static User  get(String sql){
        User t = null;
        InputStream is =null;
        Connection conn =null;
        Statement statement =null;
        ResultSet rs =null;
        try {
            is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
            Properties properties = new Properties();
            properties.load(is);

            String url = properties.getProperty("url");
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");
            String driverClass = properties.getProperty("driverClass");

            //1、注册驱动
            Class.forName(driverClass);

            //2、获取连接
            conn = DriverManager.getConnection(url, user, password);
//        System.out.println(conn);

            //3、获取statement对象
            statement = conn.createStatement();

            //4、执行语句
            rs = statement.executeQuery(sql);
//        System.out.println(rs);

            //5、处理结果集
            if (rs.next()) {
                t = new User();
//            t.setname(rs.getString("name"));
//            t.setPassword(rs.getString("password"));
                t.setname(rs.getString(1));
                t.setPassword(rs.getString(2));
                System.out.println(t);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(rs!=null)
                    rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if(statement!=null)
                    statement.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if(conn !=null)
                    conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if(is !=null)
                    is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  t;
    }
}
复制代码

User类:用于保存查询得到的信息

public class User {

    private String name;
    private String password;

    public User() {
    }

    public User(String name, String password) {
        super();
        this.name = name;
        this.password = password;
    }

    @Override
    public String toString() {
        return "name [name=" + name + ", password=" + password + "]";
    }

    public String getname() {
        return name;
    }

    public void setname(String name) {
        this.name = name;
    }


    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}
复制代码

三、使用PreparedStatement代替statement

图片.png

1、PreparedStatement介绍

  • 可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取PreparedStatement 对象
  • PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句
  • PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1开始),第二个是设置的 SQL 语句中的参数的值

2、PreparedStatement vs Statement

  • 代码的可读性和可维护性。

  • PreparedStatement 能最大可能提高性能

    1. DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。

    2. 在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存。这样每执行一次都要对传入的语句编译一次。

    3. (语法检查,语义检查,翻译成二进制命令,缓存)

  • PreparedStatement 可以防止 SQL 注入

3、Java与SQL对应数据类型转换表

图片.png

4、使用PreparedStatement实现增删改查操作

JDBCUtiles类:里面存放连接数据库通用的代码段

public class JDBCUtils {
    /**
     * 获取连接
     */
    public static Connection getConnection() throws Exception {
        //1.加载配置文件
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
        Properties pros = new Properties();
        pros.load(is);


        //2.读取配置信息
        String user = pros.getProperty("user");
        String password = pros.getProperty("password");
        String url = pros.getProperty("url");
        String driverClass = pros.getProperty("driverClass");


        //3.加载驱动
        Class.forName(driverClass);


        //4.获取连接
        Connection conn = DriverManager.getConnection(url,user,password);
        return conn;
    }

    /**
     * 关闭资源
     */

    public static void closeResource(Connection conn, Statement statement){
        try {
            if (statement != null)
                statement.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        try {
            if (conn != null)
                conn.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}
复制代码

PreparedStatementTest类:实现增删改操作

public class PreparedStatementTest {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.print("请输入用户名:");
        String username = scan.nextLine();
        System.out.print("请输入密码:");
        String password = scan.nextLine();
        Insert(username,password);
    }

    public static void Insert(String username,String userpassword){
        Connection connection = null;
        PreparedStatement ps = null;
        try {

            connection =JDBCUtils.getConnection();

            String sql = "insert into user values(?,?)";
            ps = connection.prepareStatement(sql);

            ps.setString(1, username);
            ps.setString(2, userpassword);

            ps.execute();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeResource(connection,ps);
        }
    }
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享