java数据库开发之JDBC基础使用方法及实例详解
作者:彭世瑜 发布时间:2024-01-21 04:37:00
1.什么是JDBC
JDBC是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序
JDBC 数据库访问规范
应用程序 <-> JDBC <-> MySQL驱动 <-> MySQL
<-> Oracle驱动 <-> Oracle
导入jar包
加载驱动 Class.forName(‘类名')
给出url、username、password
使用DriverManager类得到Connection类
maven导入依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
</dependencies>
连接示例
import java.sql.Connection;
import java.sql.DriverManager;
class Demo {
// MySQL >= 8.0 配置参数
private static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String DB_URL = "jdbc:mysql://localhost:3306/data";
private static final String USER = "root";
private static final String PASSWORD = "123456";
public static void main(String[] args) throws Exception {
// 注册 JDBC 驱动
Class.forName(JDBC_DRIVER);
// 等效于
// com.mysql.cj.jdbc.Driver driver = new com.mysql.cj.jdbc.Driver();
// DriverManager.registerDriver(driver);
// 打开链接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
// 关闭链接
conn.close();
}
}
所有的java.sql.Driver实现类,都提供了static代码块,
块内代码把自己注册到DriverManager中
jdbc4.0之后 每个驱动jar包中,在META-INF/services目录下提供了一个java.sql.Driver文件
内容就是该接口的实现类名称
2.JDBC完成增、删、改、查
1、增、删、改
// 发送DML, DDL
int Statement.executeUpdate(String sql);
代码示例
// 注册 JDBC 驱动
Class.forName(JDBC_DRIVER);
// 打开链接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
Statement statement = conn.createStatement();
// 增删改
// String sql = "insert into student(sname) values('陆小凤')";
// String sql = "update student set sname='花无缺' where sid=4";
String sql = "delete from student where sid=4";
int ret = statement.executeUpdate(sql);
System.out.println(ret);
// 关闭链接
conn.close();
2、查询
ResultSet executeQuery(String querySql);
boolean ResultSet.next();
// 获取列数据
ResultSet.getString()
ResultSet.getObject()
ResultSet.getInt()
ResultSet.getDouble()
行光标
beforeFirst <- 默认光标位置
first
last
AfterLast
// 打开链接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
Statement statement = conn.createStatement();
// 查询
String sql = "select * from student";
ResultSet ret = statement.executeQuery(sql);
while (ret.next()){
// 通过列序号获取
int uid = ret.getInt(1);
// 通过列名称获取
String name = ret.getString("sname");
System.out.println(uid + ", " + name);
}
// 关闭资源
ret.close();
statement.close();
conn.close();
3.JDBC之代码规范化
// 定义
try{
// 实例化
}
finally{
// 关闭资源
}
4.结果集光标与元数据
JBDC主要的类
DriverManager
Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
Statement statement = conn.createStatement();
int executeUpdate(String sql) // 执行增、删、改
ResultSet executeQuery(String sql) // 执行查询
boolean execute(String sql) // 执行增、删、改、查
ResultSet滚动结果集
一个二维表格,内部维护了一个行光标(游标)
next() // 最常用
beforeFirst()
afterLast()
first()
last()
getRow()
absolute()
relative()
isBeforeFirst()
isAfterLast()
isFirst()
isLast()
元数据
// 元数据
ResultSetMetaData ResultSet.getMetaData()
// 获取结果集列数
int ResultSetMetaData.getColumnCount()
// 获取指定列的列名
String ResultSetMetaData.getColumnName(int colIndex)
5.结果集的特性(是否可滚动、是否敏感、是否可更新)
确定结果集特性
1、是否可滚动
2、是否敏感
3、是否可更新
// 不滚动, 不敏感,不可更新
Statement createStatement()
// 滚动支持
Statement createStatement(int resultSetType, int resultSetConcurrency)
resultSetType:
ResultSet.TYPE_FORWARD_ONLY // 不滚动
ResultSet.TYPE_SCROLL_INSENSITIVE // 滚动,不随数据库变化而变化
ResultSet.TYPE_SCROLL_SENSITIVE // 滚动,不随数据库变化而变化
resultSetConcurrency // 是否通过修改结果集二反向影响数据库
ResultSet.CONCUR_READ_ONLY // 结果集只读
ResultSet.CONCUR_UPDATABLE // 结果集可更新
6.PreparedStatement的用法
PreparedStatement是Statement子接口
1、防止SQL注入攻击
2、提高代码可读性,可维护性
3、提高效率
// 打开链接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
// 使用预处理查询, 使用?占位
String sql = "select * from student where sid = ?";
PreparedStatement statement = conn.prepareStatement(sql);
// 为参数赋值
statement.setInt(1, 1);
// 获取数据
ResultSet ret = statement.executeQuery();
while (ret.next()){
String name = ret.getString("sname");
System.out.println(name);
}
// 关闭资源
ret.close();
statement.close();
conn.close();
7.预处理的原理
服务器工作:
(1)校验:sql语句的语法
(2)编译:为一个与函数相似的东西
(3)执行:调用函数
PreparedStatement
(1)先将sql发给数据库,数据库先进行校验
(2)执行的时候只发送参数
8.mysql的预编译功能默认是关闭的
prepare myfun from 'select * from student where sid = ?'
set @uid=1
execute myfun using @uid
设置连接参数:
useServerPrepStmts=true
cachePrepStmts=true
DB_URL = "jdbc:mysql://localhost:3306/data?useServerPrepStmts=true&cachePrepStmts=true";
9.JdbcUtils1.0小工具
JdbcUtils.java
package util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtils {
// 配置文件路径
private static String dbconfig = "dbconfig.properties";
private static Properties prop = null;
// 静态代码块只执行一次
static {
// 初始化数据库配置参数
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream(dbconfig);
prop = new Properties();
prop.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
// 加载驱动
try{
Class.forName(prop.getProperty("driver"));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(
prop.getProperty("url"),
prop.getProperty("username"),
prop.getProperty("password")
);
}
public static void main(String[] args) throws SQLException {
Connection conn = getConnection();
System.out.println(conn);
}
}
dbconfig.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/data
username=root
password=123456
10.面向接口编程
DAO模式
data access object
写一个类,把访问数据库的代码封装起来
DAO在数据库与业务逻辑(service)之间
实体域,即操作的对象
DAO模式步骤
(1)提供一个DAO接口
(2)提供一个DAO接口的实现类
(3)在编写一个DAO工厂,Service通过工厂来获取DAO实现
daoconfig.properties
UserDaoClassName=UserDaoImpl
UserDao.java
public interface UserDao {
}
UserDaoImpl.java
public class UserDaoImpl implements UserDao{
}
DaoFactory.java
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class DaoFactory {
// 配置文件路径
private static String dbconfig = "daoconfig.properties";
private static Properties prop = null;
// 静态代码块只执行一次
static {
// 初始化数据库配置参数
try {
InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream(dbconfig);
prop = new Properties();
prop.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 返回一个UserDao的具体实现类
*/
public static UserDao getUserDao() {
String daoClassName = prop.getProperty("UserDaoClassName");
// 通过反射创建实现类的对象
try {
Class Clazz = Class.forName(daoClassName);
return (UserDao) Clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
11.修改案例,其中dao层为jdbc
User.java
public class User {
private String username;
private int age;
public String getUsername() {
return username;
}
public int getAge() {
return age;
}
public void setUsername(String username) {
this.username = username;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}
}
daoconfig.properties
UserDaoClassName=UserDaoImpl
UserDao.java
public interface UserDao {
public void addUser(User user);
public User getUserByUsername(String username);
}
UserDaoImpl.java
import util.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* create table user(
* id int primary key auto_increment,
* username varchar(50),
* age int
* )
*/
public class UserDaoImpl implements UserDao {
/**
* ORM 对象关系映射
* @param user
*/
@Override
public void addUser(User user) {
Connection conn = null;
PreparedStatement statement = null;
try {
// 得到连接
conn = JdbcUtils.getConnection();
String sql = "insert into user(username, age) values(?, ?)";
// 准备模板
statement = conn.prepareStatement(sql);
// 赋值
statement.setString(1, user.getUsername());
statement.setInt(2, user.getAge());
// 执行
statement.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
if (statement != null) {
statement.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
}
}
}
@Override
public User getUserByUsername(String username) {
Connection conn = null;
PreparedStatement statement = null;
try {
// 得到连接
conn = JdbcUtils.getConnection();
String sql = "select * from user where username = ? limit 1";
// 准备模板
statement = conn.prepareStatement(sql);
// 赋值
statement.setString(1, username);
// 执行
ResultSet resultSet = statement.executeQuery();
if(resultSet.next()){
User user = new User();
user.setUsername(resultSet.getString("username"));
user.setAge(resultSet.getInt("age"));
return user;
}
else{
return null;
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
if (statement != null) {
statement.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
}
}
}
}
DaoFactory.java
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class DaoFactory {
// 配置文件路径
private static String dbconfig = "daoconfig.properties";
private static Properties prop = null;
// 静态代码块只执行一次
static {
// 初始化数据库配置参数
try {
InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream(dbconfig);
prop = new Properties();
prop.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 返回一个UserDao的具体实现类
*/
public static UserDao getUserDao() {
String daoClassName = prop.getProperty("UserDaoClassName");
// 通过反射创建实现类的对象
try {
Class Clazz = Class.forName(daoClassName);
return (UserDao) Clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Service.java
// 添加测试
UserDao userDao = DaoFactory.getUserDao();
User user = new User();
user.setUsername("小明");
user.setAge(23);
userDao.addUser(user);
// 查询测试
User user1 = userDao.getUserByUsername("小明");
System.out.println(user1);
12.util包下的Date与sql包下的时间类型之间的转换
Data -> java.sql.Data
Time -> java.sql.Time
Timestamp -> java.sql.Timestamp
领域对象中所有属性不能出现java.sql包内容
继承关系
java.util.Date
-java.sql.Date
父类转子类:util.Data -> sql.Date、Time、Timestamp
java.util.Date UtilDate = new java.util.Date();
long longDate = UtilDate.getTime();
java.sql.Date sqlData = new java.sql.Date(longDate);
子类转父类:sql.Date、Time、Timestamp -> util.Data
java.util.Date UtilDate = new java.sql.Date(System.currentTimeMillis());
13.大数据
可以将文件存入MySQL
my.ini配置
max_allowed_packet=10485760
14.批处理
批处理只针对更新(增,删,改)
一次向服务器发送多条sql语句
开启批处理参数
rewriteBatchedStatements=true
dbconfig.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/data?rewriteBatchedStatements=true
username=root
password=123456
import util.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
class Demo {
public static void main(String[] args) throws SQLException {
Connection conn = JdbcUtils.getConnection();
String sql = "insert into user(username)values(?)";
PreparedStatement statement = conn.prepareStatement(sql);
for(int i=0; i<10000; i++){
statement.setString(1, "name" + i);
statement.addBatch(); // 装箱
}
long start = System.currentTimeMillis();
statement.executeBatch(); // 提交数据
long end = System.currentTimeMillis();
System.out.println(end - start); // 107
}
}
结束语
本文主要讲了java数据库开发中JDBC基础使用方法及实例
来源:https://blog.csdn.net/mouday/article/details/104237380


猜你喜欢
- 背景测试工具箱写到一半,今天遇到了一个前后端数据交互的问题,就一起做一下整理。环境-----------------------------
- 1.模型类中设置:null=True,表示数据库创建时该字段可不填,用NULL填充.MySQL:Null这一列,如果值为YES表示:创建一条
- 从cmd进入python的方法如下1进入python打开cmd——>直接输入python即可,如下2退出python方法一:先按Ctr
- 前言以前在浏览文章时,看到过一个Android的加载效果,觉得挺好看的,于是自己就模仿了一个。下面话不多说,我们直接来看看详细的介绍吧。运行
- 本文实例讲述了JS实现选择TextArea内文本的方法。分享给大家供大家参考。具体实现方法如下:<script type="
- 目录1、表空间容量指标查询2、表空间扩容方式1:手工改变已存在数据文件的大小方式2:允许已存在的数据文件自动增长方式3:增加数据文件1、表空
- 步骤创建 vue 的脚手架npm install -g @vue/clivue init webpack绑定 git 项目cd existi
- 1. MySQL表空间回收我们经常会发现一个问题,就是把表数据删除以后发现,数据文件大小并没有变化,这就是标题中所说的MySQL数据库表空间
- 这片文章大体概括了一些设计网页中的大问题。希望能给你做下一个网页时给予一些儿启发。1、记住:你能掌控的时间是有限的我仅仅用4秒钟就能浏览完平
- Python中几种常用包比较2、用xlrd包读取Excel文件引用包import xlrd打开文件xlrd.open_workbook(r&
- 前言网上关于PyCharm快捷键的文章数不胜数,但是我发现有以下几个缺陷:具体基于哪个配置? 因为Windows / Mac 的配置各不同,
- 创建RandomWalk类为模拟随机漫步,我们将创建一个RandomWalk类,随机选择前进方向,这个类有三个属性,一个存储随机漫步的次数,
- 经过一轮的项目封闭开发,页面制作的动手能力提高了不少,用AW的话说就是被复杂的东西虐过以后很多问题都变得容易了,的确很有道理。我个人觉得技术
- np.nonzero函数是numpy中用于得到数组array中非零元素的位置(数组索引)的函数。一般来说,通过help(np.nonzero
- 快照复制是在数据库之间对数据以及数据库对象进行复制并进行同步,以确保多个数据库之间一致性的一个法宝。简单的说,快照复制就是实现把一个数据库服
- MySQL安装与配置1、所用MySQL的版本为:MySQL_5_1_26.msi;2、下载好软件后双击进入以下界面: 3、点击Ne
- 学习内容1.软件安装及服务器设置。2.(选做,但是强烈建议) 使用图形界面软件 Navicat for SQL3.数据库基础知识数据库定义关
- 本文分享的实例主要实现的是Python+matplotlib绘制一个有阴影和没有阴影的3D条形图,具体如下。首先看看演示效果:完整代码如下:
- 本文导读:删除表中的数据的方法有delete,truncate, 其中TRUNCATE TABLE用于删除表中的所有行,而不记录单个行删除操
- 察者模式定义定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新。观察者模式提供了一种对象设计,让