1、概述

JDBC(Java DataBase Connectivity) 是 Java 提供的用于执行 SQL 语句一套 API,可以为多种关系型数据库提供统一访问,由一套用 Java 语言编写的类和接口组成。

有了这套接口之后,开发者就不必为每一种数据库编写不同的访问逻辑,只需要在项目中加入数据库厂商提供的 JDBC 驱动,然后面向这套 Java API 接口开发自己的程序即可。

也就是说,在没有使用某个数据库特有语法、函数的情况下,开发者只要替换数据库驱动包、修改连接配置文件即可在应用层实现数据库的替换。

这就是面向接口编程的优势所在。

JDBC最核心的几个接口

Connection 与特定数据库的连接,SQL语句在这个连接上执行并返回结果
Statement 静态SQL语句对象
PreparedStatement 预编译的SQL语句对象
ResultSet 表示数据库结果集的数据表,通常通过执行查询数据库的语句生成

2、第一个 demo

环境:JDK 1.6 + mysql 5.5

首先创建一个 java 项目 jdbc_demo

导入 mysql-connector-java-5.1.26-bin.jar,这个数据库驱动可以到 http://mvnrepository.com 下载,关于 eclipse 的导包可以参考 http://5ijy01.duapp.com/it/java/java01046.html#f2-7

创建 package 和测试类,如下:

编写代码连接本地 MySQL 查询 test 下 t_user 表的数据

 String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false";
String username = "root";
String password = "123456"; Class.forName(driver); Connection conn = null;
Statement stmt = null;
ResultSet rs = null; try {
conn = DriverManager.getConnection(url, username, password); stmt = conn.createStatement();
rs = stmt.executeQuery("select id, username, role_id from t_user"); while (rs.next()) {
int id = rs.getInt(1);
String uname = rs.getString("username");
int roleId = rs.getInt(3);
System.out.println("用户信息: id=" + id + ", username=" + uname + ", role_id=" + roleId);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (conn != null)
conn.close();
if (stmt != null)
stmt.close();
if (rs != null)
rs.close();
} catch (SQLException e) {
}
}

代码解读

url 是数据库连接地址,它告诉数据库驱动数据库服务器的 IP地址、服务监听端口、使用的数据库以及连接配置参数,这个 url 的配置方式通常在数据库文档中可以找到

Class.forName(driver) 这行代码的作用是加载数据库驱动类

下面的代码就比较简单了:使用 DriverManager 获取一个数据库连接 Connection 对象、从连接创建 Statement 对象,然后执行语句获取 ResultSet 结果集,最后迭代结果集获取数据

需要注意的是:我们使用 finally 代码块关闭数据库连接资源,因为不论 try 代码块是否捕获到异常, finally 代码块都会执行

3、API

Connection 的核心方法
void close() 释放Connection对象的数据库和JDBC资源
void commit() 提交所有更改,并释放Connection对象当前持有的所有数据库锁
Statement createStatement() 创建一个Statement对象来将SQL语句发送到数据库
PreparedStatement prepareStatement(String sql) 创建一个PreparedStatement对象来将参数化的SQL语句发送到数据库
void rollback() 取消当前事务中进行的所有更改,并释放Connection对象当前持有的所有数据库锁
void setAutoCommit(boolean autoCommit) 设置是否自动提交
void setReadOnly(boolean readOnly) 设置为只读模式,作为驱动程序启用数据库优化的提示
void setTransactionIsolation(int level) 试图将此Connection对象的事务隔离级别更改为给定的级别
Statement 的核心方法
void addBatch(String sql) 将给定的SQL命令添加到Statement对象的当前命令列表中
void close() 释放Statement对象的数据库和JDBC资源,而不是等待该对象自动关闭时发生此操作
boolean execute(String sql) 执行给定的SQL语句,该语句可能返回多个结果
int[] executeBatch() 将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组
ResultSet executeQuery(String sql) 执行给定的SQL语句,该语句返回单个ResultSet对象
int executeUpdate(String sql) 执行给定SQL语句,该语句可能为INSERT、UPDATE或DELETE语句,或者不返回任何内容的SQL语句(如DDL语句)
ResultSet 的核心方法
void close() 释放ResultSet对象的数据库和JDBC资源
BigDecimal getBigDecimal(int columnIndex) 以具有全精度的java.math.BigDecimal的形式获取此ResultSet对象的当前行中指定列的值
BigDecimal getBigDecimal(String columnLabel) 以具有全精度的java.math.BigDecimal的形式获取此ResultSet对象的当前行中指定列的值
Date getDate(int columnIndex) 以java.sql.Date对象的形式获取此ResultSet对象的当前行中指定列的值
Date getDate(String columnLabel) 以java.sql.Date对象的形式获取此ResultSet对象的当前行中指定列的值
double getDouble(int columnIndex) 以double的形式获取此ResultSet对象的当前行中指定列的值
double getDouble(String columnLabel) 以double的形式获取此ResultSet对象的当前行中指定列的值
int getInt(int columnIndex) 以int的形式获取此ResultSet对象的当前行中指定列的值
int getInt(String columnLabel) 以int的形式获取此ResultSet对象的当前行中指定列的值
ResultSetMetaData getMetaData() 获取此ResultSet对象的列的编号、类型和属性
Object getObject(int columnIndex) 以Object的形式获取此ResultSet对象的当前行中指定列的值
Object getObject(String columnLabel) 以Object的形式获取此ResultSet对象的当前行中指定列的值
String getString(int columnIndex) 以String的形式获取此ResultSet对象的当前行中指定列的值
String getString(String columnLabel) 以String的形式获取此ResultSet对象的当前行中指定列的值
Timestamp getTimestamp(int columnIndex) 以java.sql.Timestamp对象的形式获取此ResultSet对象的当前行中指定列的值
Timestamp getTimestamp(String columnLabel) 以java.sql.Timestamp对象的形式获取此ResultSet对象的当前行中指定列的值
boolean next() 将光标从当前位置向前移一行

4、编写 DBUtil 连接工具类

在一个项目里面,会有很多的业务需要访问数据库,如果每次都使用上面的方式获取连接,代码写起来会很麻烦,而且不便于维护

所以我们可以把加载驱动、获取连接的代码提取出来,单独封装成一个工具类,对外只提供一个 getConnection() 的方法来获取连接

jdbc.properties 配置文件

首先,在 src 下添加 jdbc.properties 配置文件,主要配置 driverurlusernamepassword 等连接参数

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
username=root
password=123456

然后,编写 DBUtil 类

 public class DBUtil {

     private static String driver;
private static String url;
private static String username;
private static String password; private static Properties prop = new Properties(); static {
try {
prop.load(DBUtil.class.getClassLoader().getResourceAsStream(
"jdbc.properties")); driver = prop.getProperty("driver");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password"); Class.forName(driver); } catch (IOException e) {
throw new RuntimeException("加载JDBC配置失败", e);
} catch (ClassNotFoundException e) {
throw new RuntimeException("加载JDBC配置失败", e);
}
} public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
}

最后,编写 JdbcDemo2 测试类

 Connection conn = null;
Statement stmt = null;
ResultSet rs = null; try {
// 获取连接
conn = DBUtil.getConnection(); stmt = conn.createStatement();
// 执行查询并获取结果集
rs = stmt.executeQuery("select id, username, role_id from t_user"); // 遍历结果集
while (rs.next()) {
int id = rs.getInt(1);
String uname = rs.getString("username");
int roleId = rs.getInt(3);
System.out.println("用户信息: id=" + id + ", username=" + uname + ", role_id=" + roleId);
} } catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接,释放资源
// 略
}

项目结构如下:

5、字符串拼接方式执行动态查询

创建一个 UserDao 类,用上面的方式编写一个使用id查询用户的方法

 public class UserDao {

     public Map<String, Object> getUserInfoById(int id) throws SQLException {

         // 拼接sql字符串
String sql = "select id, username, role_id from t_user where id = "+ id; Connection conn = null;
Statement stmt = null;
ResultSet rs = null; try {
// 获取连接
conn = DBUtil.getConnection(); stmt = conn.createStatement();
// 执行查询并获取结果集
rs = stmt.executeQuery(sql); Map<String, Object> user = new HashMap<String, Object>(); // 遍历结果集,封装数据并返回
if (rs.next()) {
String uname = rs.getString("username");
int roleId = rs.getInt(3);
user.put("id", id);
user.put("username", uname);
user.put("role_id", roleId);
}
return user; } catch (SQLException e) {
// 可以把异常抛给业务层的调用者
throw e;
} finally {
// 关闭连接,释放资源
// 略
}
} public static void main(String[] args) {
UserDao uDao = new UserDao();
try {
Map<String, Object> user = uDao.getUserInfoById(1);
System.out.println(user);
} catch (SQLException e) {
e.printStackTrace();
}
}
}

这个方法很简单,也符合我们正常的编码习惯,但是 PreparedStatement 相比,执行效率较低,而且也有 SQL 的风险

6、代码

点击下载

JDBC第一个案例的更多相关文章

  1. 学习ExtjsForVs(第一个案例HelloWord)

    第一个案例-Hello Word 1.本次练习以ext-4.0.7为例,首先从网上下载ext包. 2.打开包后将里面的三个文件或文件夹拷贝到项目中. resource文件夹 bootstrap.js ...

  2. spring boot实战(第一篇)第一个案例

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   spring boot实战(第一篇)第一个案例 前言 写在前面的话 一直想将spring boot相关内容写成一个系列的 ...

  3. (转)编写Spring的第一个案例并测试Spring的开发环境

    http://blog.csdn.net/yerenyuan_pku/article/details/52832145 Spring4.2.5的开发环境搭建好了之后,我们来编写Spring的第一个案例 ...

  4. javascript进阶教程第一章案例实战

    javascript进阶教程第一章案例实战 一.学习任务 通过几个案例练习回顾学过的知识 通过练习积累JS的使用技巧 二.实例 练习1:删除确认提示框 实例描述: 防止用户小心单击了“删除”按钮,在用 ...

  5. JDBC第一天连接池案例

    JDBC,JDBC的工具类JDBC 连接从连接池中拿: 创建连接池的语句: package day01; import java.sql.Connection; import java.sql.Dri ...

  6. Javaweb入门 JDBC第一天

    JDBC的定义和作用 DBC(Java DataBase Connectivity) Java数据库连接, 其实就是利用Java语言/程序连接并访问数据库的一门技术. 之前我们可以通过cmd或者nav ...

  7. 第91讲:Akka第一个案例动手实战架构设计

    我们来看一下Akka的一个简单的wordcount的案例架构设计 从图中我们可以看出,不同的行我们是交给不同的actor进行入理的,每行首先进行map操作,识别出每个单词,然后交给reduce步骤的a ...

  8. Hibernate—第一个案例

    百度百科上是这样写道的:Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可 ...

  9. MyBatis第一个案例-----永远的HelloWorld 含所有代码

    1.创建表emp CREATE DATABASE mybatis; USE mybatis; CREATE TABLE emp( id INT(11) PRIMARY KEY AUTO_INCREME ...

随机推荐

  1. 《恶魔人crybaby》豆瓣短评爬取

    作业要求来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/3159 爬虫综合大作业 选择一个热点或者你感兴趣的主题. 选择爬取的对象 ...

  2. Authenticator App 两步验证会不会造成亚马逊账号关联?

    今天听人说,因为用Authenticator App做亚马逊两步验证造成了帐号关联…… 我给大家解释一下Authenticator的实现原理,作为计算机专业科班出身的我,此次从各方面了解并经过自己亲测 ...

  3. JVM探究之 —— HotSpot虚拟机对象探秘

    本节以常用的虚拟机HotSpot和常用的内存区域Java堆为例,深入探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全过程. 1. 对象的创建 Java是一门面向对象的编程语言.在语言层面 ...

  4. swoole流程图

    程图,便于以后回忆下 总结几点如下: 首先主进程监听pipe_master事件, 子进程监听pipe_worker事件 通过主进程派生的线程 swReactorThread *thread = swS ...

  5. docker vim右键进入visual模式无法粘贴

    右键不能粘贴,反而进入了visual模式, vim版本:version 8.0.707 修改方法: vim /usr/share/vim/vim80/defaults.vim 第70行 在mouse= ...

  6. spring boot集成mybatis分页插件

    mybatis的分页插件能省事,本章记录的是 spring boot整合mybatis分页插件. 1.引入依赖 <!-- 分页插件pagehelper --> <dependency ...

  7. 【446】Deep Learning

    ref: 深度学习基础介绍 机器学习19 神经网络NN算法 ref: 深度学习基础介绍 机器学习11 神经网络算法应用上 ref: 深度学习基础介绍 机器学习12 神经网络算法应用下 ref: 神经网 ...

  8. oracle 中decode的用法

    select decode(gg1.group_goods_amount, , , gg1.group_goods_amount) ; 这句话的意思是:如果group_goods_amount为0 则 ...

  9. 移动端播放直播流(video.js 播放 m3u8 流)

    流媒体服务器: wowza 流媒体格式: m3u8 播放端:移动端网页(Android.IOS) 播放工具: video.js 代码如下: <!DOCTYPE html> <html ...

  10. [LeetCode] 602. Friend Requests II: Who Has Most Friend? 朋友请求 II: 谁有最多的朋友?

    In social network like Facebook or Twitter, people send friend requests and accept others' requests ...