JDBC技术(二)

由于我们频繁的使用注册驱动,释放资源的方法,所以我们可以将上述方法抽取出来,形成 一个JDBC 工具类,这样我们就很方便的进行获取连接,释放资源的方法:

package com.jdbc.Util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtil {
    private static String url = "jdbc:mysql://localhost:3306/day20";
    private static String user = "root";
    private static String password = "root";
    static{
        //随着类的加载而夹在
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConn(){
        //注册驱动
        try {
            Connection conn = DriverManager.getConnection(url, user, password);
            return conn;        
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
    //释放资源
    public static void close(Connection conn,Statement stmt,ResultSet rs){
        if (conn!=null) {
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (stmt!=null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (rs!=null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

3.执行DQL语句

package com.jdbc.b.statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.jdbc.Util.JDBCUtil;
public class Demo3 {
    public static void main(String[] args) {
        //定义一个连接对象和一个语句执行者
        Connection conn  =null;
        Statement stmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtil.getConn();
            //定义sql
            String sql = "SELECT * FROM student;";
            //获取语句执行者对象
            stmt = conn.createStatement();
            //执行DQL查询语句
            //ResultSet executeQuery(String sql)
            //throws SQLException执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。
            rs = stmt.executeQuery(sql);
            //ResultSet是一个结果集
            /*//判断有没有下一行数据
            if (rs.next()) {
                //说明有下一行数数据
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }
            if (rs.next()) {
                //说明有下一行数数据
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }
            if (rs.next()) {
                //说明有下一行数数据
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }
            if (rs.next()) {
                //说明有下一行数数据
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }
            if (rs.next()) {
                //说明有下一行数数据
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }*/
            //使用while循环改进上面的代码,获取字段的数据(字段类型+列号)
/*          while (rs.next()) {
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }*/
            //使用字段名称获取字段的每一个数据
            while (rs.next()) {
                //当我们使用字段名称去获取字段数据的时候,字段名称是不区分大小写
                System.out.println(rs.getInt("ID")+"--"+rs.getString("NAME")+"--"+rs.getInt("AGE"));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, rs);
        }
    }
}

注意:在执行DQL的时候,会返回一个结果集合,我们要将集合中的数据拿出来,这样我们不知道下一个数据还有没有,所以要提前进行判断,而且还必须用相应的格式来将返回的值带出来。
ResultSet的使用:
在这里插入图片描述
4.PreparedStatement()接口,用于执行预编译的sql语句(是Statement的子接口)
预编译命令:将sql语句中的参数设置为动态参数,在之的查询过程的时候,可以给参数重新设置值,是程序变得更加灵活。

package com.jdbc.c_preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.jdbc.Util.JDBCUtil;
public class Demo {
    public static void main(String[] args) {
        //testInsert();
        //testUpdate();
        //testDelete();
        testSelect();
    }
    private static void testSelect() {
        Connection conn  =null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            //获取连接
            conn  = JDBCUtil.getConn();
            //定义预编译sql
            String sql = "SELECT * FROM student WHERE id=?;";
            //获取预编译sql对象
            stmt = conn.prepareStatement(sql);
            //给问好赋值
            stmt.setInt(1, 3);
            //发送参数并执行sql语句
            //ResultSet executeQuery()throws SQLException在此 
            //PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。
            rs = stmt.executeQuery();
            //遍历结果集
            while (rs.next()) {
                System.out.println(rs.getInt("id")+"--"+rs.getString("name")+"--"+rs.getInt("age"));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, rs);
        }
    }
    private static void testDelete() {
        Connection conn  =null;
        PreparedStatement stmt = null;
        try{
            conn = JDBCUtil.getConn();
            //写一个参数化的sql
            String sql = "DELETE FROM student WHERE id=?;";
            //获取预编译的sql对象
            stmt = conn.prepareStatement(sql);
            //给?设置参数
            stmt.setInt(1, 2);
            //发送参数并执行sql
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, null);
        }
    }
    private static void testUpdate() {
        Connection conn  =null;
        PreparedStatement stmt = null;
        try{
            conn = JDBCUtil.getConn();
            String sql = "UPDATE student SET NAME=? WHERE id=?;";
            //执行预编译sql
            stmt = conn.prepareStatement(sql);
            //给?赋值
            stmt.setString(1, "张学友");
            stmt.setInt(2, 5);
            //发送参数到数据库服务器,并执行sql,将执行结果返回
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, null);
        }
    }
    private static void testInsert() {
        //定义连接对象和预编译sql对象
        Connection conn  = null;
        PreparedStatement stmt = null;
        try{
            //获取连接
            conn = JDBCUtil.getConn();
            //PreparedStatement prepareStatement(String sql)
            //throws SQLException创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。
            String sql = "INSERT INTO student VALUES(?,?,?);";//参数化的sql,动态sql
            stmt = conn.prepareStatement(sql);//需要一个预编译的sequel语句,将sq发送到数据库端,检查sql语法及用户权限等信息
            //给之前参数化的sql语句设置参数
            //两个参数:1:是给第几个?设置数据    2:给?设置的数据
            stmt.setInt(1, 5);
            stmt.setString(2, "黎明");
            stmt.setInt(3, 60);
            //int executeUpdate()throws SQLException
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //释放资源
            JDBCUtil.close(conn, stmt, null);
        }
    }
}

注意:在我们给程序分配一定的权限的时候,我们必须使用预编译 命令,因为如果直接使用Statement(),将用户的信息完全暴露出来,这样程序很不安全,所以我们应该使用预编译命令,将用户的信息传递进去,避免这种情况。
5.使用预编译 命令处理用户的的登录问题

package com.jdbc.c_preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import com.jdbc.Util.JDBCUtil;
public class Login {
    //SELECT * FROM USER WHERE userName='james' OR 1=1 -- ' AND PASSWORD='123456';
    //sql注入行为
    private static String user = "james' OR 1=1 -- ";
    private static String password = "123456";
    public static void main(String[] args) {
        //testStatement();
        testPreparedStatement();
    }
    private static void testPreparedStatement() {
        Connection conn  =null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            conn  =JDBCUtil.getConn();
            String sql = "SELECT * FROM USER WHERE userName=? AND PASSWORD=?;";
            stmt = conn.prepareStatement(sql);
            //给问号设置参数
            stmt.setString(1, user);
            stmt.setString(2, password);
            //发送参数并执行sql
            rs = stmt.executeQuery();
            if (rs.next()) {
                System.out.println("登陆成功");
            }else {
                System.out.println("登录失败");
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, rs);
        }
    }
    private static void testStatement() {
        Connection conn  =null;
        Statement stmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtil.getConn();
            stmt = conn.createStatement();
            String sql  ="SELECT * FROM USER WHERE userName='"+user+"' AND PASSWORD='"+password+"';";
            rs = stmt.executeQuery(sql);
            if (rs.next()) {
                System.out.println("登陆成功");
            }else {
                System.out.println("登录失败");
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, rs);
        }
    }
}

6.CallableStatement()接口,用于执行sql存储过程的接口(是PreparedStatement的子接口)

package com.jdbc.d_callablestatement;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import com.jdbc.Util.JDBCUtil;
public class Demo {
    public static void main(String[] args) {
        //执行带有输入参数存储过程
        //testIn();
        //执行带有输出参数的存储过程
        testOut();
    }
    private static void testOut() {
        Connection conn  =null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtil.getConn();
            String sql = "CALL pro_QueryNameById(?,?);";
            stmt = conn.prepareCall(sql);
            //给问号赋值
            stmt.setInt(1, 2);
            //如果存储过程带有输出参数的时候,首先需要注册,输出参数的类型
            //void registerOutParameter(int parameterIndex,int sqlType)
            stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
            //发送参数并执行sql
            stmt.executeQuery();
            //从stmt中取出输出参数的结果
            System.out.println(stmt.getString(2));
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //释放资源
            JDBCUtil.close(conn, stmt, rs);
        }
    }
    private static void testIn() {
        Connection conn  =null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtil.getConn();
            String sql = "CALL pro_QueryById(?);";
            stmt = conn.prepareCall(sql);
            //给问号设置值
            stmt.setInt(1, 2);
            //发送参数并执行sql,只能调用excuteQuery()
            rs = stmt.executeQuery();
            if (rs.next()) {
                System.out.println(rs.getInt(1)+"--"+rs.getString(2));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //释放资源
            JDBCUtil.close(conn, stmt, rs);
        }
    }
}

注意:在使用存储过程的接口的时候,如果存储过程会有返回值,那么我们应该显注册一个返回值类型,然后在去接受这个返回值。
//如果存储过程带有输出参数的时候,首先需要注册,输出参数的类型:
//void registerOutParameter(int parameterIndex,int sqlType)
stmt.registerOutParameter(2, java.sql.Types.VARCHAR);

发布了62 篇原创文章 · 获赞 55 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Veer_c/article/details/103879890
今日推荐