系列文章
java系列JDBC的使用
JDBC的使用
前言
JDBC 提供了数据库访问的API,为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。不必为访问MySql数据库专门写一个程序,为访问Oracle数据库又专门写一个程序,或为访问SqlServer数据库又编写另一个程序等等。程序员只需用JDBC API写一个程序就够了,它可向相应数据库发送SQL调用。
JDBC可做三件事:与数据库建立连接、执行SQL 语句、处理结果。
一、JDBC是什么?
Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。
二、工作原理
1、数据库驱动
我们安装好数据库之后,我们的应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数据库打交道。其实也就是数据库厂商的JDBC接口实现,即对Connection等接口的实现类的jar文件。
2、Driver Manager
管理各种不同的JDBC驱动。在编程中要连接数据库,必须先装载特定厂商的数据库驱动程序,不同的数据库有不同的装载方法,Driver Manager实现了不现数据库驱动程序的加载。
3、JDBC API
供程序员调用的接口与类,集成在java.sql和javax.sql包中,如:
连接数据库:Connection接口。
为数据库传递查询和更新指令:Statement接口。
处理数据库响应并返回的结果:ResultSet接口。
三、使用步骤
1.加载驱动
使用maven仓库加载驱动
mvn install:install-file -Dfile=ojdbc6-11.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.1 -Dpackaging=jar -DgeneratePom=true
oracle官方驱动下载地址
oracle官方驱动下载地址
https://www.oracle.com/cn/database/technologies/enterprise-edition/jdbc.html
【语法】
Class.forName(driverClass)
【示例】加载驱动
//加载MySql驱动
Class.forName("com.mysql.jdbc.Driver")
//加载Oracle驱动
Class.forName("oracle.jdbc.driver.OracleDriver")
//加载SqlServer驱动
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
2.获取连接
【语法】
DriverManager.getConnection(URL,用户名,密码);
【说明】
Connection接口与特定数据库的连接(会话),在连接上下文中执行sql语句并返回结果。DriverManager.getConnection(url, user, password)方法建立在JDBC URL中定义的数据库Connection连接上。
createStatement():创建向数据库发送sql的statement对象。
prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
prepareCall(sql):创建执行存储过程的callableStatement对象。
setAutoCommit(boolean autoCommit):设置事务是否自动提交。
commit() :在链接上提交事务。
rollback() :在此链接上回滚事务。
URL:数据库的连接地址。
URL:连接协议://IP地址:端口号/数据库名?参数名=参数值
【示例】
//连接MySql数据库
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "user", "password");
//连接Oracle数据库
Connection conn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:database", "user", "password");
//连接SqlServer数据库
Connection conn =
DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=database", "user", "password");
3.发送SQL语句
【语法】
连接.createStatement();
连接.prepareStatement(sql);
【说明】
Statement:由createStatement创建,用于发送简单的SQL语句(不带参数)。
PreparedStatement :继承自Statement接口,由preparedStatement创建,用于发送含有一个或多个参数的SQL语句。
PreparedStatement对象比Statement对象的效率更高,并且可以防止SQL注入,所以我们一般都使用PreparedStatement。
【示例】使用PreparedStatement发送SQL
/*
PreparedStatement 有效的防止sql注入
(SQL语句在程序运行前已经进行了预编译,当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符如 or '1=1'也数据库会作为一个参数一个字段的属性值来处理而不会作为一个SQL指令)
*/
String sql = "insert into t_user (u_name,u_pwd) values(?,?)";
PreparedStatement ps = conn.preparedStatement(sql);
ps.setString(1, "admin"); //占位符顺序从1开始
ps.setString(2, "123456"); //也可以使用setObject
ps.executeUpdate(); //发送SQL
4.处理结果
【说明】
Statement发送查询句后,会得到一个结果集,用ResultSet接口接收返回的结果集,并进行处理。
ResultSet提供检索不同类型字段的方法,常用的有:
getString(int index)、getString(String columnName):获得在数据库里是varchar、char等类型的数据对象。
getFloat(int index)、getFloat(String columnName):获得在数据库里是Float类型的数据对象。
getDate(int index)、getDate(String columnName):获得在数据库里是Date类型的数据。
getBoolean(int index)、getBoolean(String columnName):获得在数据库里是Boolean类型的数据。
getObject(int index)、getObject(String columnName):获取在数据库里任意类型的数据。
ResultSet还提供了对结果集进行滚动的方法:
next():移动到下一行 Previous():移动到前一行
absolute(int row):移动到指定行 beforeFirst():移动resultSet的最前面。 afterLast():移动到resultSet的最后面。
【示例】查询结果处理
String sql = "select u_name,u_pwd from t_user";
PreparedStatement ps = conn.preparedStatement(sql);
ResultSet rs=ps.executeQuery();//发送SQL语句并得到返回结果集
//rs.next()为假,结果集遍历完成
while(rs.next()){
String name=rs.getString(1); //取结果集列的值
String pwd=rs.getString(2);//取结果集列的值
}
5.释放资源
【说明】
使用后依次关闭对象及连接:ResultSet → Statement → Connection
### 【示例】释放资源
if(rs!=null) rs.close();//关闭ResultSet
if(ps!=null) ps.close();//关闭Statement
if(conn!=null) conn.close();//关闭Connection
代码
java1.8连接Oracal
package com.atm.utils;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* @BelongsProject:
* @BelongsPackage:
* @Author: 系凌乱鹅
* @CreateTime: 2022-06-24 14:47
* @Description: TODO
* @Version: 1.0
*/
public class JdbcUtil {
public static String url = "jdbc:oracle:thin:@localhost:1521:orcl";
public static String user = "scott";
public static String password = "root";
public static String driver = "oracle.jdbc.driver.OracleDriver";
/**
* @description: 加载驱动,连接数据库
* @author: 系凌乱鹅
* @date: 2022/6/21 15:03
* @param: []
* @return: java.sql.Connection
**/
private static Connection getConnection() throws Exception {
// 1.加载驱动
Class.forName(driver);
// 2.连接数据库
return DriverManager.getConnection(url, user, password);
}
/**
* @description: 从数据库取到的数据对应到java的数据类型
* @author: 系凌乱鹅
* @date: 2022/6/21 15:03
* @param: [field, rs, colnum]
* @return: java.lang.Object
**/
private static Object getValue(Field field, ResultSet rs, Integer colnum) throws Exception {
// 按需完善
if (field.getType() == Integer.class) {
return rs.getInt(colnum);
} else if (field.getType() == String.class) {
return rs.getString(colnum);
} else if (field.getType() == Double.class) {
return rs.getDouble(colnum);
} else {
return rs.getObject(colnum);
}
}
/**
* @description:用来查询,返回的list存储查询结果
* @author: 系凌乱鹅
* @date: 2022/6/21 15:02
* @param: [sql, cls, params]
* @return: java.util.List<T>
**/
public static <T> List<T> list(String sql, Class<T> cls, Object... params) {
List<T> list = new ArrayList<>();
Connection conn = null;
ResultSet rs = null;
PreparedStatement st = null;
try {
conn = getConnection();
st = conn.prepareStatement(sql);
// 设置参数
for (int i = 0; i < params.length; i++) {
st.setObject(i + 1, params[i]);
}
rs = st.executeQuery(); // 用于查询语句
ResultSetMetaData rsMetaData = rs.getMetaData();
int columnNum = rsMetaData.getColumnCount();
// 拿到属性
Field[] fields = cls.getDeclaredFields();
while (rs.next()) {
// 利用反射new对象
T t = cls.newInstance();
//rs.getInt(1)
// 设置值
for (int i = 0; i < columnNum; i++) {
//
String lable = rsMetaData.getColumnLabel(i + 1);
for (Field field : fields) {
field.setAccessible(true);
if (field.getName().equalsIgnoreCase(lable)) {
field.setAccessible(true);
field.set(t, getValue(field, rs, i + 1));
// field.set(t,rs.getObject(i+1));
break;
}
}
}
list.add(t);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JdbcUtil.close(conn, st, rs);
}
return list;
}
/**
* @description:释放资源
* @author: 系凌乱鹅
* @date: 2022/6/21 15:31
* @param: [conn, st, rs]
* @return: void
**/
public static void close(Connection conn, Statement st, ResultSet rs) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
/**
* @description:增删改
* @author: 系凌乱鹅
* @date: 2022/7/2 16:47
* @param: [sql, params]
* @return: int
**/
public static int update(String sql, Object... params) {
Connection conn = null;
PreparedStatement st = null;
int num = 0;
try {
conn = getConnection();
st = conn.prepareStatement(sql);
// 设置参数
for (int i = 0; i < params.length; i++) {
st.setObject(i + 1, params[i]);
}
num = st.executeUpdate(); // 用于查询语句
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JdbcUtil.close(conn, st, null);
}
return num;
}
}
写稿不易,感谢支持!