当前位置: 首页 > news >正文

文案策划的网站手机论坛手机之家

文案策划的网站,手机论坛手机之家,wordpress主题jenney,网站rss地址生成目录 引言 一、JDBC连接数据库步骤 1. 加载驱动 2. 获取连接(URL 用户名 密码) 3. 编写sql 4. 获取执行sql的stmt的对象 5. 执行sql 拿到结果集 6. 遍历结果集 7. 关闭资源(先开的后关 后开的先关) 二、JDBC工具类 版…

目录

引言

一、JDBC连接数据库步骤

1. 加载驱动

2. 获取连接(URL 用户名  密码)

3. 编写sql

4. 获取执行sql的stmt的对象

5. 执行sql  拿到结果集

6. 遍历结果集

7. 关闭资源(先开的后关 后开的先关)

二、JDBC工具类

版本一:基础JDBC工具类(JdbcUtils)

版本二:配置化JDBC工具类(JdbcUtils2)

版本三:连接池JDBC工具类(JdbcUtils3)

测试

总结


引言

        JDBC(Java Database Connectivity)是Java连接数据库的标准API,但在实际开发中直接使用原始JDBC API会带来大量重复代码。本文将介绍三种不同版本的JDBC工具类实现,展示如何通过逐步优化来提高开发效率和代码质量。

一、JDBC连接数据库步骤

1. 加载驱动

        首先,需要加载数据库驱动。驱动是各个数据库生产商提供的实现类,用于实现JDBC接口规范。对于MySQL数据库,需要导入mysql-connector-java-5.1.13-bin.jar驱动包。

        在Java代码中,通常使用以下方式加载驱动:

Class.forName("com.mysql.jdbc.Driver");

​注意​​:通过Class.forName("com.mysql.jdbc.Driver")加载驱动,可以避免直接使用new Driver()方式带来的依赖问题和驱动jar包加载两次的问题。

2. 获取连接(URL 用户名  密码)

        加载驱动后,需要获取数据库连接。使用DriverManager类的getConnection方法,传入数据库连接URL、用户名和密码。

String url = "jdbc:mysql:///spring_db"; // 如果是本地数据库,localhost:3306可以省略
String user = "root";
String password = "12345";
Connection conn = DriverManager.getConnection(url, username, password);

​URL格式​​:jdbc:mysql://localhost:3306/spring_db

  • jdbc:主协议

  • mysql:子协议(可能变化)

  • localhost:主机

  • 3306:默认端口号

  • spring_db:数据库名称

3. 编写sql

        接下来,编写需要执行的SQL语句。SQL语句可以是查询、插入、更新或删除操作。

String sql = "SELECT * FROM t_user";

4. 获取执行sql的stmt的对象

        有两种方式获取执行SQL的对象:StatementPreparedStatement

Statement

   Statement接口用于执行静态SQL语句,但存在SQL注入问题(字符串拼接)。

Statement stmt = conn.createStatement();

​注意​​:Statement接口虽然简单易用,但在处理用户输入时容易受到SQL注入攻击。例如,如果用户输入的用户名或密码包含恶意SQL代码,可能会导致数据库泄露或被篡改。

PreparedStatement

   PreparedStatementStatement的子接口,支持预编译SQL语句,采用占位符的形式,能有效防止SQL注入问题。推荐使用。

String sql = "SELECT * FROM t_user WHERE username = ? AND password = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username); // 设置第一个参数
pstmt.setString(2, password); // 设置第二个参数

​注意​​:使用PreparedStatement时,SQL语句中的参数用?占位符代替,再通过setXxx方法设置具体值。这种方式不仅提高了代码的可读性和可维护性,还能有效防止SQL注入攻击。

5. 执行sql  拿到结果集

        执行SQL语句并获取结果集。如果是查询语句,返回的结果集封装在ResultSet接口中。

ResultSet rs = pstmt.executeQuery(); // 查询语句
// int affectedRows = pstmt.executeUpdate(); // 增删改语句

​注意​​:executeQuery方法用于执行查询语句,返回一个ResultSet对象;executeUpdate方法用于执行增删改语句,返回受影响的行数。

6. 遍历结果集

        遍历ResultSet结果集,获取查询的数据。

while (rs.next()) {int id = rs.getInt("id");String username = rs.getString("username");String password = rs.getString("password");String email = rs.getString("email");System.out.println(id + ", " + username + ", " + password + ", " + email);
}

​注意​​:ResultSet内部维护一个游标,默认指向第一行数据之前,调用next()方法向下移动游标。获取值的方法有多种,如getIntgetString等,可以根据字段类型选择合适的方法。

7. 关闭资源(先开的后关 后开的先关)

        最后,必须关闭所有打开的资源,包括ResultSetStatementConnection对象。关闭资源的代码一般放在finally块中,确保一定会执行。

if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}
}
if (pstmt != null) {try {pstmt.close();} catch (SQLException e) {e.printStackTrace();}
}
if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}
}

​注意​​:关闭资源的顺序应与打开的顺序相反,即先开的后关,后开的先关。这样可以确保资源的正确释放,避免内存泄漏和资源占用问题。

        通过以上步骤,我们可以使用JDBC连接数据库并执行SQL操作。结合PreparedStatement可以有效防止SQL注入问题,确保数据库操作的安全性。

二、JDBC工具类

版本一:基础JDBC工具类(JdbcUtils)

        这是最基础的JDBC工具类实现(加载驱动,获取连接和关闭资源可提取出来,重复使用,即JDBC工具类1.0版本),主要解决了驱动加载和连接获取的基本需求。

package com.qcby.utils;import com.mysql.jdbc.Driver;import java.sql.*;/*** JDBC工具类 简化开发* 减少重复性代码* JDBC的工具类 1.0版本*/
public class JdbcUtils {/*** 加载驱动*/public static void createDriver(){try{//2种//1.直接调用方法DriverManager.registerDriver(new Driver());//2.反射加载//Class.forName("com.mysql.jdbc.Driver");}catch (Exception e){e.printStackTrace();}}/*** 获取连接* @return*/public static Connection getConnection(){Connection connection=null;try {//1.加载驱动createDriver();//2.获取连接connection=DriverManager.getConnection("jdbc:mysql:///spring_db","root","12345");}catch (SQLException e){e.printStackTrace();}return connection;}/*** 关闭资源*///1.查询 重载方法public static void close(Connection connection, ResultSet resultSet, Statement statement){try{resultSet.close();statement.close();connection.close();}catch (SQLException e){e.printStackTrace();}}//2.增删改public static void close(Connection connection, Statement statement){try{statement.close();connection.close();}catch (SQLException e){e.printStackTrace();}}
}

特点分析

  1. ​优点​​:

    • 简单直接,适合小型项目或快速原型开发

    • 封装了基本的连接获取和资源关闭操作

  2. ​缺点​​:

    • 硬编码数据库连接信息,不利于维护

    • 每次调用都会重复注册驱动(虽然JDBC规范允许重复注册,但不推荐)

    • 缺乏异常处理机制

    • 没有连接池支持,性能较差

版本二:配置化JDBC工具类(JdbcUtils2)

        这个版本通过读取配置文件来提高灵活性,解决了硬编码问题。

package com.qcby.utils;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;/*** JDBC的工具类 2.0版本(智能一些),编写properties属性文件,程序就可以读取属性文件*      1. 驱动类*      2. 数据库地址*      3. 用户名*      4. 密码*/
public class JdbcUtils2 {//静态不可更改常量private static final String diverclass;private static final String url;private static final String username;private static final String password;//静态代码块 类一加载的时候就会执行,调用的这个类的时候static {//加载db.properties文件读取链接数据库的所有参数// 加载属性文件Properties pro = new Properties();InputStream inputStream = JdbcUtils.class.getResourceAsStream("/db.properties");// 加载属性文件try {pro.load(inputStream);} catch (IOException e) {e.printStackTrace();}// 给常量赋值diverclass = pro.getProperty("driverclass");url = pro.getProperty("url");username = pro.getProperty("username");password = pro.getProperty("password");}/*** 加载驱动*/public static void createDriver(){try{//2种//1.直接调用方法//DriverManager.registerDriver(new Driver());//2.反射加载Class.forName(diverclass);}catch (Exception e){e.printStackTrace();}}/*** 获取连接* @return*/public static Connection getConnection(){Connection connection=null;try {//1.加载驱动createDriver();//2.获取连接connection= DriverManager.getConnection(url,username,password);}catch (SQLException e){e.printStackTrace();}return connection;}/*** 关闭资源*///1.查询public static void close(Connection connection, ResultSet resultSet, Statement statement){try{resultSet.close();statement.close();connection.close();}catch (SQLException e){e.printStackTrace();}}//2.增删改public static void close(Connection connection, Statement statement){try{statement.close();connection.close();}catch (SQLException e){e.printStackTrace();}}
}
#db.properties
driverclass=com.mysql.jdbc.Driver
url=jdbc:mysql:///spring_db
username=root
password=12345

改进点

  1. ​配置文件支持​​:

    • 将数据库连接信息移到db.properties文件中

    • 通过Properties类加载配置

  2. ​异常处理改进​​:

    • 将检查异常转换为运行时异常,强制调用方处理

  3. ​驱动加载优化​​:

    • 使用Class.forName()替代直接注册驱动

仍然存在的问题

  1. 仍然没有连接池支持

  2. 资源管理可以更完善

  3. 配置文件路径硬编码

版本三:连接池JDBC工具类(JdbcUtils3)

        这是最完善的版本,引入了连接池技术(Druid)来提高性能和资源利用率。

package com.qcby.utils;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;/*** JDBC的工具类 1.0版本* JDBC的工具类 2.0版本(智能一些),编写properties属性文件,程序就可以读取属性文件* JDBC的工具类 3.0版本,加入连接池对象*/
public class JdbcUtils3 {// 连接池对象private static DataSource DATA_SOURCE;static{// 加载属性文件Properties pro = new Properties();InputStream inputStream = JdbcUtils3.class.getResourceAsStream("/druid.properties");try {// 加载属性文件pro.load(inputStream);// 创建连接池对象DATA_SOURCE = DruidDataSourceFactory.createDataSource(pro);} catch (Exception e) {e.printStackTrace();}}/*** 从连接池中获取连接,返回。* @return*/public static Connection getConnection(){Connection conn = null;try {conn = DATA_SOURCE.getConnection();} catch (SQLException e) {e.printStackTrace();}return conn;}/*** 关闭资源* @param conn* @param stmt* @param rs*/public static void close(Connection conn, ResultSet rs, Statement stmt){if(rs != null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if(stmt != null){try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if(conn != null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}/*** 关闭资源* @param conn* @param stmt*/public static void close(Connection conn, Statement stmt){if(stmt != null){try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if(conn != null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}
}
#druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///spring_db
username=root
password=12345
initialSize=5
maxActive=10
maxWait=3000
maxIdle=6
minIdle=3

核心优势

  1. ​连接池支持​​:

    • 使用Druid连接池,显著提高性能

    • 连接可复用,减少创建和销毁开销

  2. ​配置灵活性​​:

    • 所有数据库配置(包括连接池参数)都通过druid.properties管理

    • 可以轻松调整连接池大小、超时时间等参数

  3. ​更健壮的异常处理​​:

    • 构造阶段失败会抛出运行时异常

    • 方法内部捕获异常但不吞掉,便于排查问题

  4. ​资源管理优化​​:

    • 虽然关闭逻辑与版本二类似,但配合连接池使用更合理

最佳实践建议

  1. ​异常处理​​:

    • 生产环境中应使用日志框架记录异常,而不是简单打印

    • 考虑自定义异常类提供更友好的错误信息

  2. ​资源管理​​:

    • 使用try-with-resources语法(Java 7+)自动关闭资源

    • 对于连接池,close()方法实际上是将连接返回到池中

  3. ​连接池选择​​:

    • Druid是不错的选择,也可以考虑HikariCP(性能更好)

    • 根据项目需求配置合适的连接池参数

  4. ​SQL操作​​:

    • 对于生产代码,应使用PreparedStatement防止SQL注入

    • 考虑使用ORM框架(MyBatis、Hibernate)进一步简化开发

特性1.0版本2.0版本3.0版本
配置管理硬编码配置文件连接池专属配置
连接创建每次新建每次新建连接池复用
性能表现差(100ms/次)优(<10ms/次)
并发支持队列机制
适用场景学习/测试小型项目生产环境

测试

package com.qcby.model;/*** 对应数据库的账户表* 实体类*/
public class Account {private Integer id;private String name;private Double money;public Account(){}public Account(Integer id, String name, Double money) {this.id = id;this.name = name;this.money = money;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
}
package com.qcby.dao;import com.qcby.model.Account;
import com.qcby.utils.JdbcUtils;
import com.qcby.utils.JdbcUtils2;
import com.qcby.utils.JdbcUtils3;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class JdbcDao {public void select01(){Connection connection = null;Statement statement = null;ResultSet resultSet = null;try {//jdbc连接数据库//1.加载驱动//2.获取连接(URL 用户名  密码)connection = JdbcUtils.getConnection();//3.编写sqlString sql="select * from account";//4.获取执行sql的stmt的对象statement = connection.createStatement();// 两个  stmt(sql注入问题 字符串拼接)  pstmt(预编译 防止sql植入问题  占位符))//5.执行sql  拿到结果集resultSet = statement.executeQuery(sql);//6.遍历结果集while (resultSet.next()){Account account=new Account();account.setId(resultSet.getInt("id"));account.setName(resultSet.getString("username"));account.setMoney(resultSet.getDouble("money"));System.out.println(account);}} catch (SQLException e) {e.printStackTrace();}finally {//7.关闭资源(先开的后关 后开的先关)JdbcUtils.close(connection, resultSet, statement);}}public static void main(String[] args) {Connection connection = null;Statement statement = null;ResultSet resultSet = null;try {//jdbc连接数据库//1.加载驱动//2.获取连接(URL 用户名  密码)connection = JdbcUtils3.getConnection();//3.编写sqlString sql="select * from account";//4.获取执行sql的stmt的对象statement = connection.createStatement();// 两个  stmt(sql注入问题 字符串拼接)  pstmt(预编译 防止sql植入问题  占位符))//5.执行sql  拿到结果集resultSet = statement.executeQuery(sql);//6.遍历结果集while (resultSet.next()){Account account=new Account();account.setId(resultSet.getInt("id"));account.setName(resultSet.getString("name"));account.setMoney(resultSet.getDouble("money"));System.out.println(account);}} catch (SQLException e) {e.printStackTrace();}finally {//7.关闭资源(先开的后关 后开的先关)JdbcUtils3.close(connection, resultSet, statement);}}//    public void select(){
//        //jdbc连接数据库
//        //1.加载驱动
//        //2.获取连接(URL 用户名  密码)
//        //3.编写sql
//        //4.获取执行sql的stmt的对象
//        // 两个  stmt(sql注入问题 字符串拼接)  pstmt(预编译 防止sql植入问题  占位符))
//        //5.执行sql  拿到结果集
//        //6.遍历结果集
//        //7.关闭资源(先开的后关 后开的先关)
//    }
}

总结

JDBC工具类的演进反映了软件开发中"封装重复、提高灵活性、优化性能"的普遍原则:

  1. ​基础版​​:解决基本功能,适合简单场景

  2. ​配置化版​​:通过外部配置提高灵活性

  3. ​连接池版​​:引入连接池提升性能和资源利用率

在实际项目中,建议直接使用成熟的ORM框架或经过充分测试的JDBC工具类库,除非有特殊需求需要自定义实现。

http://www.dtcms.com/a/425449.html

相关文章:

  • 网页设计与网站建设考试热点大兴德艺网站建设
  • 厦门数字引擎 怎么打不开网站做图表的网站推荐
  • 东莞网站开发哪里找公司网络营销的方案
  • 天津在哪做网站哪些网站需要icp备案
  • 如何做团购网站中的美食地处地图功能旅游网站开发周期
  • 重庆做木门网站公司wordpress文章输出数
  • wordpress如何编辑器重庆网站seo技术
  • 淘宝网站建设评价表wordpress自定义呢
  • 北京泰达建设有限公司网站资深seo顾问
  • 网站建设合同交印花税吗企业网站制作素材
  • 李家沱网站建设左侧固定导航栏的网站
  • 网站备案 失败西安官网seo方法
  • 电商网站设计思维导图网站首页的布局
  • 导航网站系统榆林市建设局网站
  • 南沙滩网站建设安徽网站排名优化公司
  • 扬州网站开发公司wordpress添加分类图片
  • 微网站备案做教育网站挣钱
  • 一般企业网站3年多少钱建网站公司锦程
  • 设计参考图网站腾讯企点下载安装
  • 东莞网站建设时间网站建设mingxinsh
  • wordpress建站赚钱如何建设一个社交网站
  • 江门找人做网站排名黑群晖 frp wordpress 访问
  • 阿里云新增网站如果用局域网做网站
  • 受欢迎的常州做网站网路神做网站怎么样
  • 微信小程序开发平台官网宁波网站运营优化系统
  • 用数据库代码做家乡网站陇南市建设局网站公示
  • 网站的域名和密码怎么查看网站用的php还是.net
  • 爱ppt网站广州官方发布
  • 做网站的相关规定ipc网站备案查询
  • 汕头制作网站软件腾讯网