JDBC流程
最近要学习Mybatis的源码,因此对JDBC的使用进行总结。
一、JDBC概述
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,让我们通过程序操作数据库,是java的核心技术之一。
二、JDBC流程详解
JDBC操作数据库共包括6个步骤:
注冊驱动 (仅仅做一次)
建立连接(Connection)
创建传输器Statement
运行SQL语句
处理运行结果(ResultSet)
释放资源
下面就分别针对六个步骤进行说明。
第一步:注册驱动
注冊驱动有三种方式:
1、 Class.forName(“com.mysql.jdbc.Driver”);
推荐这样的方式,不会对详细的驱动类产生依赖
2、DriverManager.registerDriver(com.mysql.jdbc.Driver);
会对详细的驱动类产生依赖
3、System.setProperty(“jdbc.drivers”, “driver1:driver2”);
尽管不会对详细的驱动类产生依赖,但注冊不太方便,所以非常少使用
第二步:建立连接
通过Connection建立连接,Connection是一个接口类。其功能是与数据库进行连接(会话)。
建立Connection接口类对象:
Connection conn =DriverManager.getConnection(url, user, password);
user为登录数据库的username,如root
password为登录数据库的密码,为空填””
当中url的格式要求为:
//子协议:子名称//主机名:port/数据库名?属性名=属性值&…
url = "jdbc:mysql://localhost:3306/test“
第三步:创建传输器Statement
运行对象Statement负责运行SQL语句。由Connection对象产生。
Statement st = connection.createStatement();
Statement接口类还派生出两个接口类PreparedStatement和CallableStatement,这两个接口类对象为我们提供了更加强大的数据訪问功能。
PreparedStatement接口
PreparedStatement能够对SQL语句进行预编译,这样防止了SQL注入,提高了安全性。
PreparedStatement ps=connection.prepareStatement( "update user set id = ? where username = ?”);
//sql语句中用?作为通配符,变量值通过参数设入:ps.setObject(1, object);
此外预编译结果能够存储在PreparedStatement对象中,当多次运行SQL语句时能够提高效率。作为Statement的子类,PreparedStatement继承了Statement的全部函数。
CallableStatement接口
CallableStatement类继承了PreparedStatement类,他主要用于运行SQL存储过程。
在JDBC中运行SQL存储过程须要转义。
JDBC API提供了一个SQL存储过程的转义语法:
{call<procedure-name>[<arg1>,<arg2>, ...]}
//procedure-name:是所要运行的SQL存储过程的名字
//[<arg1>,<arg2>, ...]:是相相应的SQL存储过程所须要的參数
第四步:运行SQL语句
运行对象Statement 或 PreparedStatement 提供两个经常使用的方法来运行SQL语句:executeQuery和executeUpdate。
1、executeQuery(Stringsql),该方法用于运行实现查询功能的sql语句。返回类型为ResultSet(结果集)。
ResultSet rs =st.executeQuery(sql);
2、executeUpdate(Stringsql),该方法用于运行实现增、删、改功能的sql语句,返回类型为int,即受影响的行数。
int flag = st.executeUpdate(sql);
第五步:处理运行结果
ResultSet对象负责保存Statement运行后所产生的查询结果。结果集ResultSet是通过游标来操作的,游标就是一个可控制的、能够指向随意一条记录的指针。有了这个指针我们就能轻易地指出我们要对结果集中的哪一条记录进行改动、删除,或者要在哪一条记录之前插入数据。一个结果集对象中仅仅包括一个游标。另外,借助ResultSetMetaData ,可以将数据表的结构信息都查出来。
ResultSetMetaData rsmd= resultSet.getMetaData();
第六步:释放资源
数据库资源不关闭,其占用的内存不会被释放,消耗资源,影响系统。倒序释放资源:倒叙释放资源resultSet—>preparedStatement—>connection。
三、代码实现
数据库删除,修改和插入,使用executeUpdate()方法。
public class JDBCTest {
/**
* 加载的mysql的驱动
*/
public static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
/**
* 连接数据库的url
*/
public static final String JDBC_URL = "jdbc:mysql://localhost:3306/test";
/**
* 连接数据库用户名
*/
public static final String JDBC_USERNAME = "root";
/**
* 数据库密码
*/
public static final String JDBC_PASSWORD = "123456";
/**
* 测试数据库删除,修改和插入
*/
@Test
public void testUpdate() {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
// 加载Driver类,注册数据库驱动
Class.forName(JDBC_DRIVER);
// 通过DriverManager,使用url,用户名和密码建立连接(Connection)
connection = DriverManager.getConnection(JDBC_URL, JDBC_USERNAME, JDBC_PASSWORD);
// 通过Connection,使用sql语句打开Statement对象;
preparedStatement = connection.prepareStatement("UPDATE student SET age=20 WHERE name=?");
// 传入参数,防止sql注入
preparedStatement.setString(1, "xiaoming");
// 执行语句,将结果返回resultSet
int count = preparedStatement.executeUpdate();
// 对结果进行处理
System.out.println(count);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 倒序释放资源
try {
if (preparedStatement != null && !preparedStatement.isClosed()) {
preparedStatement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (connection != null && connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 测试批量操作
*/
@Test
public void testBatch() {
Connection connection = null;
PreparedStatement preparedStatement = null;
String insertSql = "insert into student values(?,?)";
try {
// 加载Driver类,注册数据库驱动
Class.forName(JDBC_DRIVER);
// 通过DriverManager,使用url,用户名和密码建立连接(Connection)
connection = DriverManager.getConnection(JDBC_URL, JDBC_USERNAME, JDBC_PASSWORD);
// 通过Connection,使用sql语句打开Statement对象;
preparedStatement = connection.prepareStatement(insertSql);
// 传入参数,防止sql注入
for (int i = 0; i < 10; i++) {
preparedStatement.setString(1, 100 + i + "user");
preparedStatement.setInt(2, 100 + i);
preparedStatement.addBatch();
}
// 执行语句,将结果返回resultSet
int[] count = preparedStatement.executeBatch();
// 对结果进行处理
System.out.println(count);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 倒序释放资源
try {
if (preparedStatement != null && !preparedStatement.isClosed()) {
preparedStatement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (connection != null && connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
参考了:
https://www.cnblogs.com/homejim/p/8068199.html
https://www.cnblogs.com/lightandtruth/p/9473862.html
JDBC流程的更多相关文章
- JDBC 流程
转载地址:https://blog.csdn.net/suwu150/article/details/52744952 JDBC编程的六个步骤: 准备工作中导入ojdbc文件,然后右键选中添加路 ...
- 加载数据库驱动程序的方法和JDBC的流程
加载驱动方法 1.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 2. DriverManager.r ...
- JDBC详解系列(一)之流程
---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)--- JDBC概述 使用JDBC也挺长 ...
- JDBC的使用
JDBC详解系列(一)之流程 ---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)--- 使 ...
- JDBC详解系列(二)之加载驱动
---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)--- 在JDBC详解系列(一)之流程中 ...
- JDBC详解系列(三)之建立连接(DriverManager.getConnection)
在JDBC详解系列(一)之流程中,我将数据库的连接分解成了六个步骤. JDBC流程: 第一步:加载Driver类,注册数据库驱动: 第二步:通过DriverManager,使用url,用户名和密码 ...
- Java面试通关要点汇总集
Java面试通关要点汇总集 2018-03-09 转自:Java面试通关要点汇总集 文章目录 1. 基础篇 1.1. 基本功 1.2. 集合 1.3. 线程 1.4. 锁机制2. 核心篇 2 ...
- Java面试题[转载]
目录 转载 简历篇 请自我介绍 请介绍项目 基础篇 基本功 面向对象的特征 final, finally, finalize 的区别 int 和 Integer 有什么区别 重载和重写的区别 抽象类和 ...
- Java基础知识盘点(一)- 基础篇
基本功 面向对象特征 封装.继承.多态和抽象 1.封装:给对象提供了隐藏内部特性和行为的能力.对象提供一些能被其他对象访问的方法,来改变它内部的数据. 在Java中,其访问权限有3种修饰符:publi ...
随机推荐
- MVVM双向绑定实现之Object.defineProperty
随着web应用的发展,直接操作dom的应用已渐行渐远,取而代之的是时下越来越流行的MVVM框架,dom操作几乎绝迹,这里面自然是框架底层封装的结果.MVVM框架的双向数据绑定使开发效率大大提高:然后在 ...
- ssh远程登录出现Host key verification failed.解决办法
今天通过ssh和域名连接主机: IcarusdeMacBook-Pro:~ icarus$ ssh root@icarusyu.me 出现了如下错误: @@@@@@@@@@@@@@@@@@@@@@@@ ...
- [转载]java开发中的23种设计模式
原文链接:http://blog.csdn.net/zhangerqing 设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反 ...
- vue项目axios请求接口,后端代理请求接口404,问题出现在哪?
在vue项目中,列表数据需要用到qq音乐接口中的数据,但是直接请求不行,有host及referer限制,需要采用后端代理的方式.借助axios及node的express,在dev-server.js中 ...
- Angular使用总结 --- 搜索场景中使用rxjs的操作符
在有input输入框的搜索/过滤业务中,总会考虑如何减少发起请求频率,尽量使每次的请求都是有效的.节流和防抖是比较常见的做法,这类函数的实现方式也不难,不过终归还是需要自己封装.rxjs提供了各种操作 ...
- Python3之PrettyTable模块
一. 简介 Python通过prettytable模块将输出内容如表格方式整齐输出,python本身并不内置,需要独立安装该第三方库. 二. 安装 方式一:pip安装 >>> pip ...
- [原创]K8 Struts2 Exp 20170310 S2-045(Struts2综合漏洞利用工具)
工具: K8 Struts2 Exploit组织: K8搞基大队[K8team]作者: K8拉登哥哥博客: http://qqhack8.blog.163.com发布: 2014/7/31 10:24 ...
- POJ 2681
#include<iostream> #include<stdio.h> #include<string> #include<algorithm> #d ...
- 线程中的同步辅助类Exchanger
Exchanger 允许两个线程在 collection 点交换对象,它在多流水线设计中是有用的. 允许两条线程之间交换数据.Exchanger的exchange方法是阻塞的,当其他线程也调用了该方法 ...
- webgl介绍
一.webgl与three.js 我们知道canvas.svg等是2D绘图的,那么如果想要使用js进行3D绘图,可以吗? 答案是肯定的!实际上主流的3D开发使用的是c++,但是随着技术的发展,Java ...