其实写这些是因为最近在看spring事务,跟着就追溯到了JDBC上,工作中全都是使用各种封装好的方法,真正原始的方法也忘得也差不多了,就自己跟着被人的文章边看边自己记录一下,增强一起对jdbc的理解。
自己只写了创建连接到执行sql获取结果的整个过程,想了解更多的可以看这篇文章:
https://blog.csdn.net/qq_22172133/article/details/81266048
什么是JDBC
JDBC(Java DataBase Connectivity),是一套面向对象的应用程序接口(API),制定了统一的访问各类关系数据库的标准接口,为各个数据库厂商提供了标准的实现。通过JDBC技术,开发人员可以用纯Java语言和标准的SQL语句编写完整的数据库应用程序,并且真正地实现了软件的跨平台性。
我们在最开始学习java连接数据库时,应该都导入过一个jar包 mysql-connector-java-8.0.14.jar,这就是用于连MySQL接数据库的jdbc驱动;DriverManager就是驱动管理器;
DriverManager:负责加载各种不同驱动程序(Driver),并根据不同的请求,向调用者返回相应的数据库连接(Connection)。Driver:驱动程序,会将自身加载到DriverManager中去,并处理相应的请求并返回相应的数据库连接(Connection)。Connection:数据库连接,负责与进行数据库间通讯,SQL执行以及事务处理都是在某个特定Connection环境中进行的。可以产生用以执行SQL的Statement。Statement:用以执行SQL查询和更新(针对静态SQL语句和单次执行)。PreparedStatement:用以执行包含动态参数的SQL查询和更新(在服务器端编译,允许重复执行以提高效率)。CallableStatement:用以调用数据库中的存储过程。SQLException:代表在数据库连接的建立和关闭和SQL语句的执行过程中发生了例外情况(即错误)。
-
加载数据库驱动
Class.forName(com.mysql.jdbc.Driver);
-
建立连接
-
数据库url
URL用于标识数据库的位置,通过URL地址告诉JDBC程序连接哪个数据库;
常用数据库URL地址的写法:
Oracle:jdbc:oracle:thin:@localhost:1521:test
SqlServer:jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=test
MySql:jdbc:mysql://localhost:3306/test
-
Connection
jdbc程序中的Connection代表数据库的连接,客户端和数据库所有的交互都是通过connection对象完成;
Connection conn = DriverManager.getConnection(url,user,pwd);
Connection接口常见的方法:
方法 描述 createStatement():Statement 创建向数据库发送sql的statement对象。 prepareStatement(sql): PreparedStatement 创建向数据库发送预编译sql的PrepareSatement对象。 prepareCall(sql): CallableStatement 创建执行存储过程的callableStatement对象。 setAutoCommit(boolean autoCommit): void 设置事务是否自动提交。 commit(): void 在连接上提交事务。 rollback(): void 在此连接上回滚事务。 close(): void 关闭数据库连接
-
-
执行sql
-
Statement
创建Statement对象用来发送sql;
Statement state = conn.createStatement();
常用方法:
方法 描述 executeQuery(String sql) : ResultSet 用于向数据发送查询语句。 executeUpdate(String sql): int 用于向数据库发送更新语句 execute(String sql):boolean 用于向数据库发送任意sql语句 addBatch(String sql):void 把多条sql语句放到一个批处理中。 executeBatch():int[] 向数据库发送一批sql语句执行。 发送sql语句过程:
Connection conn = DriverManager.getConnection(url,user,pwd); Statement state = conn.createStatement(); state.executeQuery("select * from user);
-
PreperedStatement
PreperedStatement作用其实和statement一样的,但是它可以对sql语句进行预编译,提高sql执行效率,避免sql的注入问题;
对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写;
PreperedStatement st = conn.preparedStatement();
发送sql语句过程:
String sql = "select * from user where name=? and password=?"; //获取用于向数据库发送sql语句的Preperedstatement PreperedStatement st = conn.preparedStatement(sql);//进行预编译 st.setString(1, username); st.setString(2, password); //向数据库发sql ResultSet result = st.executeQuery();
-
-
返回结果
-
ResultSet类用于代表Sql语句的执行结果。Resultset封装执行结果时,采用的类似于表格的方式,ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。
-
获取方法
获取行:
- next():移动到下一行
- Previous():移动到前一行
- absolute(int row):移动到指定行
- beforeFirst():移动resultSet的最前面。
- afterLast() :移动到resultSet的最后面。
获取值:
- getObject(int index)
- getObject(string columnName)
- getString(int index)
- getString(String columnName)
-
输出具体数据:
//循环取出(id) while(rs.next()) { String id=rs.getString(1);//1代表数据库中表的列数 System.out.println(id+" "); }
-
-
释放资源
释放资源就不用说了,在finally语句中判断各个对象是否为null,不为null则执行close()方法;
最后
我们可以看到,每创建一个连接和执行完sql语句前后,都是需要去注册驱动,获取连接,关闭连接。其实这些操作都是重复的,所以我们可以创建一个工具类,专门用来实现这些重复的操作。
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
//初始化数据源
static{
try{
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties prop = new Properties();
prop.load(in);
driver = prop.getProperty("driver");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
Class.forName(driver);
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
//创建conn
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url, username,password);
}
//释放资源
public static void release(Connection conn,Statement st,ResultSet rs){
if(rs!=null){
try{
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try{
st.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}