zoukankan      html  css  js  c++  java
  • java基础(十三):JDBC

    目录

    • JDBC概述
    • 使用JDBC完成添加/更新/删除操作
    • 使用JDBC完成查询操作
    • JDBC语法总结
    • 使用PreparedSatement完善JDBC操作
    • 手动启动事务管理
    • 使用JDBC完成多表查询操作
    • 采用分层实现JDBC操作

    JDBC概述

    JDBC(Java Data Base Connectivity,Java数据库连接)

    是一种用于执行SQL语句的Java API,为多种关系数据库提供统一访问

    它由一组用Java语言编写的类和接口组成

    程序员只需用JDBC API写一个程序,就可以访问所有数据库。

    JDBC API

      提供者:Sun公司

      内容:供程序员调用的接口与类,集成在java.sql和javax.sql包中,如

            DriverManager类  作用:管理各种不同的JDBC驱动

            Connection接口

            Statement接口

            ResultSet接口

    JDBC 驱动

      提供者:数据库厂商

      作用:负责连接各种不同的数据库

    JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。

    三方关系

      SUN公司是规范制定者,制定了规范JDBC(连接数据库规范)

      数据库厂商微软、甲骨文等分别提供实现JDBC接口的驱动jar包

      程序员学习JDBC规范来应用这些jar包里的类。

    简单地说,JDBC 可做三件事:

      与数据库建立连接、发送 操作数据库的语句并处理结果。

    • DriverManager :依据数据库的不同,管理JDBC驱动
    • Connection :负责连接数据库并担任传送数据的任务
    • Statement :由 Connection 产生、负责发送执行SQL语句
    • ResultSet:负责保存Statement执行后所产生的查询结果

    JDBC语法总结

    • 1:加载一个Driver驱动
    • 2:创建数据库连接(Connection)
    • 3 :创建SQL命令发送器Statement
    • 4:通过Statement发送SQL命令并得到结果
    • 5:处理SQL结果(select语句)
    • 6:关闭数据库资源
      • ResultSet
      • Statement
      • Connection。

    1.加载驱动

    加载JDBC驱动是通过调用方法java.lang.Class.forName(),

    下面列出常用的几种数据库驱动程序加载语句的形式 :

    • Class.forName(“oracle.JDBC.driver.OracleDriver”);//使用Oracle的JDBC驱动程序
    • Class.forName(“com.microsoft.JDBC.sqlserver.SQLServerDriver”);//使用SQL Server的JDBC驱动程序
    • Class.forName(“com.ibm.db2.JDBC.app.DB2Driver”);//使用DB2的JDBC驱动程序
    • Class.forName("com.mysql.JDBC.Driver");//使用MySql的JDBC驱动程序

    2.创建数据库连接

    与数据库建立连接的方法是调用

    DriverManager.getConnection(String url, String user, String password )方法

    • Connection conn=null;
    • String url="jdbc:oracle:thin:@localhost:1521:orcl";
    • String user=“scott";
    • String password=“tiger";
    • conn = DriverManager.getConnection(url, user, password);

    3.创建Statement并发送命令

    • Statement对象用于将 SQL 语句发送到数据库中,或者理解为执行sql语句
    • 有三种 Statement对象:
      • Statement:用于执行不带参数的简单SQL语句;
      • PreparedStatement(从 Statement 继承):用于执行带参数或不带参数的预编译SQL语句;
      • CallableStatement(从PreparedStatement 继承):用于执行数据库存储过程的调用。

    4.处理ResultSet结果

    • ResultSet对象是executeQuery()方法的返回值,它被称为结果集,它代表符合SQL语句条件的所有行,并且它通过一套getXXX方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问
    • ResultSet里的数据一行一行排列,每行有多个字段,且有一个记录指针,指针所指的数据行叫做当前数据行,我们只能来操作当前的数据行。我们如果想要取得某一条记录,就要使用ResultSet的next()方法 ,如果我们想要得到ResultSet里的所有记录,就应该使用while循环
    • ResultSet对象自动维护指向当前数据行的游标每调用一次next()方法,游标向下移动一行
    • 初始状态下记录指针指向第一条记录的前面,通过next()方法指向第一条记录。循环完毕后指向最后一条记录的后面。

    5.关闭数据库资源

      (1)作为一种好的编程风格,应在不需要Statement对象和Connection对象时显式地关闭它们

          关闭Statement对象和Connection对象的语法形式为:

            public void close() throws SQLException

      (2)用户不必关闭ResultSet。当它的 Statement 关闭、重新执行或用于从多结果序列中获取下一个结果时,该ResultSet将被自动关闭。

    注意:要按先ResultSet结果集,后Statement,最后Connection的顺序关闭资源,因为Statement和ResultSet是需要连接是才可以使用的,所以在使用结束之后有可能其他的Statement还需要连接,所以不能先关闭Connection。

    • PreparedStatement 接口继承 Statement接口
    • PreparedStatement比普通的Statement对象使用起来更加灵活,更有效率

     代码示例

    demo1

    package cn.sxt.jdbc.demo1;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Scanner;
    
    public class Tester {
    
        /**
         * 引入驱动Jar
         *         JRE System Library——>鼠标右键——>build Path——>Config build Path ——〉Libraries——〉add external jars
         * 访问数据库的步骤
         *         1、加载驱动
         *         2、创建数据库连接
         *         3、创建语句发送器Statement
         *         4、Statement对象发送Sql语句(发送给服务器)
         *         5、处理服务器的响应结果
         *         6、关闭资源
         * 
         * connection
         *         一个数据库连接对象
         * Statement
         *         概述
         *             将Sql语句发送给数据库服器(也可以理解为Sql语句的执行者)
         *         对象    
         *             Statement            :可以执行不带参数的Sql语句
         *             PreparedStatement    :执行执行带参数和不带参数的Sql语句
         *             CallableStatement    :用于执行存储过程的Satatement
         * 
         *             PreparedStatement比Statement更加方便灵活。所以一般使用PreparedStatement
         *         方法
         *             executeUpdate()        :执行非查询语句(insert、delete、update)
         *             executeQuery()        :执行查询语句(select)
         * @param args
         * @throws ClassNotFoundException 
         * @throws SQLException 
         */
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
            Scanner input = new Scanner(System.in);
            
            //6、结果处理
            /*
            if(delete(50) >0)
                System.out.println("数据删除成功");
            else
                System.out.println("数据删除失败");
                
            int count = add(70, "tdt","nj");
            System.out.println(count);
            
            getAll();
            */
            
            System.out.print("请输入部门ID:");
            int id = input.nextInt();
            
            System.out.println("请输入部门名称:");
            String name = input.next();
            
            System.out.println("请输入部门所在地:");
            String loc = input.next();
            
            System.out.println(add(id, name, loc));
            
            
        }
        
        static String url = "jdbc:oracle:thin:@localhost:1521:oracle";
        static String user = "scott";
        static String password = "tiger";
        
        /**
         * 查询所有数据
         */
        static void getAll(){
            
            try {
                //1、加载驱动
                Class.forName("oracle.jdbc.driver.OracleDriver");
                
                //2、获取连接对象
                Connection conn = DriverManager.getConnection(url,user, password);
                
                //3、创建statement对象
                Statement statement = conn.createStatement();
                            
                //4、执行语句
                String sql = "select * from dept";
                ResultSet rs = statement.executeQuery(sql);
                //5、处理查询结果
                while(rs.next()){
                    System.out.println(rs.getInt("DeptNo") + "	" + rs.getString("DName") + "	" +rs.getString("Loc"));
                }
                //6、关闭资源
                rs.close();
                statement.close();
                conn.close();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
        /**
         * 将部门信息添加到dept表中
         * @param id
         * @param name
         * @param loc
         * @return
         */
        static int add(int id, String name, String loc){    
            int count = 0;
            try {
                //1、加载驱动
                Class.forName("oracle.jdbc.driver.OracleDriver");
                
                //2、获取连接对象
                Connection conn = DriverManager.getConnection(url, user, password);
                
                //3、创建statement对象
                Statement statement = conn.createStatement();
                
                //4、执行Sql语句
                //拼接Sql语句
                String sql = "insert into dept values(" + id +",'" +name+ "','"+loc+"')";
                System.out.println(sql);
                count =  statement.executeUpdate(sql);
                
                //5、关闭对象
                statement.close();
                conn.close();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            return count;
        }
        
        /**
         * 使用Statement执行非查询语句
         * @param id
         * @return
         */
        static int delete2(int id){
            int count = 0;
            
            try {
                //1、加载驱动
                Class.forName("oracle.jdbc.driver.OracleDriver");
                
                //2、获取连接对象
                Connection conn =  DriverManager.getConnection(url, user, password);
                
                //3、创建Statement对象
                Statement statement = conn.createStatement();
                
                //4、执行命令
                String sql = "delete from dept where deptNo=" + id;
                count = statement.executeUpdate(sql);
                
                //5、关闭资源
                statement.close();
                conn.close();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return count;
        }
        
        /**
         * 按照ID删除部门信息
         *         使用preparedStatement对象进行实现
         * @param id
         */
        static int delete(int id){
            int count = 0;
            
            try {
                // 1、加载JDBC驱动
                Class.forName("oracle.jdbc.driver.OracleDriver");
                
                // 2、创建数据库连接
                // jdbc:oracle:thin :固定的,前缀,表示当前连接数据库的类型信息
                // localhost :本地服务器的地址
                // 1521 :数据库服务器的端口
                // oracle :数据库实例的名称
                //String url = "jdbc:oracle:thin:@localhost:1521:oracle";
                //String user = "scott";
                //String password = "tiger";
                // DriverManager :驱动管理器
                // getConnection() :根据驱动信息可以获取到一个连接对象——Connection
                Connection conn = DriverManager.getConnection(url, user, password);
    
                // 3、获取Statement对象
                String sql = "delete from dept where deptNo =" + id;
                PreparedStatement statement = conn.prepareStatement(sql);
    
                // 4、发送Sql语句(执行Sql语句)
                // executeUpdate() :将Sql语句发送给数据库服器(返回值:执行该语句后受影响的行数)
                count = statement.executeUpdate();
                
                // 5、关闭资源
                statement.close();
                conn.close();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            return count;
        }
    
    }

    demo2

    package cn.sxt.jdbc.demo2;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.Scanner;
    
    /**
     * "insert into dept values(" + id +",'" +name+ "','"+loc+"')"
     * Sql语句的生成方式是拼接Sql语句
     * 拼接Sql语句容易造成Sql注入攻击。注入攻击可能造成系统崩溃
     * 
     * 命令行参数
     *         意义
     *             1、有效的避免注入攻击,更加安全可靠
     * 
     *         实现
     *             PreparedStatement对象
     *                 方法
     *                     setXxxx(参数索引,值)
     *                 说明
     *                     setXxxx        :设置指定类型的参数给PreparedStatement对象
     *                     参数索引        :当前设置的参数的索引位置,从1开始
     *                     值            :需要设置的参数之
     * @author Terry
     *
     */
    public class Tester {
        static String url = "jdbc:oracle:thin:@localhost:1521:oracle";
        static String user = "scott";
        static String password = "tiger";
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            
            System.out.print("请输入部门ID:");
            int id = input.nextInt();
            
            System.out.print("请输入部门名称:");
            String name = input.next();
            
            System.out.print("请输入部门所在地:");
            String loc = input.next();
            
            int c = add(id, name, loc);
            System.out.println(c);
        }
        
        /**
         * 使用参数化的方式执行非查询语句
         * @param id
         * @param name
         * @param addr
         * @return
         */
        static int add(int id, String name ,String addr){    
            int count = 0;
            try {
                //1、加载驱动
                //通过反射加载对应的类
                Class.forName("oracle.jdbc.driver.OracleDriver");
                
                //2、获取连接对象            
                Connection con = DriverManager.getConnection(url, user, password);
                
                //3、创建Statement对象
                //?表示语句执行过程中所需要的参数
                String sql = "insert into dept values(?,?,?)";
                //带有参数的语句需要通过PreparedStatement对象才能执行
                PreparedStatement statement= con.prepareStatement(sql);
                
                //将参数传递给Statement对象
                //将int类型参数——id传递给Statement对象
                statement.setInt(1,id);
                statement.setString(2, name);
                statement.setString(3, addr);
                
                //4、执行Sql语句
                count = statement.executeUpdate();
                
                //5、关闭资源
                statement.close();
                con.close();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return count;
        }
    
    }

    demo3

    工具类:可以实现执行查询语句和非查询语句

    package cn.sxt.util;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    /**
     * 工具类
     *         可以实现执行查询语句和非查询语句
     * @author Terry
     *
     */
    public class DBUtil {
        //数据库连接参数
        private static String url = "jdbc:oracle:thin:@localhost:1521:oracle";
        private static String user = "scott";
        private static String password = "tiger";
        
        //定义JDBC对象
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        
        /**
         * 加载驱动并初始化Connection对象
         */
        private void init(){        
            try {
                //加载驱动
                Class.forName("oracle.jdbc.driver.OracleDriver");
                
                //获取连接对象
                con = DriverManager.getConnection(url, user, password);
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
        /**
         * 执行非查询语句
         * eg:insert、delete及update
         * @param sql
         * @return        :受影响行数
         */
        public int executeUpdate(String sql,Object...parameters){
            //初始化Connection对象
            init();
                    
            try {
                //获取Prepared对象
                ps = con.prepareStatement(sql);
                
                //为PreparedStatement初始化参数
                for(int i = 1;i<=parameters.length;i++){
                    //i-1    :因为数组的下标是从0开始的。所以这里需要使用i-1
                    ps.setObject(i, parameters[i-1]);
                }
                
                //执行Sql语句
                return ps.executeUpdate();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            finally{
                close();
            }
            
            return -1;
        }
        
        /**
         * 执行查询语句
         * 注意:ResultSet(连接式的数据访问对象)使用过程中JDBC不能关闭
         * @param sql
         * @return        :查询结果集
         */
        public ResultSet executeQuery(String sql,Object...parameters){
            //初始化Connection对象
            init();
                    
            try {
                //获取PreparedStatement对象
                ps = con.prepareStatement(sql);
                
                //为PreparedStatement初始化参数
                for(int i = 1;i<=parameters.length;i++){
                    //i-1    :因为数组的下标是从0开始的。所以这里需要使用i-1
                    ps.setObject(i, parameters[i-1]);
                }
                
                //执行语句
                return ps.executeQuery();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }        
            return null;
        }
        
        /**
         * 关闭所有的JDBC资源对象
         */
        public void close() {
            try {
                if (rs != null)
                    rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            try {
                if (ps != null)
                    ps.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            try {
                if (con != null)
                    con.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }    
        }
    }

    调用示例

    package cn.sxt.jdbc.demo3;
    
    import cn.sxt.util.*;
    
    public class Tester {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            DBUtil util = new DBUtil();
            //util.executeUpdate("delete from Dept");
            util.executeUpdate("insert into dept values(?,?,?)", 91,"i'm2","tjj");
        }
    
    }
  • 相关阅读:
    HBase Coprocessor 剖析与编程实践
    图数据库实践系列 (一)Neo4J简介与安装
    BootStrap入门教程 (三)
    图数据库实践系列 (三)Neo4j Spatial的REST集成
    BootStrap入门教程 (二)
    R与GIS实践系列Shapefile导入与地图显示
    空间分析读书笔记
    BootStrap入门教程 (四)
    Java并发之线程池的使用浅析
    RSA详解
  • 原文地址:https://www.cnblogs.com/Vincent-yuan/p/13128897.html
Copyright © 2011-2022 走看看