使用JDBC(API)来操作数据库用到的类:
1 Connection 连接
2 Statement 语句
3 ResultSet 结果集
Connection
连接 相当于Session 、Socket
连接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函数参数:
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 found for jdbc:mysql://localhost:3306/itcast
(对于协议jdbc:mysql://localhost:3306/itcast找不到合适的驱动)
因为连接Connection是接口,光有接口的干不了事情的!必须要有实现类!
看Connection源代码:
右击查看层次视图:(按F4也可)
可见根本没有连接的实现类
JDBC是API 是一套规范 这套API就是接口(规范一般都是接口) 接口 抽象类 都是不具体的 而对于每个厂商又有自己产品的实现 所以每个厂商都得给出这个实现 那就是驱动程序的作用 而驱动程序需要去网上下载 即mysql-connector-java-5.x.x.jar 文件
在此给出一个版本的下载:
mysql-connector-java-5.1.30
将驱动程序加到项目中:
先在java项目下新建lib文件夹
直接ctrl + c / v 把 mysql-connector-java-x.jar文件粘贴到lib文件夹下:
还要右击把jar文件放到构架路径中去!!:
(即加入classpath中)
添加构架路径成功:
再看等级树 有了实现类:
所以驱动程序就是把这些规范加以实现
来看驱动文件中的com.mysql.jdbc.Driver.class:
此Driver.class实现的是java.sql.Driver接口:
java.sql.Driver是驱动器接口
java.sql.Driver javadoc:
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对象:
注意:我们使用java.sql包下的 不使用com.mysql.jdbc下的Statement来创建(即选择截图中上面的而不是下面的Statement)这样做是为了解耦合! 这样代码换成其他数据库也同样适用 面向对象编程要 高内聚 低耦合
创建好语句对象 我们来看执行的操作:
String sql = "insert into test(id,name,age) values(2, 'ta', 99)";
st.execute(sql);
语句对象 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();
}
}
}
}
运行代码:
刷新表后显示成功插入数据:
较之前的代码 只是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的数据更新:
删除数据示例:
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的数据被删除:
总结以上增删改 操作步骤:
第一步 加载注册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()函数方法:
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();
}
}
}
}
运行后遍历打印:
总结查询数据7步骤:
第一步 加载注册JDBC的驱动类
第二步 提供JDBC连接的url 数据库账号、密码
第三步 创建数据库的连接
第四步 创建一个statement对象
第五步 执行sql语句
第六步 遍历结果集
第七步 关闭JDBC对象