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)

随后需要配置数据库驱动程序,驱动程序路径:找到数据库安装文件目录...\product\11.2.0\dbhome_1\jdbc\lib\ojdbc6.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

 

posted on 2018-04-13 23:27  lonske  阅读(747)  评论(0编辑  收藏  举报