什么是jdbc?
全称java data base connectivity, java数据库连接。是一种执行sql语句的java API,可以为多种关系数据库提供统一访问,它是由一组用java语言编写的类和接口组成。
为什么要用jdbc?
运用jdbc就不必为访问不同数据库专门写程序了。只需要用jdbc API就过了。将Java语言和JDBC结合起来使程序员不必为不同的平台编写不同的应用程序,只须写一遍程序就可以让它在任何平台上运行,这也是Java语言编写一次,处处运行”的优势。
怎样使用jdbc?
既然jdbc这么好用?哪要怎样去使用它, 首先需要向项目中导入jdbc驱动。将驱动包导入到工程中之后,接下来就是与数据库连接的6个步骤了。
- 第一步加载驱动类
try {
Class.forName("oracle.jdbc.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
java中通过class.fromName()方法来加载驱动类,由于每种数据库的驱动包不一样所以它们的驱动类也是不一样的,但这个方法它会抛出一个classNotFoundException找不到类异常,所以我们需要捕获它或者是抛出这个异常
- 第二步 连接数据库
try {
Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@//localhost:1521/orcl","system","12345678");
} catch (SQLException e) {
e.printStackTrace();
}
这步是Java与数据的连接,通过DriverManager的getConnection()方法连接,而getConnection()方法中有三个参数分别是有数据库连接的url,每种数据库的URL是不一样的,第二个是参数是登陆数据库是的用户名,第三个参数是在登陆数据库是的密码。同时这个我方法也会抛出一个SQLException。
*第三步发送sql请求
PreparedStatement statement = connection.prepareStatement(sql);
通过第二步创建的connection对象的prepareStatement()方法返回一个 statement对象。
- 第四步执行sql代码
ResultSet resultSet = statement.executeQuery();
int row = statement.executeUpdate();
通过第三步返回的statement对象的executeQuery()的方法执行查询语句返回的是一个int类型的结果,也就是影响的行数,statement的executeUpdate()的方法执行增删改,返回的算是一个结果集,这个结果集就是从数据库中查询到的数据
- 处理结果
当我们返回的是一个结果集的时候,我们需要通过一个循环来打印这几个数据:
while (resultSet.next()){
int newId = resultSet.getInt(1);
String title = resultSet.getString(2);
}
如果返回的结果集它有下一项的话,就通过结果集对象的getInt等方法来打印这个结果,而这个方法中的参数是第几列或者是该列的列名。
如果返回的是一个int类型的话,说明执行的是数据库的增、删、改操作这样我们只需要判断这个int类型的书是否是大于0,如果他大于0则说明操作执行成功。否则执行失败。
- 关闭数据库连接
try {
if (rs != null)
rs.close();
if (st != null)
st.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
最后要关闭数据库连接,要注意的是数据库的连接时有内向外关闭的,也就是说自开始创建的对象最后关闭,而最后创建的对象,最先关闭。
这样就实现了与数据库的连接。当我们有很多程序都需要与数据库建立连接的话,每个程序我们都需要这样写而且有大量的重复代码,是一件很麻烦的事。
有什么方法可以解决中这个问题呢?
我们可以对一些重复的代码进行封装,这样我们每次要对数据库进行操作的时候我们调用就可以了
public class DBUtils {
// 驱动程序类
private static final String DB_DRIVER = "oracle.jdbc.OracleDriver";
// 数据库连接字符串
private final static String DB_URL = "jdbc:oracle:thin:@localhost:1521:orcl";
// 数据库账户名
private static final String DB_ACCT = "system";
// 数据库密码
private static final String DB_PWD = "12345678";
// 静态块中加载数据库驱动
static {
try {
Class.forName(DB_DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接
*
* @return Connection据库连接
*/
public static Connection getConn() {
try {
return DriverManager.getConnection(DB_URL, DB_ACCT, DB_PWD);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 执行查询操作
*
* @param sql
* 查询SQL语句
* @param args
* SQL语句 参数
* @return 返回查询结果
*/
public static Map<String, Object> query(String sql, Object... args) {
Connection conn = getConn();// 获取数据连接
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
// 设置参数
for (int i = 0; i < args.length; i++) {
if (args[i] != null)
pst.setObject(i + 1, args[i]);
}
// 执行查询语句
rs = pst.executeQuery();
if (rs.next()) {
return rsToMap(rs);
}
return null;
} catch (Exception e) {
e.printStackTrace();
} finally {
close(conn, pst, rs);
}
return null;
}
/**
* 执行查询操作
*
* @param sql
* 查询SQL语句
* @param args
* SQL语句 参数
* @return 返回查询结果
*/
public static List<Map<String, Object>> list(String sql, Object... args) {
Connection conn = getConn();// 获取数据连接
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
// 设置参数
for (int i = 0; i < args.length; i++) {
if (args[i] != null)
pst.setObject(i + 1, args[i]);
}
// 执行查询语句
rs = pst.executeQuery();
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
while (rs.next()) {
Map<String, Object> map = rsToMap(rs);
list.add(map);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
close(conn, pst, rs);
}
return null;
}
/**
* 执行增删改操作
*
* @param sql
* 增删改SQL语句
* @param args
* SQL语句 参数
* @return 返回是否执行成功
*/
public static boolean update(String sql, Object... args) {
PreparedStatement pst = null;
Connection conn = null;
try {
conn = getConn();// 获取数据库连接
pst = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
if (args[i] != null)
pst.setObject(i + 1, args[i]);
}
int row = pst.executeUpdate();
return row > 0;
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(conn, pst, null);
}
return false;
}
/**
* 关闭连接释放资源
*
* @param conn
* 数据库连接
* @param st
* Statement对象
* @param rs
* ResultSet 结果集
*/
public static void close(Connection conn, Statement st, ResultSet rs) {
try {
if (rs != null)
rs.close();
if (st != null)
st.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 将结果集转换成Map
*
* @param rs
* 结果集
* @return map
* @throws SQLException
*/
public static Map<String, Object> rsToMap(ResultSet rs) throws SQLException {
Map<String, Object> map = new HashMap<String, Object>();
// 获取结果集的元信息(列名,列类型,大小,列数量等等)
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();// 获取结果集中的列的数量
for (int i = 1; i <= count; i++) {
// 根据列的下标获取列名称
String columnName = rsmd.getColumnName(i);
Object value = rs.getObject(i);
map.put(columnName.toLowerCase(), value);
}
// map.get("uname");
return map;
}
首先将数据库的连接的驱动包和url等定义为静态的常量这样就可以直接写了;然后再将加载驱动类的方法静态代码块中这样当程序调用的时候就会加载这个方法;然后在定义一个与数据库连接的方法返回值为connection,这样就可以数据库进行操作了,定义一个当个查询的方法,返回一个Map集合,这样就可以通过Map集合来存取数据了,数据库中的列名是Map集合的键而查询到的数据为值;在定义一个查询多条数据的方法,返回一个List集合,在List集合里面的嵌套以个Map集合,这样就可以对多条数据进行存取了;在定义一个增删改的方法,因为它们返回的都是sql语句在数据库所影响的行数所以可以定义成一个方法,只需要返回以boolean类型的来判断是否执行成功。这样就这个工具类就完成了。