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

JDBC快速入门

JDBC入门到精通

  • Java,是Java提供的,用来操作数据库的,接口API,不同的数据库需要有着不同的实现
  • JDBC API是一系列的接口,相关类和接口在java.sql和javax.sql包中

JDBC快速入门

  1. 注册驱动
  2. 得到Connection
  3. 发送SQL给MySQL执行
  4. 释放资源
//得到驱动,得到连接 Driver driver = new Driver(); String url = "jdbc:mysql://127.0.0.1:3306/student"; Connection connect = driver.connect(url, properties); //connect createStatement()//Statement用于执行静态SQL语句 //statement executeUpdate(String sql)//return number of affected rows executeQuery(String sql)//return ResultSet类,注意要释放这个资源 //释放资源 statement.close(); connect.close();

获取数据库连接的5种方式

  1. 获取Driver实现类对象,通过其connect方法,得到数据库连接
    • 属于静态加载,灵活性差,依赖强
  2. 通过反射机制,得到数据库连接
    • 属于动态加载,更加的灵活,减少了依赖性,可以把信息写在配置文件上
  3. 使用DriverManager 替代 Driver 进行统一管理,得到数据库连接
  4. 使用class.forName自动完成注册驱动,简化代码
  5. 在第四种方法中,使用properties文件,让连接mysql更加灵活

通过反射机制,得到数据库连接

Class<?> aClass = Class.forName("com.mysql.jdbc.Driver"); Driver driver = (Driver) aClass.newInstance(); Connection connect = driver.connect(url, properties);

使用DriverManager 替代 Driver 进行统一管理,得到数据库连接

Class<?> aClass = Class.forName("com.mysql.jdbc.Driver"); Driver driver = (Driver) aClass.newInstance(); DriverManager.registerDriver(driver); Connection connection = DriverManager.getConnection(url, user, password);

使用class.forName自动完成注册驱动,简化代码,推荐使用√

  • jdk1.5以后使用了jdbc4,在程序启动时,会自动调用jar包下META-INF\services\java.sql.Driver文本中的类名称去注册
  • 不再需要显示调用class.forName()注册驱动
//也可以使用properties文件,让连接MySQL更加灵活 Class.forName("com.mysql.jdbc.Driver"); DriverManager.getConnection(url, user, password);
//ResultSet结果集 next()//光标移到下一行,如果不存在下一行会返回false //ResultSet结果集 RowDataStatic rowData ArrayList rows//存放着所有的行(ByteArrayRow) //ByteArrayRow Byte[4] internalRowData//存放着行里的每列

在连接建立后,需要对数据库进行访问,执行命令或是SQL语句,可以通过三种方式

  • Statement,存在SQL注入,不能使用
  • PreparedStatement,继承了Statement接口
  • CallableStatement

scanner.next();有单引号或空格就结束了,而nextLine()认为回车才算是结束

PreparedStatement

  • PreparedStatement预处理的好处有三点
    1. 在SQL语句中使用?作为占位符,而不是使用+拼接SQL语句,减少了语法错误
    2. 有效的解决了SQL注入的问题
    3. 大大减少了编译次数,执行效率较高
String sql = "select * from admin where name=? and pwd=?"; connection.prepareStatement(sql); preparedStatement.setString(1, "hsp"); preparedStatement.setString(2, "000000"); preparedStatement.executeQuery(); preparedStatement.executeUpdate();

JDBC API

//DriverManger驱动管理 getConnection(url,user,pwd) //Connection createStatement()//存在sql注入问题 prepareStatement(sql) setAutoCommit(true)//设置此连接的自动提交模式的状态,默认为true commit()//使自上次提交/回滚以来所作的所有更改都将永久性,并释放此Connection对象当前持有的任何数据库锁 rollback()//默认回滚到事务开始的状态,并释放此Connection对象当前持有的任何数据库锁 //
  • Statement
    • executeUpdate(sql)执行dml语句,返回受影响的行数
    • executeQuery(sql)执行查询语句,返回一个ResultSet接口的实现类对象
    • execute(sql)可以执行任意的sql语句,返回boolean
  • PreparedStatement,继承了Statement接口
    • executeUpdate()
    • executeQuery()
    • execute()
    • setXxx(第几个占位符, 占位符的值)设置类型为Xxx,这个方法解决了SQL注入问题
  • ResultSet,结果集
    • next()光标向下移动一行,返回boolean
    • previous()光标向上移动一行,返回boolean
    • getXxx(列的索引 | 列名)返回对应列的值,接收类型为Xxx

事务

批处理

  • Java的批量更新机制,允许多条语句一次性提交给数据库批量处理,通常情况下比单独提交处理有着更高的效率
  • 注意,JDBC连接MySQL时,在url中加上?rewriteBatchedStatements=true后才可以使用批处理功能
  • 批处理往往和PreparedStatement搭配使用,既可以减少发送SQL语句的网络开销,和运行次数,又可以减少编译次数,效率大大提高
  • addBatch(),添加需要批处理的SQL语句或参数
  • executeBatch(),执行批量处理语句
  • clearBatch(),清空批处理包的语句

数据库连接池

为什么会出现连接池呢?

  • 传统的JDBC数据库连接是使用DriverManager来获取,每次向数据库建立连接都需要将Connection加载到内存中,再验证IP地址、用户名和密码。需要数据库连接的时候,就向数据库要求一个,频繁的进行数据库连接操作将占用很多的系统资源,容易造成服务器崩溃
  • 每一次数据库连接,使用完后都要断开,如果程序出现异常而未能关闭,将导致数据库内存泄漏,最终将导致重启数据库
  • 传统获取连接的方式,不能控制创建的连接数量,如果高并发连接数量过多了,也可能导致内存泄漏,MySQL崩溃

数据库连接池的基本介绍

  • 连接池预先在缓冲池中放入了一定数量的连接,当需要建立数据库连接时,只需要从“缓冲池”中取出一个,用完之后再放进去即可
  • 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
  • 当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中

JDBC的数据库连接池使用javax.sql.DataSource来表示,这是一个接口,通常由第三方提供实现的jar包

数据库连接池的种类

  • C3P0数据库连接池,老牌的,速度相对较慢,稳定性不错(hibernate和spring都在用)
  • DBCP数据库连接池,速度相对c3p0较快,但不稳定
  • Proxool数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点
  • BoneCP数据库连接池,速度快
  • Druid(德鲁伊),是阿里提供的数据库连接池,集C3P0、DBCP、Proxool优点于一身的数据库连接池,推荐使用√,速度超级快√

C3P0连接池,使用方式一:它相关的参数在程序中指定,如用户名,密码

CombopolledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setDriverClass(driver); comboPooledDataSource.setJdbcUrl(url); comboPooledDataSource.setUser(user); comboPooledDataSource.setPassword(password); comboPooledDataSource.setInitialPoolSize(10); comboPooledDataSource.setMaxPollSize(50); Connection connection = comboPooledDataSource.getConnection(); connection.close();

C3P0连接池,使用方式二:使用c3p0提供的配置文件模板c3p0-config.xml

CombopolledDataSource comboPooledDataSource = new ComboPooledDataSource("hsp"); Connection connection = comboPooledDataSource.getConnection(); connection.close();

Druid连接池,加入jar包和配置文件(配置文件名可随意,后缀为properties)后

DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); Connection connection = dataSource.getConnection(); connection.close();

Apache-DBUtils工具

  • commons-dbutils是Apache提供的一个开源JDBC工具类库,它是对jdbc的封装,能极大简化jdbc编码的工作量
  • QueryRunner类:封装了SQL的执行,是线程安全的,可以实现crud和批处理
    • query(connection, sql, new BeanHandler<>(Student.class), ...)
    • update(connection, sql, ...)执行增删改查,并返回受影响的行数,...给?赋值
  • ResultSetHandler接口:用于处理java.sql.ResultSet,将数据按要求转换为另一种形式
    • ArrayHandler类,把结果集中的第一行数据转成对象数组
    • ArrayListHandler类,把结果集中的每一行数据都转成一个数组,再放到List中
    • BeanHandler
    • BeanListHandler
    • ColumnListHandler
    • KeyedHandler(name)
    • MapHandler
    • MapListHandler
    • ScalarHandler用于返回单行中单列的值
List<Actor> list = queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1); Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 1); Object obj = queryRunner.query(connection, sql, new ScalarHandler(), 1); connection.close();
  • query方法会自动关闭结果集和statement
  • Actor.class会用到反射
    Pasted image 20251007235236.png

BasicDao

对于dbutils+Druid简化了jdbc开发,但还有不足

  1. SQL语句是固定的,不能通过参数传入,通用性不好
  2. 对于select操作,如果有返回值,返回类型不能固定,需要使用泛型
  3. 将来的表很多,业务是复杂的,不可能只靠一个Java类完成

BasicDao

  • DAO,data access object数据访问对象
  • BasicDao,是专门和数据库交互的,即完成对数据库的crud操作
  • 在BasicDao的基础上,实现一张表对应一个Dao,更好的完成功能,比如Student表-Student.java类(javabean)-StudentDao.java
http://www.jsqmd.com/news/611006/

相关文章:

  • c语言错题
  • 【苍穹外卖】Mac前端开发环境搭建:从零到部署的完整指南
  • 【技术解析】MASt3R-SLAM:如何通过两视图先验实现实时稠密三维重建?
  • 沃虎REACH RoHS合规产品如何助力企业应对全球环保法规升级
  • SDXL 1.0电影级绘图工坊实战案例:品牌LOGO多风格延展设计应用
  • 告别旧版配置:基于frp 0.52.3新特性的内网穿透实战搭建
  • 8大AI核心概念,让你秒懂智能体、多智能体系统、RAG、工作流、微调、函数调用、MCP和A2A!
  • C# 13主构造函数+Records+With表达式三重组合技(.NET 8.0正式版实测):DTO层代码减少83%,但需绕过这个编译器Bug
  • QT集成QRencode与Code128:从源码集成到界面绘制的条码生成实战
  • 从 Apache SeaTunnel 走向 ASF Member:一位开发者的长期主义样本悔
  • springboot基于java搭建网站框架音乐系统_714i0lac
  • 芯视野 | Synwit_UI_Creator(ugui)PC端设计器:从零到一构建高效嵌入式UI
  • 别再混淆了!RuoYi-Vue中‘第三方登录’与‘标准单点登录(SSO)’的实现差异与选型建议
  • CompressO:重新定义音视频压缩的开源解决方案
  • AI:词向量模型详解(Word Embedding)
  • GIL终结者来了!Python原生无锁并发的3大工业级模式:MPMC队列、无等待哈希表、RCU读写分离实战(含perf火焰图验证)
  • IMX6ULL 裸机开发:RGB LCD 显示与 PWM 背光控制
  • OpenClaw日志分析:Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF快速定位服务异常根因
  • 云原生环境中的边缘AI推理服务
  • 利用Dockerfile打造高效Android持续集成环境
  • NUnit并行测试实战:利用Parallelizable提升测试效率300%
  • openclaw平替之nanobot源码解析(七):Gateway与多渠道集成未
  • 从原理到实践:使用Cost733完成天气环流分型的完整指南
  • Chat Smith 7.1.0 vs 原生ChatGPT:哪个更适合你的日常AI需求?
  • SQLite 创建表
  • 无障碍体验:OpenClaw+百川2-13B-4bits实现语音控制自动化
  • 嵌入式数值过渡库:轻量整数插值实现确定性平滑变化
  • 2026年绕线机生产厂家找哪家,自动嵌线机/下线机/立绕机/绑线机/大电机/伺服插纸机/插纸机,绕线机公司怎么选择 - 品牌推荐师
  • 可视化监控OpenClaw:Qwen3-14B任务执行看板搭建
  • Jmeter插件性能优化实战(下载、安装与高级应用指南)