JDBC第一个案例

 

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 表的数据

 

 1 String driver = "com.mysql.jdbc.Driver";
 2 String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false";
 3 String username = "root";
 4 String password = "123456";
 5 
 6 Class.forName(driver);
 7 
 8 Connection conn = null;
 9 Statement stmt = null;
10 ResultSet rs = null;
11 
12 try {
13     conn = DriverManager.getConnection(url, username, password);
14 
15     stmt = conn.createStatement();
16     rs = stmt.executeQuery("select id, username, role_id from t_user");
17 
18     while (rs.next()) {
19         int id = rs.getInt(1);
20         String uname = rs.getString("username");
21         int roleId = rs.getInt(3);
22         System.out.println("用户信息: id=" + id + ", username=" + uname + ", role_id=" + roleId);
23     }
24 } catch (SQLException e) {
25     e.printStackTrace();
26 } finally {
27     try {
28         if (conn != null)
29             conn.close();
30         if (stmt != null)
31             stmt.close();
32         if (rs != null)
33             rs.close();
34     } catch (SQLException e) {
35     }
36 }

 

代码解读

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 类

 

 1 public class DBUtil {
 2 
 3     private static String driver;
 4     private static String url;
 5     private static String username;
 6     private static String password;
 7 
 8     private static Properties prop = new Properties();
 9 
10     static {
11         try {
12             prop.load(DBUtil.class.getClassLoader().getResourceAsStream(
13                     "jdbc.properties"));
14 
15             driver = prop.getProperty("driver");
16             url = prop.getProperty("url");
17             username = prop.getProperty("username");
18             password = prop.getProperty("password");
19 
20             Class.forName(driver);
21 
22         } catch (IOException e) {
23             throw new RuntimeException("加载JDBC配置失败", e);
24         } catch (ClassNotFoundException e) {
25             throw new RuntimeException("加载JDBC配置失败", e);
26         }
27     }
28 
29     public static Connection getConnection() throws SQLException {
30         return DriverManager.getConnection(url, username, password);
31     }
32 }

 

最后,编写 JdbcDemo2 测试类

 1 Connection conn = null;
 2 Statement stmt = null;
 3 ResultSet rs = null;
 4 
 5 try {
 6     // 获取连接
 7     conn = DBUtil.getConnection();
 8 
 9     stmt = conn.createStatement();
10     // 执行查询并获取结果集
11     rs = stmt.executeQuery("select id, username, role_id from t_user");
12 
13     // 遍历结果集
14     while (rs.next()) {
15         int id = rs.getInt(1);
16         String uname = rs.getString("username");
17         int roleId = rs.getInt(3);
18         System.out.println("用户信息: id=" + id + ", username=" + uname + ", role_id=" + roleId);
19     }
20 
21 } catch (SQLException e) {
22     e.printStackTrace();
23 } finally {
24     // 关闭连接,释放资源
25     //
26 }

 

项目结构如下:

 

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

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

 1 public class UserDao {
 2 
 3     public Map<String, Object> getUserInfoById(int id) throws SQLException {
 4 
 5         // 拼接sql字符串
 6         String sql = "select id, username, role_id from t_user where id = "+ id;
 7 
 8         Connection conn = null;
 9         Statement stmt = null;
10         ResultSet rs = null;
11 
12         try {
13             // 获取连接
14             conn = DBUtil.getConnection();
15 
16             stmt = conn.createStatement();
17             // 执行查询并获取结果集
18             rs = stmt.executeQuery(sql);
19 
20             Map<String, Object> user = new HashMap<String, Object>();
21 
22             // 遍历结果集,封装数据并返回
23             if (rs.next()) {
24                 String uname = rs.getString("username");
25                 int roleId = rs.getInt(3);
26                 user.put("id", id);
27                 user.put("username", uname);
28                 user.put("role_id", roleId);
29             }
30             return user;
31 
32         } catch (SQLException e) {
33             // 可以把异常抛给业务层的调用者
34             throw e;
35         } finally {
36             // 关闭连接,释放资源
37             //
38         }
39     }
40 
41     public static void main(String[] args) {
42         UserDao uDao = new UserDao();
43         try {
44             Map<String, Object> user = uDao.getUserInfoById(1);
45             System.out.println(user);
46         } catch (SQLException e) {
47             e.printStackTrace();
48         }
49     }
50 }

 

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

 

6、代码

点击下载

 

转载于:https://www.cnblogs.com/xugf/p/9219703.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值