JDBC技术

来源:互联网 发布:python count函数 编辑:程序博客网 时间:2024/05/23 20:22

一,
在之前我们操作mysql数据库的时候,我们是使用sqlyog客户端连接数据库,然后发送sql语句到服务器端,并执行,现在我们要使用Java程序来连接数据库,并发送sql语句到数据库,操作数据库。
二,使用Java程序连接数据库,这就是用到了JDBC技术(Java Database Connection),JDBC技术是oracle -sun 公司设计的一套专门用于Java程序操作数据库的接口。
我们在使用Java程序了解数据库的时候,一般是Java程序连接数据库的驱动,然后连接数据库的服务器,而Java程序和数据库的驱动都是让Java程序员去做,为了减少工作量,oracle-sun公司设计了一套专门用于Java程序连接数据库的接口,然后让数据库的厂商去设计驱动的实现类。
Java程序连接数据库的示意图如下
这里写图片描述

三,JDBC的条件
使用Java程序连接数据库:数据库主机,端口号,数据库用户名和密码,要连接的数据库,
四,JDBC的一些重要的api
由于我们在之前的一些库文件不够用,我们必须把Jar文件导入,在项目工程下创建一个lib文件,然后将jar文件复制进去,然后在 将改文件,buildpath,设置为相关库文件。
(1)Driver 接口,数据库驱动程序的接口,所有的数据库厂商需要实现此接口
(2)Connection 接口,用于获取数据库的连接

获取连接的三种方式package com.jdbc.a_driver;import java.sql.Connection;import java.sql.Driver;import java.sql.DriverManager;import java.sql.SQLException;import java.util.Properties;public class DriverDemo {    private static String url = "jdbc:mysql://localhost:3306/day20";    //jdbc协议:mysql协议://主机地址:端口号/需要连接的数据库名称    private static String user = "root";    private static String password="root";    public static void main(String[] args) throws Exception {        /**         * java程序连接mysql数据库         * 1.mysql数据库的主机地址         * 2.端口号         * 3.用户名         * 5.密码         * 6.需要连接的数据库         *          * 需求:先使用java程序连接我们的数据库,需要一个连接对象Connection         */        //conn1();        //conn2();        conn3();    }    //我们以后就使用这种方式获取数据库的连接对象    private static void conn3() throws Exception {        //注册驱动,我们发现mysql驱动程序的Driver实现类已经帮我们在静态代码块中注册好了驱动,        //我们在此时只需要将Driver实现类加载到我们的内存中,static代码块就会自动执行,我们的驱动也就自动注册了        //注册驱动        Class.forName("com.mysql.jdbc.Driver");        //获取java连接数据库的对象        Connection conn = DriverManager.getConnection(url, user, password);        //打印这个连接对象        System.out.println(conn);    }    private static void conn2() throws Exception {        //使用驱动管理类,连管理我们的驱动程序,并获取连接        //1.注册驱动        //public static void registerDriver(Driver driver)throws SQLException        Driver driver = new com.mysql.jdbc.Driver();        DriverManager.registerDriver(driver);        //获取连接        //public static Connection getConnection(String url,String user,String password)throws SQLException        Connection conn = DriverManager.getConnection(url, user, password);        //打印这里数据库连接        System.out.println(conn);    }    //直连    private static void conn1() throws SQLException {        //创建一个驱动类对象Driver        Driver driver = new com.mysql.jdbc.Driver();        //获取java连接数据库的连接        //Connection connect(String url, Properties info)throws SQLException        //创建一个properties集合        Properties prop = new Properties();        prop.setProperty("user", user);        prop.setProperty("password", password);        Connection conn = driver.connect(url, prop);        //打印这个连接对象,如果连接对象不为空,就说明我们已经成功获取到了连接对象        System.out.println(conn);    }}

三种获取连接的方式:
1.利用properties将数据库的用户名和密码传进去,获取连接
2.先注册驱动,利用驱动的管理类来获取连接方式,
3.我们知道注册驱动这个过程是静态的,然后可以利用字节码文件对象的方法,将这个类直接加载到我们的类存中,然后再次利用驱动管理类,获取连接,在以后我们就利用这个方法 ,更快,更方便。
(3)Statement 接口,用于执行静态的sql语句
Statement createStatement()创建一个静态的sql语句对象
PreparedStatement PreparedStatement(String sql) 创建预编译语句执行对象
CallableStatement prepareCall(String sql) 创建存储过程的sql语句执行对象,
int executeUpdata (String sql)用于执行更新的语句操作,可以执行
DDL语句(数据定义语言)(create,drop,alter,Declare);
DML语句(数据操控语句)(delete,updata,insert);
ResultSet executeQuery (String sql) 执行DQLY语句(数据)(select)
1.执行DDL语句

package com.jdbc.b.statement;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;public class Demo {    private static String url = "jdbc:mysql://localhost:3306/day20";    private static String user = "root";    private static String password = "root";    public static void main(String[] args){        Connection conn = null;        Statement stmt = null;        try {            //注册驱动            Class.forName("com.mysql.jdbc.Driver");            //通过驱动管理类获取数据库连接            conn = DriverManager.getConnection(url, user, password);            //创建语句执行者            stmt = conn.createStatement();            //int executeUpdate(String sql)            //throws SQLException执行给定 SQL 语句,            //该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。            String sql = "CREATE TABLE student("+                            "id INT,"+                            "NAME VARCHAR(20),"+                            "age INT"+                            ");";            //使用语句执行者执行创建的sql语句            int count = stmt.executeUpdate(sql);            //打印一下影响的结果            System.out.println(count);        } catch (Exception e) {            e.printStackTrace();            throw new RuntimeException();        }finally{            //释放资源            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();                }            }        }       }}

2.执行DQL语句

package com.jdbc.b.statement;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;import com.jdbc.Util.JDBCUtil;public class Demo2 {    private static String url = "jdbc:mysql://localhost:3306/day20";    private static String user = "root";    private static String password = "root";    public static void main(String[] args) {        testInsert();//给数据库添加一条记录        testUpdate();//修改数据库中的一条数据        testDelete();    }    private static void testDelete() {        //需求:将刘德华改为岳云鹏        Connection conn = null;        Statement stmt = null;        try{            //2.获取连接对象            conn  =JDBCUtil.getConn();            //3.准备sql            String sql = "DELETE FROM student WHERE id=1;";            //4.获取语句执行者            stmt = conn.createStatement();            //5.发送兵长执行sql            int count = stmt.executeUpdate(sql);            //打印影响的行数            System.out.println(count);        }catch(Exception e){            e.printStackTrace();            throw new RuntimeException();        }finally{            JDBCUtil.close(conn, stmt, null);        }    }    private static void testUpdate() {        //需求:将刘德华改为岳云鹏        Connection conn = null;        Statement stmt = null;        try{            //1.注册驱动            Class.forName("com.mysql.jdbc.Driver");            //2.获取连接对象            conn  =DriverManager.getConnection(url, user, password);            //3.准备sql            String sql = "UPDATE student SET NAME='岳云鹏' WHERE id=1;";            //4.获取语句执行者            stmt = conn.createStatement();            //5.发送兵长执行sql            int count = stmt.executeUpdate(sql);            //打印影响的行数            System.out.println(count);        }catch(Exception e){            e.printStackTrace();            throw new RuntimeException();        }finally{            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();                }            }        }    }    private static void testInsert() {        //专门测试添加功能        Connection conn = null;        Statement stmt = null;        try{            //注册驱动            Class.forName("com.mysql.jdbc.Driver");            //获取连接            conn = DriverManager.getConnection(url, user, password);            //定义sql            String sql = "INSERT INTO student VALUES(1,'刘德华',50);";            //获取语句执行者            stmt = conn.createStatement();            //使用语句执行者发送并执行sql语句,并返回影响的行数            int count = stmt.executeUpdate(sql);            System.out.println(count);        }catch(Exception e){            e.printStackTrace();            throw new RuntimeException();        }finally{            //释放资源            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();                }            }        }    }}

三,由于我们频繁的使用注册驱动,释放资源的方法,所以我们可以将上述方法抽取出来,形成 一个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);
原创粉丝点击