zoukankan      html  css  js  c++  java
  • Java_JDBC

    JDBC-ODBC桥连接形式:利用微软提供的ODBC进行数据库链接,然后利用JDBC访问ODBC的函数库,实现数据操作

    流程:程序>JDBC>ODBC>数据库;这样操作性能差,但支持度最高,不需要配置任何第三方驱动程序

    JDBC连接形式:利用不同数据库的生产商提供的JDBC驱动程序进行数据库操作

    流程:程序>JDBC>数据库;性能很好;

    JDBC网络连接形式:

    流程:程序>JDBC连接协议>数据库,实际使用中是最多的;

    JDBC协议连接:使用特定数据库生产厂商提供的协议标准进行数据库的操作,难度较高;

    使用Java.sql包开发,此包由以下类和接口组成:

    类:DriverManager类

    接口:Connection、Statement、PreparedStatement、ResultSet;

    JDBC一定是按照固定的代码操作执行的;

    第一步:加载数据库驱动程序

    第二部:依靠DriverManager类连接数据库

    第三部:进行数据库的CRUD操作(Statement、PreparedStatement、ResultSet)

    第四步:关闭数据库链接

    按照指定步骤连接数据库:

    1. 配置数据库驱动程序

    需要打开Oracle两个服务:监听、实力服务;(OracleOraDb11g_home1TNSListener、OracleServiceORCL)

    随后需要配置数据库驱动程序,驱动程序路径:找到数据库安装文件目录...product11.2.0dbhome_1jdbclibojdbc6.jar

    若没有开发工具而使用记事本开发,需要配置CLASSPATH中路径。

    使用开发工具,需要在【Java Build Path】中配置扩展的程序包,复制路径,Eclipse中右键项目》属性》Java Build Path》Libraries》》Add External JARs》粘贴路径》已经配置到了当前项目环境中,已经可以连接数据库了

    2.驱动加载

    所有的数据库的驱动加载是向容器加载(每当使用Java命令解释一个程序的时候都表示启动了一个Java Application容器),利用Class.forName()进行加载,Oracle的驱动程序类名称:Oracle.jdbc.driver.OracleDriver

    如果没有配置驱动程序,则会出现找不到类的异常。

    3.连接数据库

    要连接数据库,要使用java.sql.DriverManager程序类,这个类没有定义构造方法(私有化了),所以要想操作这个类可以使用它的静态方法:

      连接数据库:public static Connection getConnection(String url, String user, String password)

            这个方法会返回一个Connection接口对象,每一个Connection接口对象都会表示一个数据库连接。而后再getConnection方法里会需要有三个参数

      String url:每一个数据库连接地址都是不同的,使用的协议也是不同的

           Oracle标准格式:jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称

               连接ORCL数据库:jdbc:oracle:thin@localhost:1521:orcl

      String user:连接用户名,使用scott

      String password:连接密码,使用tiger

    4.关闭数据库连接

    如果要关闭,肯定使用Connection接口所定义的方法

    import java.sql.Connection;
    import java.sql.DriverManager;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            System.out.println(conn);
            //第三步:关闭数据库连接
            conn.close();
        }
    }

    此时一执行,没出错就是连上了。

    整个数据库连接对象的取得使用的设计模式就是工厂设计模式,DriverManager就是工厂类

    利用statement接口实现数据CRUD操作。

    在java.sql包中的Connection接口只负责数据库的连接使用,不具备数据操作能力,只有Statement接口才有数据操作能力。

    想取得Statement接口的对象可通过Connection接口的如下方法完成:

      实例化Statement对象:public Statement createStatement() throws SQLException;

    如果使用Statement大部分情况下操作的都是DML(数据库增删改查),所有Statement接口提供两种方法:

      数据更新操作:public int executeUpdate(String sql) throws SQLException;   返回int数据,是该更新影响的数据行数

      数据查询操作:public ResultSet executeQuery(String sql) throws SQLException; 

    范例:数据库脚本

    DROP TABLE member PURGE;
    DROP SEQUENCE myseq;
    CREATE SEQUENCE myseq;
    CREATE TABLE member(
        mid        NUMBER ,
        name        VARCHAR2(50) ,
        age        NUMBER(3) ,
        birthday    DATE ,
        note        CLOB,
        CONSTRAINT pk_mid PRIMARY KEY (mid)
    );

    member表中mid字段内容是依靠序列进行增长的。

    数据更新操作

    更新分为:INSERT、UPDATE、DELETE

    范例:增加数据

    SQL语句:

    INSERT INTO member(mid,name,age,birthday,note) VALUES(myseq.nextval,'张三',10,TO_DATE('1989-10-10','yyyy-mm-dd'),'是个人');
    
    commit;

    Java:

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.Statement;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            //第三步:进行数据库操作
            Statement stmt = conn.createStatement();//创建数据库操作
            String sql = "INSERT INTO member(mid,name,age,birthday,note) VALUES(myseq.nextval,'张三',10,TO_DATE('1989-10-10','yyyy-mm-dd'),'是个人')";
            int len = stmt.executeUpdate(sql);//执行更新,返回更新行数
            System.out.println("影响的数据行数:" + len);
            //第四步:关闭数据库连接
            conn.close();
        }
    }

    范例:数据更新操作:

    SQL:

    UPDATE member SET name='李四',birthday=SYSDATE WHERE mid IN (1,3,5,7,9);

    Java:

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.Statement;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            //第三步:进行数据库操作
            Statement stmt = conn.createStatement();//创建数据库操作
            String sql = "UPDATE member SET name='李四',birthday=SYSDATE WHERE mid IN (1,3,5,7,9)";
            int len = stmt.executeUpdate(sql);//执行更新,返回更新行数
            System.out.println("影响的数据行数:" + len);
            //第四步:关闭数据库连接
            conn.close();
        }
    }

    JDBC往往出现两种异常:

    1. java.sql.SQLException:数据库连接出错

    2. java.sql.SQLSyntaxErrorException:执行的SQL语句有错

    范例:数据删除:

    SQL:

    DELETE FROM member WHERE mid BETWEEN 3 AND 10; //删3到10的

    Java:

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.Statement;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            //第三步:进行数据库操作
            Statement stmt = conn.createStatement();//创建数据库操作
            String sql = "DELETE FROM member WHERE mid BETWEEN 3 AND 10";
            int len = stmt.executeUpdate(sql);//执行更新,返回更新行数
            System.out.println("影响的数据行数:" + len);
            //第四步:关闭数据库连接
            conn.close();
        }
    }

    数据查询操作:

    要将查询结果进行保留,为了保存,java.sql包中引入了ResultSet接口的概念。

    在ResultSet处理结果的时候实际是根据数据类型来处理的。

    SQL:

    SELECT mid,name,age,birthday,note FROM member

    Java:

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.Date;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            //第三步:进行数据库操作
            Statement stmt = conn.createStatement();//创建数据库操作
            String sql = "SELECT mid,name,age,birthday,note FROM member"; //开发中不允许写“*”
            ResultSet rs = stmt.executeQuery(sql); //数据查询操作
            //知道循环结束条件但是不知道循环次数,选择while循环
            while(rs.next()) { //移动指针同时判断是否还有数据行
                int mid = rs.getInt("mid");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                Date birthday = rs.getDate("birthday");
                String note = rs.getString("note");
                System.out.println("mid = " + mid + ", name = " + name + ", age = " + age + ", birthday = " + birthday + ", note = " + note);
            }
            //第四步:关闭数据库连接
            conn.close();
        }
    }
     

    写getXxx方法读取的数据可以不写列名称,直接编写序号就行了

    while(rs.next()) { //移动指针同时判断是否还有数据行
                int mid = rs.getInt(1);
                String name = rs.getString(2);
                int age = rs.getInt(3);
                Date birthday = rs.getDate(4);
                String note = rs.getString(5);
                System.out.println("mid = " + mid + ", name = " + name + ", age = " + age + ", birthday = " + birthday + ", note = " + note);
            }

    使用ResultSet说明:

      所有的内容最好只取得一次

      所有的内容最好按照顺序取

    PreparedStatement数据库操作接口(所有项目都用)

    statement存在的问题:

      有一个最严重的的问题,所有操作都需要使用完整的SQL语句,那么这时候如果数据是由用户自己输入的,就会产生问题。

    例如用户输入名字Mr'SMITH, 中间有单引号,而sql语句要用‘Mr'SMITH’双引号,会出错。

    PreparedStatement操作(核心!!!)

    Statement开发不要用,永远优先使用PreparedStatement接口,这是Statement的子接口,使用预处理的方式来操作。

    如果想取得PreparedStatement接口的实例化对象,继续依靠Connection接口,

    预处理指的是执行SQL语句的时候,是在创建PreparedStatement接口是,而具体的内容使用问好:?来进行占位,而后利用一系列setXxx()方法来设置内容。

    由于创建PreparedStatement接口的时候就已经准好了SQL语句,所以在执行SQL的时候就不在需要传递SQL语句了,使用PreparedStatement接口的如下方法实现数据库操作:

    更新操作:public int executeUpdate() throws SQLException;

    查询操作:public ResultSet executeQuery() throws SQLException;

    程序中日期时间的描述使用的是java.util.Date,这个类下有三个类:java.sql.Date、java.sql.Time、java.sql.Timestamp

    如果想java.util.Date变为具体的子类对象,必须依靠long数据类型;

    范例:利用PreparedStatement接口,解决名字Mr'SMITH不能写进SQL的问题

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.util.Date;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
            String name = "Mr'SMITH";
            int age = 30;
            Date birthday = new Date();
            String note = "是个能活动的人";
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            String sql = "INSERT INTO member(mid,name,age,birthday,note) VALUES (myseq.nextval,?,?,?,?) ";
            PreparedStatement pstmt = conn.prepareStatement(sql); //已经预处理的sql,但是没有输入值
            pstmt.setString(1, name);  //设占位符,1是代表第一个问号
            pstmt.setInt(2, age);
            pstmt.setDate(3, new java.sql.Date(birthday.getTime()));
            pstmt.setString(4, note);
            System.out.println(pstmt.executeUpdate());
            //第三步:关闭数据库连接
            conn.close();
        }
    }

    此时更新与删除的操作完全一样。

    在整个PreparedStatement接口里面最重要的就是查询。

    范例:查询全部

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.Date;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
    
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            String sql = "SELECT mid,name,age,birthday,note FROM member";
            PreparedStatement pstmt = conn.prepareStatement(sql); //已经预处理的sql,但是没有输入值
            ResultSet rs = pstmt.executeQuery();
            while(rs.next()) {
                int mid = rs.getInt(1);
                String name = rs.getString(2);
                int age = rs.getInt(3);
                Date birthday = rs.getDate(4);
                String note = rs.getString(5);
                System.out.println("mid = " + mid + ", name = " + name + ", age = " + age + ", birthday = " + birthday + ", note = " + note);
            }
            //第三步:关闭数据库连接
            conn.close();
        }
    }

    范例:实现限定查询,根据id查询

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.Date;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
    
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            String sql = "SELECT mid,name,age,birthday,note FROM member WHERE mid BETWEEN ? AND ?";
            PreparedStatement pstmt = conn.prepareStatement(sql); //已经预处理的sql,但是没有输入值
            pstmt.setInt(1, 1);  //第一个问号,设置内容为1
            pstmt.setInt(2, 13);  //第二个问号,设置内容为13   
            ResultSet rs = pstmt.executeQuery();
            while(rs.next()) {
                int mid = rs.getInt(1);
                String name = rs.getString(2);
                int age = rs.getInt(3);
                Date birthday = rs.getDate(4);
                String note = rs.getString(5);
                System.out.println("mid = " + mid + ", name = " + name + ", age = " + age + ", birthday = " + birthday + ", note = " + note);
            }
            //第三步:关闭数据库连接
            conn.close();
        }
    }

    范例:模糊查询

    模糊查询需要设置模糊查询字段

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.Date;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
            String keyword = "李";
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            String sql = "SELECT mid,name,age,birthday,note FROM member WHERE name LIKE ?";
            PreparedStatement pstmt = conn.prepareStatement(sql); //已经预处理的sql,但是没有输入值
            pstmt.setString(1, "%" + keyword + "%");  //设置匹配符
            ResultSet rs = pstmt.executeQuery();
            while(rs.next()) {
                int mid = rs.getInt(1);
                String name = rs.getString(2);
                int age = rs.getInt(3);
                Date birthday = rs.getDate(4);
                String note = rs.getString(5);
                System.out.println("mid = " + mid + ", name = " + name + ", age = " + age + ", birthday = " + birthday + ", note = " + note);
            }
            //第三步:关闭数据库连接
            conn.close();
        }
    }

     需要注意,使用占位符只能设置数据,不能设置表字段名称。

    范例:分页查询

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.Date;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
            String keyword = "张";
            int currentPage = 1;
            int lineSize = 5;  //每页显示的数据行数
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            String sql = "SELECT * FROM (SELECT mid,name,age,birthday,note, ROWNUM rn FROM member WHERE name LIKE ? AND ROWNUM <= ? ) temp WHERE temp.rn > ?";
            PreparedStatement pstmt = conn.prepareStatement(sql); //已经预处理的sql,但是没有输入值
            pstmt.setString(1, "%" + keyword + "%");  //设置匹配符
            pstmt.setInt(2,currentPage * lineSize);
            pstmt.setInt(3, (currentPage-1) * lineSize);
            ResultSet rs = pstmt.executeQuery();
            while(rs.next()) {
                int mid = rs.getInt(1);
                String name = rs.getString(2);
                int age = rs.getInt(3);
                Date birthday = rs.getDate(4);
                String note = rs.getString(5);
                System.out.println("mid = " + mid + ", name = " + name + ", age = " + age + ", birthday = " + birthday + ", note = " + note);
            }
            //第三步:关闭数据库连接
            conn.close();
        }
    }

    范例:查询数据库中数据记录个数:使用COUNT()函数,

    使用COUNT统计一定会返回结果

    name叫张三的有几行

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    public class Hello{
        public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
        public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl";  //jdbc:oracle:thin:@IP 地址:端口号:数据库的SID名称
        public static final String DBUSER = "scott"; // 连接用户名
        public static final String PASSWORD = "123456"; //连接密码
        public static void main(String[] args) throws Exception {
            
            //第一步:加载数据库驱动程序
            Class.forName(DBDRIVER); //向容器中加载驱动连接类
            //第二步:取得数据库连接对象
            Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
            String sql = "SELECT COUNT(*) FROM member WHERE name = '张三'";
            PreparedStatement pstmt = conn.prepareStatement(sql); //已经预处理的sql,但是没有输入值
            ResultSet rs = pstmt.executeQuery();
            if(rs.next()) {
                int count = rs.getInt(1); //取第一个数
                System.out.println(count);
            }
            //第三步:关闭数据库连接
            conn.close();
        }
    }

    批处理:若干条语句一起执行。在Statement接口与PreparedStatement接口中都定义有批处理的支持方法 。

    Statement接口:

      追加批处理:public void addBatch(String sql) throws SQLException

      执行批处理:public int[] executeBatch() throws SQLException

    PreparedStatement接口:

      追加批处理:public void addBatch() throws SQLException

    自动提交控制:public void setAutoCommit(boolean autoCommit) throws SQLException; 如果是true,就自动提交

    提交:public void commit() throws SQLException

    回滚:public void rollback() throws SQLException

  • 相关阅读:
    ASP.NET图片上传(配合jquery.from.js 插件)
    判断上传文件类型,上传图片
    父子一对多iframe,子iframe改子iframe元素
    Jquery 清空input file的值
    通过createObjectURL实现图片预览
    URL.createObjectURL() 与 URL.revokeObjectURL()
    python try finally和with语句
    python mixin 模式特点
    Python中的Sentinel(哨兵)值
    《JavaScript ES6 函数式编程入门经典》笔记1
  • 原文地址:https://www.cnblogs.com/lonske/p/8824743.html
Copyright © 2011-2022 走看看