相信对于初入IT行业的初学者来说,不论是学Java还是学C++,又或者其他语言,都或多或少都听过或是了解过数据库。在日常的生活中,数据库的应用也是随处可见,比如银行的转账系统,各大电信运营商,企业公司的办公自动化系统等,都有他们各自的数据库。可以说基本上的项目开发都用到了数据库,因此数据库的开发设计也成软件开发中一种必备的技能,是衡量一名合格程序员的重要指标。
而实际中,我们很少直接在数据库进行操作,比如数据库的增删改查等。对于Java程序员来说,一般都是通过Java程序来间接操作数据库。而JDBC就是Java程序与数据库通信的标准API(Application Programming Interface应用程序编程接口),实质上就是Java操作数据库是的一种规范。说的通俗形象点,JDBC就是一座架在Java程序和数据库之间的桥梁。Java程序可以通过JDBC来实现与数据库的交互。在使用JDBC操作数据库时,我们需要一个数据库的驱动程序,这个驱动是由相应的数据库厂商提供的。如果是mysql数据库就要用mysql的驱动,oracle数据库就要用oracle驱动,这是相匹配的。
接下来我们开始讲述JDBC的具体操作。
准备运行环境和开发工具
运行环境:JDK1.7
Tomcat7.0
开发工具: Myeclipse2015
Oracle11.2g
再说JDBC操作前,我们先来知道JDBC中一些常用的API
1、Connection接口(java.sql.Connection)
2、DriverManager类(java.sql.DriverManager)
3、Statement接口(java.sql.Statement)
4、PreparedStatement(java.sql.PreparedStatement)
5、ResultSet接口(java.sql.ResultSet)
步骤一:1、JDBC连接数据库
思路很简单,想要操作数据库,必定要先连接到数据库,建立两者间的通信桥梁,有了桥梁才可以进行信息交互。
在连接前我们需要准备一些连接环境工作。
首先先建立一个java项目,我的项目名是JDBCTest1
接下来需要先添加Oracle驱动库。先在项目中新建一个oracle包,然后将oracle驱动包加入该包中。
如图
然后右击项目选择Build Path 点击Configure Build Path
然后出现该界面
点击Add Library
选择User Library,点击Next
点击User Libraries…
然后
当出现如上的图标时,就代表驱动应用库建成了。
到此连接的环境搭建好了,接下来新建一个DBUtil类,可以把这个类定义为数据库工具类,所在包名为com.java.jdbc.uitl
接下来我们开始在这个数据库工具类中编写连接数据库代码:
因为要连接数据库,我们得用到数据库驱动,所以首先得加载数据库驱动,注册到驱动管理器,语法如下:
Class.forName(DriverName);
DriverName:是所加载的驱动名是字符串类型
加载驱动后,我们就需要真正构建连接了,语法如下:
DrvierManager.getConnection(url, username, password);
DriverManager:驱动管理器,主要用于驱动连接。
url:数据库连接路径,这个路径是由数据库厂商制定,不同数据库,url不同。
username:数据库的用户名,可以通过该用户名登入数据库。
password:数据库用户名的登入密码。
好了,了解连接数据库的两个主要方法后,我们来看看具体示例。
第一种写法(推荐的写法):
package com.java.jdbc.util;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class DBUtil {
// 驱动名
private static String driver;
// 数据库连接路径
private static String url;
// 数据库用户名
private static String uname;
// 用户名密码
private static String upass;
// 连接对象
private static Connection con;
// 通过静态代码块初始化对象,获取相关数据
static {
// 通过Properties对象来获取配置信息,实质上就是HashTable用键值对的方式存取信息
Properties p = new Properties();
try {
/* getResourceAsStream()返回一个字节输入流InputStream, Class.getClassLoader.getResourceAsStream(String path):默认从ClassPath根下获取
db.properties配置文件放置在src源码包下面
*/ p.load(DBUtil.class.getClassLoader().getResourceAsStream(
"db.properties"));
// 从db.properties文件中获取相关数据
driver = p.get("driver").toString();
url = p.get("url").toString();
uname = p.get("uname").toString();
upass = p.get("upass").toString();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获得连接对象
*/
public static Connection getCon() {
try {
// 1. 加载驱动
Class.forName(driver);
// 2. 通过驱动管理器获得连接对象
if (null == con)
// 加上线程同步
synchronized (new String()) {
if (null == con){
con = DriverManager.getConnection(url, uname, upass);
System.out.println("数据库连接成功");
}
}
} catch (ClassNotFoundException e) {
System.out.println("数据库连接失败");
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
}
我的db.properties配置信息是如下:
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
uname=……
upass=……
uname和upass根据自己数据库连接的用户名和密码而定
第二种写法(不用配置信息,直接将信息写在代码中)
private static String driver=”oracle.jdbc.driver.OracleDriver”;
// 数据库连接路径
private static String url=”jdbc:oracle:thin:@localhost:1521:orcl”;
// 数据库用户名
private static String uname=”…”;
// 用户名密码
private static String upass=”…”;
若是用这种方法可以将第一种方法中的静态代码块删除static{},但是这种代码是一种死代码,高度耦合的代码,扩展性极差。而配置文件的话,我们只需修改配置文件中的信息,就可以达到动态变换数据库或是用户,简单方便,极具扩展性。
到此,数据库的连接已经完成,接下来做个测试:
步骤二:数据库的基本操作(增删改查)
先从简单入手,我就在测试类中实现类增删改查。这肯定是不可取的,之后我会在另外的例子中详细说明。
package com.java.jdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.java.jdbc.util.DBUtil;
public class ThreeTest {
Connection conn = DBUtil.getCon();
public static void main(String[] args) {
//建表
String createTableSql = "CREATE TABLE USER1(USERID INT, USERNAME VARCHAR2(50))";
//删表
String deletTableName = "USER1";
//添加数据
String insertSql = "INSERT INTO USER1 VALUES(1, '王五')";
//查询数据
String selectSql = "SELECT * FROM USER1";
//修改数据
String updateSql = "UPDATE USER1 SET USERNAME = '张三' WHERE USERID = 1";
//删除数据
String deleteSql = "DELETE FROM USER1";
ThreeTest tt = new ThreeTest();
/*
* PreparedStatement
* int executeUpdate(String sql)
* 返回值具体含义:
* (1) 对于 SQL 数据操作语言 (DML) 语句,既是数据的增删改查,返回行计数
* (2) 对于不返回任何内容的 SQL 语句,比如建表,删表,返回 0
*/
//删表
int lines = tt.deleteTable(deletTableName);;
//添表
lines = tt.createTable(createTableSql);
lines = tt.update(insertSql);
System.out.println("添加数据:" + lines);
//查询结果集
ResultSet res = tt.select(selectSql);
try {
while(res.next()){
//打印
System.out.println("查询数据: userid:" + res.getInt("USERID") + " " + "username:" + res.getString("USERNAME"));
}
} catch (SQLException e) {
e.printStackTrace();
}
//修改
lines = tt.update(updateSql);
System.out.println("修改数据:" + lines);
//删除数据
lines = tt.update(deleteSql);
System.out.println("删除数据:" + lines);
}
/**
* 增删改
* @param sql
* @return
*/
public int update(String sql){
int lines = -1;
try {
PreparedStatement pstate = conn.prepareStatement(sql);
lines = pstate.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
return lines;
}
/**
* 查询
* @param sql
* @return
*/
public ResultSet select(String sql){
ResultSet res = null;
try {
PreparedStatement pstate = conn.prepareStatement(sql);
res = pstate.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return res;
}
/**
* 删除表
* @param tableName
* @return
*/
public int deleteTable(String tableName){
int lines = -1;
String sql = "DROP TABLE " + tableName;
try {
PreparedStatement pstate = conn.prepareStatement(sql);
lines = pstate.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
if(lines >= 0)
System.out.println("删除表成功:" + lines);
return lines;
}
/**
* 建表
* @return
*/
public int createTable(String sql){
int lines = -1;
try {
PreparedStatement pstate = conn.prepareStatement(sql);
lines = pstate.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
if(lines >= 0)
System.out.println("创建表成功:" + lines);
return lines;
}
}
结果如下:
到此我们就把基本的数据库操作完成了。
接下来对程序做一些简单分析:
Connection接口主要两个作用
1、获取连接
Connection conn = DBUtil.getCon();
2、获取PreparedStatement对象,同时对sql预编译
PreparedStatement pstate = conn.prepareStatement(sql);
PreparedStatement接口用于执行各种数据库操作
int lines = pstate.executeUpdate();
通过lines来判断数据库操作是否成功。此处需注意lines的返回值根据操作不同,会有所不同。如果是操作DML语句(数据的增删改查),返回行计数。若是DDL语句(建表,删表等),则返回0;
ResultSet res = pstate.executeQuery();
执行数据库查询会返回一个结果集,所有的查询结果都在结果集中。
需要遍历结果集才能获取其中的数据。
对于输出结果有一个地方需要注意的是,我是先删除表成功,在创建表的,之前做了个测试,所以数据库中已经存在表,如果不先删除,创建相同的表,就会报错。对于还未建表的你们,可以把删除表的语句放在程序最后执行。
说到这,JDBC最基本的数据库操作基本完成,对于初学者应该对JDBC有了一个笼统的了解。
但是这个程序代码还存在许多不足,比如代码重复高,数据库连接关闭,设计上的问题等。