7.22 JDBC 学习总结

使用JDBC(API)来操作数据库用到的类:
1 Connection 连接
2 Statement 语句
3 ResultSet 结果集

Connection
连接 相当于Session 、Socket


连接.png

连接Connection是接口!!!

A connection (session) with a specific database. SQL statements are executed and results are returned within the context of a connection.
(一个连接就是一个和指定数据库的会话,SQL语句被执行并在连接的上下文中返回结果)
即首先要和服务器建立连接 然后发给其消息 服务器执行后返回结果 通过连接来完成!

A Connection object's database is able to provide information describing its tables, its supported SQL grammar, its stored procedures, the capabilities of this connection, and so on. This information is obtained with the getMetaData method.
一个连接对象能够提供一些描述表的信息、和它支持的SQL语句、存储过程、连接的能力等,这些信息可以通过getMetaData(获得元数据)方法得到。
注:元数据是描述数据的数据...

Connection对象创建方式:

Connection conn = DriverManager.getConnection(url, user, password);

即使用DiverManager(驱动器管理器)的getConnection方法创建连接对象。

拓展:
驱动器管理器 DiverManager
The basic service for managing a set of JDBC drivers.
是管理一系列JDBC驱动的基本服务

来看getConnection函数参数:


getConnection函数参数.png

url:数据库的url地址
user:数据库账号
password:数据库密码

注:
URL Uniform Resource Locator
统一资源定位符(是标识符的一种)
(定位符是带层级结构的概念)

URI Uniform Resource Identifier
统一资源标识符

注意:
url地址对不同的数据库,格式不一样!

对于MySQL数据库格式:

String url = "jdbc:mysql://localhost:3306/itcast";

jdbc:mysql 叫协议 中间有:分割叫子协议
locakhost 为主机名
3306 为端口号 port
itcast 为路径path (一个数据库名称)

写全url 等并加入try - catch处理运行:

no suitable driver.png

显示:No suitable driver found for jdbc:mysql://localhost:3306/itcast
(对于协议jdbc:mysql://localhost:3306/itcast找不到合适的驱动)
因为连接Connection是接口,光有接口的干不了事情的!必须要有实现类!

看Connection源代码:


Paste_Image.png

右击查看层次视图:(按F4也可)


Paste_Image.png

可见根本没有连接的实现类

JDBC是API 是一套规范 这套API就是接口(规范一般都是接口) 接口 抽象类 都是不具体的 而对于每个厂商又有自己产品的实现 所以每个厂商都得给出这个实现 那就是驱动程序的作用 而驱动程序需要去网上下载 即mysql-connector-java-5.x.x.jar 文件
在此给出一个版本的下载:
mysql-connector-java-5.1.30

将驱动程序加到项目中:
先在java项目下新建lib文件夹


Paste_Image.png
Paste_Image.png

直接ctrl + c / v 把 mysql-connector-java-x.jar文件粘贴到lib文件夹下:

Paste_Image.png

还要右击把jar文件放到构架路径中去!!:


Paste_Image.png

(即加入classpath中)

添加构架路径成功:


Paste_Image.png

再看等级树 有了实现类:

Paste_Image.png
Paste_Image.png

所以驱动程序就是把这些规范加以实现

来看驱动文件中的com.mysql.jdbc.Driver.class:


Paste_Image.png

此Driver.class实现的是java.sql.Driver接口:


Paste_Image.png

java.sql.Driver是驱动器接口

Paste_Image.png

java.sql.Driver javadoc:

Paste_Image.png

javadoc中指出
The interface that every driver class must implement.
The Java SQL framework allows for multiple database drivers.
Each driver should supply a class that implements the Driver interface.
(以上英文很简单 自行阅读)
The DriverManager will try to load as many drivers as it can find and then for any given connection request, it will ask each driver in turn to try to connect to the target URL.
(驱动器管理器将尝试去加载很多它能找到的或者通过给定的链接找到的驱动器们,它将轮流请求每一个驱动程序 并 试图去连接到地址)

java doc重要的:
When a Driver class is loaded, it should create an instance of itself and register it with the DriverManager. This means that a user can load and register a driver by calling:

Class.forName("foo.bah.Driver")

当驱动程序类被加载,它将去创建一个自身的实例并在驱动器管理器中进行注册,这意味着用户可以通过调用 Class.forName("foo.bah.Driver") 函数 加载并注册一个驱动

Class.forName("foo.bah.Driver")用来注册驱动!

所以在 提供JDBC连接的url、账号、密码 和 创建数据库的连接 之前需要 先加载JDBC的驱动类:

Class.forName("com.mysql.jdbc.Driver");

"com.mysql.jdbc.Driver" 是 className

到此我们完成了:
第一步 加载注册JDBC的驱动类
第二步 提供JDBC连接的url 账号密码等信息
第三步 创建数据库的连接

try {
    // 第一步 加载注册JDBC的驱动类
    Class.forName("com.mysql.jdbc.Driver");
    // 第二步 提供JDBC连接的url
    String url = "jdbc:mysql://localhost:3306/itcast";
    String user = "root";
    String password = "root";
    // 第三步 创建数据库的连接
    Connection conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
    e.printStackTrace();
}

然后我们用连接Connection对象的createStatement()函数方法创建一个Statement(语句):
语句 相当于数据 InputStream (套接字Socket里面已经封住好流)

创建语句

createStatement()函数方法说明:
Creates a Statement object for sending SQL statements to the database. SQL statements without parameters are normally executed using Statement objects. If the same SQL statement is executed many times, it may be more efficient to use a PreparedStatement object.
创建一个Statement对象用来发送SQL语句给数据库 SQL语句没有参数,使用Statement对象来执行

创建Statement对象:

Paste_Image.png

注意:我们使用java.sql包下的 不使用com.mysql.jdbc下的Statement来创建(即选择截图中上面的而不是下面的Statement)这样做是为了解耦合! 这样代码换成其他数据库也同样适用 面向对象编程要 高内聚 低耦合

创建好语句对象 我们来看执行的操作:


Paste_Image.png
String sql = "insert into test(id,name,age) values(2, 'ta', 99)";
st.execute(sql);
Paste_Image.png

语句对象 execute() 方法:
Executes the given SQL statement, which may return multiple results. In some (uncommon) situations, a single SQL statement may return multiple result sets and/or update counts. Normally you can ignore this unless you are (1) executing a stored procedure that you know may return multiple results or (2) you are dynamically executing an unknown SQL string.
执行这个sql语句,可返回多个记录。
单个sql语句可以返回多个结果集或者更新的数量。除非你对它执行存储过程,通常你可以忽视它。

Returns:
true if the first result is a ResultSet object; false if it is an update count or there are no results
如果第一个结果是ResultSet对象 返回true
否则返false
不是我们理解的返回成功和失败 即执行sql语句返回的是一个标记

返回的说明较难理解 通常我们让其直接执行即可 而不用其返回值

在此给出利用其返回值的一个示例:

// 第五步 执行sql语句
String sql = "select * from student";
ResultSet rs = stmt.executeQuery(sql);
// 第六步 循环遍历处理结果
while(rs.next()) {
    System.out.println(rs.getString("name"));
    System.out.println(rs.getFloat("grade"));
}

执行完后要关闭JDBC对象 释放资源:

//关闭JDBC对象
rs.close();
stmt.close();
conn.close();

插入数据完整代码:

public class JDBCDemo {

    public static void main(String[] args) {
        
        Connection conn = null;
        Statement stmt = null;
        
        try {
            // 第一步 加载注册JDBC的驱动类
            Class.forName("com.mysql.jdbc.Driver");
            // 第二步 提供JDBC连接的url
            String url = "jdbc:mysql://localhost:3306/itcast";
            String user = "root";
            String password = "root";
            // 第三步 创建数据库的连接
            conn = DriverManager.getConnection(url, user, password);
            // 第四步 创建一个statement对象
            stmt= conn.createStatement();
            // 第五步 执行sql语句
            String sql = "insert into test(id,name,age) values(2, 'ta', 99)";
            stmt.execute(sql);
        }catch(ClassNotFoundException e) {
            e.printStackTrace();
        }catch(SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                // 第六步 关闭JDBC对象
                if(stmt != null) {
                    stmt.close();
                }
                if(conn != null) {
                    conn.close();
                }
            }catch(SQLException e) {
                e.printStackTrace();
            }
        }
    }
}  

运行代码:


Paste_Image.png

刷新表后显示成功插入数据:

Paste_Image.png
Paste_Image.png

较之前的代码 只是sql语句不同!

更新数据示例:

public class JDBCDemo {

    public static void main(String[] args) {
        
        Connection conn = null;
        Statement stmt = null;
        
        try {
            // 第一步 加载注册JDBC的驱动类
            Class.forName("com.mysql.jdbc.Driver");
            // 第二步 提供JDBC连接的url
            String url = "jdbc:mysql://localhost:3306/itcast";
            String user = "root";
            String password = "root";
            // 第三步 创建数据库的连接
            conn = DriverManager.getConnection(url, user, password);
            // 第四步 创建一个statement对象
            stmt= conn.createStatement();
            // 第五步 执行sql语句
            String sql = "update test set name='up',age=18 where id=1";
            stmt.execute(sql);
        }catch(ClassNotFoundException e) {
            e.printStackTrace();
        }catch(SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                // 第六步 关闭JDBC对象
                if(stmt != null) {
                    stmt.close();
                }
                if(conn != null) {
                    conn.close();
                }
            }catch(SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

id为1的数据更新:


Paste_Image.png

删除数据示例:

public class JDBCDemo {

    public static void main(String[] args) {
        
        Connection conn = null;
        Statement stmt = null;
        
        try {
            // 第一步 加载注册JDBC的驱动类
            Class.forName("com.mysql.jdbc.Driver");
            // 第二步 提供JDBC连接的url
            String url = "jdbc:mysql://localhost:3306/itcast";
            String user = "root";
            String password = "root";
            // 第三步 创建数据库的连接
            conn = DriverManager.getConnection(url, user, password);
            // 第四步 创建一个statement对象
            stmt= conn.createStatement();
            // 第五步 执行sql语句
            String sql = "delete from test where id=2";
            stmt.execute(sql);
        }catch(ClassNotFoundException e) {
            e.printStackTrace();
        }catch(SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                // 第六步 关闭JDBC对象
                if(stmt != null) {
                    stmt.close();
                }
                if(conn != null) {
                    conn.close();
                }
            }catch(SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

较之前的代码 只是sql语句不同!

id=2的数据被删除:

Paste_Image.png

总结以上增删改 操作步骤:
第一步 加载注册JDBC的驱动类
第二步 提供JDBC连接的url 数据库账号、密码
第三步 创建数据库的连接
第四步 创建一个statement对象
第五步 执行sql语句
第六步 关闭JDBC对象

增删改 代码模板:

Connection conn = null;
Statement stmt = null;

try {
    // 第一步 加载注册JDBC的驱动类
    Class.forName("com.mysql.jdbc.Driver");
    // 第二步 提供JDBC连接的url
    String url = "jdbc:mysql://localhost:3306/itcast";
    String user = "root";
    String password = "root";
    // 第三步 创建数据库的连接
    conn = DriverManager.getConnection(url, user, password);
    // 第四步 创建一个statement对象
    stmt= conn.createStatement();
    // 第五步 执行sql语句
    String sql = ...;
    stmt.execute(sql);
}catch(ClassNotFoundException e) {
    e.printStackTrace();
}catch(SQLException e) {
    e.printStackTrace();
}finally{
    try {
        // 第六步 关闭JDBC对象
        if(stmt != null) {
            stmt.close();
        }
        if(conn != null) {
            conn.close();
        }
    }catch(SQLException e) {
        e.printStackTrace();
    }
}

应用时需要对sql赋予相对应的增删改的sql指令
String sql = ...;

只查询是比较麻烦:
用到Statement对象的executeQuery()函数方法:


Paste_Image.png

executeQuery()函数说明:

Executes the given SQL statement, which returns a single ResultSet object.

Parameters:sql an SQL statement to be sent to the database, typically a static SQL SELECT statement

Returns:a ResultSet object that contains the data produced by the given query; never null

返回一个包含数据的ResultSet! 注意 never null !
因为其never null 所有查询数据库时不能用以下代码判断非空:

   rs != null;

(rs 为ResultSet 对象)
而应该用下面的语句判断非空:

while( rs.next() ) {
    ...
}

关于ResultSet的描述:
A table of data representing a database result set, which is usually generated by executing a statement that queries the database.

A ResultSet object maintains a cursor pointing to its current row of data. Initially the cursor is positioned before the first row.
注意:初始游标cursor指向第一行之前。

给出遍历查询数据库代码:

public class JDBCDemo {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            // 第一步 加载注册JDBC的驱动类
            Class.forName("com.mysql.jdbc.Driver");
            // 第二步 提供JDBC连接的url
            String url = "jdbc:mysql://localhost:3306/itcast";
            String user = "root";
            String password = "root";
            // 第三步 创建数据库的连接
            conn = DriverManager.getConnection(url, user, password);
            // 第四步 创建一个statement对象
            stmt= conn.createStatement();
            // 第五步 执行sql语句
            String sql = "select * from test";
            rs = stmt.executeQuery(sql); 
            // 第六步 遍历结果集
            while(rs.next()){
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                System.out.println(id + " : " + name + " : " + age);
            } 
        }catch(ClassNotFoundException e) {
            e.printStackTrace();
        }catch(SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                // 第七步 关闭JDBC对象
                if(rs != null) {
                    rs.close();
                }
                if(stmt != null) {
                    stmt.close();
                }
                if(conn != null) {
                    conn.close();
                }
            }catch(SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

运行后遍历打印:


查询数据.png

总结查询数据7步骤:
第一步 加载注册JDBC的驱动类
第二步 提供JDBC连接的url 数据库账号、密码
第三步 创建数据库的连接
第四步 创建一个statement对象
第五步 执行sql语句
第六步 遍历结果集
第七步 关闭JDBC对象

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,422评论 0 4
  • 本人的环境为Myeclipse10、MySQL5.7.15 本文包括:简介JDBC编程步骤打通数据库程序详解—Dr...
    廖少少阅读 3,922评论 7 39
  • JDBC概述 在Java中,数据库存取技术可分为如下几类:JDBC直接访问数据库、JDO技术、第三方O/R工具,如...
    usopp阅读 3,526评论 3 75
  • 本节介绍Statement接口及其子类PreparedStatement和CallableStatement。 它...
    zlb阅读 1,132评论 0 0
  • 现在物质很丰富,尤其是中国。可是我看不见得年轻人能幸福多少,大家反而感觉压力重重。这个幸福的问题,每个人都在找,有...
    善知识摘抄阅读 194评论 0 0