JDBC连接数据库详解
不能不说有了各种ORM框架之后,最初使用JDBC连接数据库的方法也忘得差不多了,这不最近打算换份工作,所以就把该拾起的基础知识好好的看看,java基础也会写一个系列文章,大概的顺序就是就看目前工作中每天的感触了。希望本文能够帮助到刚好在关注JDBC的朋友。
使用JDBC连接数据库大概分为7步,先整体上看一个简单的例子,然后一步一步的进行讲解。
示例:
public classJdbcTest {
public static void main(String[] args) {
//数据库连接
Connectionconnection= null;
//预编译的Statement,使用预编译的Statement提高数据库性能
PreparedStatementpreparedStatement= null;
//结果集
ResultSetresultSet= null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//提供jdbc链接的url
Stringurl= "jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8";
//通过驱动管理类获取数据库链接
connection = DriverManager.getConnection(url, "root", "123456");
//定义sql语句 ?表示占位符
Stringsql= "select * from user where username =?";
//获取预处理statement
preparedStatement= connection.prepareStatement(sql);
//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setString(1,"cody");
//向数据库发出sql执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
//遍历查询结果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));
}
}catch(Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(resultSet!=null){
try {
//关闭记录集
resultSet.close();
}catch(SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
//关闭申明
preparedStatement.close();
}catch(SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
//关闭链接对象
connection.close();
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
}
详细讲解:
一、加载数据库驱动
在连接数据库之前,先得通过java.lang.Class类的静态方法forName(StringclassName)将想要连接的数据库的驱动加载到JVM(Java虚拟机)。
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
成功加载后,会将Driver类的实例注册到DriverManager类中。
二、提供JDBC链接URL
·连接URL:"jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8",其中定义了链接数据库时的协议、子协议、数据源标识。
·书写形式:协议:子协议:数据源标识
---协议:在JDBC中总是以jdbc开始
---子协议:是桥链接的驱动程序或是数据库管理系统名称
---数据源标识:标记找到数据库来源的地址与链接端口
其中,上文连接中characterEncoding=utf-8表示编码格式。
三、创建数据库的连接
要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。
使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和 密码来获得。
例如:
connection = DriverManager.getConnection(url, "root","123456");
四、创建jdbc statement对象
要执行sql语句,必须现货的java.sql.Statement实例,Statement实例分为以下3种类型:
---执行静态SQL语句:通过Statement实例实现
---执行动态SQL语句:通过PreparedStatement实例实现
---执行数据库存储过程:通过CallableStatement实例实现
具体的实现方式:
Statement stmt = con.createStatement() ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;
例如:
//定义sql语句 ?表示占位符
String sql = "select *from user where username = ?";
//获取预处理statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setString(1,"cody");
五、执行sql并获取结果
Statement接口提供了三种执行SQL语句的方法:executeQuery、executeUpdate和execute
---ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返回一个结果集(ResultSet)对象。
---int executeUpdate(String sqlString):用于执行INSERT、UPDATE或DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
--- boolean execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的语句。
例如:
//向数据库发出sql执行查询,查询出结果集
resultSet= preparedStatement.executeQuery();
六、处理结果
结果处理的两种方式:一执行更新返回本次操作影响的记录数;二执行查询返回的结果是一个ResultSet。
---ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些行中数据的访问
例如:
//遍历查询结果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));
}
也可以使用列的编号获取查询结果如resultSet.getString(1),列的编号从左往右从1开始编,同时这种方法的执行效率更高。
七、释放资源(resultSet、preparedstatement、connection)
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声 明顺序相反:
---关闭记录集
---关闭声明
---关闭连接对象
例如:
//释放资源
if(resultSet!=null){
try{
//关闭记录集
resultSet.close();
}catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try{
//关闭申明
preparedStatement.close();
}catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try{
//关闭链接对象
connection.close();
}catch (SQLException e) {
e.printStackTrace();
}
}
其实,整个的过程看完之后就能立刻想到为什么我们需要使用框架了,因为如下:
1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
2、 Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。