前言
这两天工作上的事情比较少,想着前段时间涉及到的JDBC的相关东西自己当时看着还有点生硬,就想着再来复习一下,如果有理解有误的地方,还望在下方指正。
如果转载请标明出处。
JDBC概述
JDBC(Java DataBase Connection)Java数据库连接,是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口。我们通常说的JDBC是面向关系型数据库的。
它是Java与数据库之间的桥梁,用于将Java和数据库连接起来。可以执行SQL语句。
它由一组Java编写的类和接口组成,不同数据库厂商有不同的实现,分别封装与不同的驱动中,我们编写JDBC程序,就需要去下载相应数据库的驱动。
使用前的准备工作
所谓的准备工作就是导入相应数据库的驱动,也就是jar包了,我们使用eclipse的maven导包方式。
首先使用eclipse建一个maven项目(创建maven项目的步骤就不在这里赘述了,有需要的可以查看我的其他博客),按照我上图的步骤依次执行。值得注意的是,第五步搜索出jar包后,需要点开下面的包选择相应的版本,然后导入,导入成功后,会再第六步的位置出现你选中版本的jar包。(因为我这里的包是有问题的,大家不要介意,知识介绍一下流程)
导入成功后,可以在项目的MavenDependencise中查看你所导入的包。如下如所示。
现在我们就可以敲代码了!
JDBC的使用步骤
1. 加载驱动
//加载驱动
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
该方法会抛出一个ClassNotFoundException,当找不到驱动的时候才会抛出,"oracle.jdbc.driver.OracleDriver"表示驱动,这一串东西是死记硬背写出来的么,其实不然,有两种方式获取。
方法一:在项目中的Maven Dependencies/ojdbc7/oracle/jdbc文件夹中找到OracleDriver.class文件,鼠标点击右键,选择Copy Qualified Name,然后复制在 Class.forName()中。
方法二:如方法一一样找到OracleDriver.class文件,双击打开。复制如下一段话,然后粘贴在Class.forName () 中。(好像复制继承的那个驱动也可以,哈哈哈)
2. 创建连接
String url = "jdbc:oracle:thin:@118.111.11.111:1521:orcl";
String username = "w1111";
String password = "d111";
Connection conn = null;
try {
//建立连接
conn = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
e.printStackTrace();
}
创建连接时会有三个参数,分别为需要连接的数据库地址,用户名,密码。
该方法会抛出一个SQLException。
3. 创建statement
try {
Statement stat = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
4. 执行SQL,处理结果集
String sql = "SELECT * FROM A";
String sql2 = "DELETE FORM A WHERE id = 1";
String sql3 = "SELECT * FROM A";
try {
boolean b = stat.execute(sql);
int n = stat.executeUpdate(sql2);
ResultSet rs = stat.executeQuery(sql3);
while(rs.next()){
int i = rs.getInt("id");
System.out.println(i);
}
} catch (SQLException e) {
e.printStackTrace();
}
这里写了三种执行SQL的方法。使用时使用一种就行了。
boolean b = stat.execute(sql);
这个方法可以执行任何SQL语句,返回值表示是否成功,一般用来执行DDL语句。
int n = stat.executeUpdate(sql2);
这个方法用来执行DML语句。返回值表示操作的记录数。
ResultSet rs = stat.executeQuery(sql3);
while(rs.next()){
int i = rs.getInt("id");
System.out.println(i);
}
这个方法用来执行DQL语句。返回值表示查询的结果集,里面存在一个游标用来操作结果集,可以通过迭代器将查询的结果集查询出来操作。
5. 关闭接口,释放资源
rs.close();
stat.close();
conn.close();
在这个过程中,我们创建了一些接口和类,比如Statement,ResultSet等,他们会占用内存资源,所以我们在使用完后,需要关闭他们,释放资源。
代码优化
上面介绍的知识点只是可以实现java连接数据库,执行sql语句,可以作为测试,学习使用,但是不能应用于工作中,因为那样写代码,使得数据与代码结合太过于紧密,不利于后期更改数据,如果更改一次URL就要重启一次程序不太理想,因此,需要将代码进行优化,优化的方案有很多种,我们这里使用properties存储数据,建立工具类的方式。
1. 创建properties文件
首先,在java的同级目录resources目录下建立一个db.properties文件,打开文件,在文件中填写如下代码。
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@118.111.11.111:1521:orcl
username=w111
password=db111
注意:
properties使用键值对的形式存储信息,即key=value
value是直接写在后面的,无需加引号
value后不能有空格
url、username、password根据自己的实际情况填写,我这里只是做个示范
一定要注意填写的值准确性,否在无法连接数据库
2. 创建工具类
创建一个类DBUtis,在该类中,我们去获取properties中的信息,并创建连接,最后将关闭连接的方法也写在里面,如下图所示。
/**
* 用于建立数据库连接和断开连接
* @author DH
*
*/
public class DBUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
static{
Properties p = new Properties();
try {
p.load(DBUtils.class.getClassLoader().getResourceAsStream("db.propertise"));
driver = p.getProperty("driver");
url = p.getProperty("url");
username = p.getProperty("username");
password = p.getProperty("password");
} catch (IOException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url,username,password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public static void close(Connection conn){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
1.我们使用Properties的load方法获取文件,因为这里的文件放在resource内的,我们使用DBUtils.class.getClassLoader().getResourceAsStream(“db.propertise”)的方式,DBUtis是当前类,db.propertise是我们写的存储数据的properties文件。
2.我们将方法都定义成静态的
3.因为静态方法中无法调用非静态成员变量,因此,变量也是静态的
4.给静态变量赋值就是用静态代码块实现
3. 使用工具类
public class Test {
public static void main(String[] args) throws SQLException {
Connection conn = DBUtils.getConnection();
Statement stat = conn.createStatement();
String sql = "SELECT a FROM A";
ResultSet rs= stat.executeQuery(sql);
while(rs.next()){
String a = rs.getString("a");
System.out.println(a);
}
rs.close();
stat.close();
DBUtils.close(conn);
}
}
调用就是直接调用就好。
连接池
数据库连接是非常宝贵的系统资源,但是我们每连接一次数据库,是需要走很多步,非常消耗资源的,如果我们每一次需要使用的时候才去创建数据库连接,用完之后将之关闭,会非常消耗资源,影响效率的,我们就可以使用连接池来解决这一问题。
系统初始运行时,主动建立足够的连接,组成一个池,每次应用程序,请求数据库连接时,无需重新打开连接,而是从池中取出已有的连接,使用完不在关闭,而是归还池中。
1. 导包
这里我们使用dbcp来介绍,首先按照我上面的方法导入dbcp的jar包,dbcp会依赖pool包,用pom.xml导出dbcp后会将两个包都导出。如图所示。
2. 使用连接池创建连接
在properties中可以加上一下内容:
初始化连接池
获取配置信息,将信息赋予连接池。
接下来就是调用连接,和上面调用连接一样,就不再赘述。
Statement和PreparedStatement
Statement主要用于执行静态SQL语句,即内容固定不变的SQL,如DDL语句。每执行一次都要对传入的SQL编译一次,效率很差,某些情况下SQL语句只是其中的参数不同,其余子句完全相同,每次都编译就很不理想,因此就可以使用preparedStatement
PreparedStatement可以预防SQL注入攻击。
PreparedStatement是接口,继承于Statement。语句中可以包含动态参数“?”,在执行时可以为“?”动态设置参数值。
数据库是不认识SQL语句的,需要将SQL语句编译成执行计划。
事务
什么是事务
事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。即我们将一系列操作看作一个事务,当这些操作全部顺利执行了就提交了,表示这件事情成功完成了,否在,只要其中一个操作失败,都会回滚掉整个流程。
事务的四大特征
(1)原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
(2)一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
(3)隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。
(4)持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中。
事务相关API
conn.setAutoCommit(false);//开启事务 取消自动提交
conn.commit();//提交事务
conn.rollback();//回滚事务
JDBC批处理
将一组SQL发送给数据库执行,一般是DML语句。
相关API
addBatch(String sql);将Sql语句添加到statement的命令列表中
addBatch();将Sql语句添加到preparedstatement的命令列表中
executeBatch();//将statement或preparedStatementde的命令列表中所有sql语句发送给数据库
clearBatch();//清空当前sql命令列表
结束语
本来是打算好好写完整的,不过确实没有那么多时间了,就先这样吧。本文涉及到了我以前培训时用到的相关资料, 我想应该没问题把,如果有问题,请联系我。
参考页面
https://blog.csdn.net/jungle_rao/article/details/81274720