JDBC核心技术(基础)
一、JDBC概述
1.1 Java中的数据存储技术
- 在Java中,数据库存取技术可分为如下几类:
- JDBC直接访问数据库
- JDO (Java Data Object )技术
- 第三方O/R工具,如Hibernate, Mybatis 等
- JDBC是java访问数据库的基石,JDO、Hibernate、MyBatis等只是更好的封装了JDBC。
1.2 JDBC介绍
- JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。
- JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
- JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
1.3 JDBC程序编写步骤
1.获取数据库连接
Connection conn = JDBCUtils.getConnection(); //方式1:手动获取连接 方式2:数据库连接池
conn.setAutoCommint(false); //体现事务
2.如下的多个DML操作,作为一个事务出现
操作1:需要使用通用的增删改查操作 //通用的增删改查如何实现?
操作2:需要使用通用的增删改查操作 //方式1:手动使用PreparedStatement实现
操作3:需要使用通用的增删改查操作 //方式2:使用dbutils.jar中QueryRunner类
conn.commit()
3.如果出现异常,则:
conn.rollback();
4.关闭资源
JDBCUtils.closeResource(......); //方式1:手动关闭资源 方式2:DbUtils类的关闭放法
二、获取数据库连接
三要素:
- Driver接口实现类
(1)ava.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。
(2)在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现。
(3)加载驱动:加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的类名Class.forName(“com.mysql.jdbc.Driver”);
(4)注册驱动:DriverManager 类是驱动程序管理器类,负责管理驱动程序 使用DriverManager.registerDriver(com.mysql.jdbc.Driver)来注册驱动 - URL
jdbc:mysql://主机名称:mysql服务端口号/数据库名称?参数=值&参数=值 - 用户名和密码
user,password可以用“属性名=属性值”方式告诉数据库
可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接
连接方式举例
@Test
public void testConnection5() throws Exception {
//1.加载配置文件
InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pros = new Properties();
pros.load(is);
//2.读取配置信息
String user = pros.getProperty("user");
String password = pros.getProperty("password");
String url = pros.getProperty("url");
String driverClass = pros.getProperty("driverClass");
//3.加载驱动
Class.forName(driverClass);
//4.获取连接
Connection conn = DriverManager.getConnection(url,user,password);
System.out.println(conn);
}
配置文件声明在工程的src目录下:【jdbc.properties】
user=root
password=abc123
url=jdbc:mysql://localhost:3306/test
driverClass=com.mysql.jdbc.Driver
三、使用PreparedStatement实现CRUD操作
3.1 操作和访问数据库
- 数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果。其实一个数据库连接就是一个Socket连接。
- 在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:
- Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
- PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。
- CallableStatement:用于执行 SQL 存储过程
PreparedStatement 与Statement对比
https://blog.csdn.net/str125757855/article/details/120921660?spm=1001.2014.3001.5501
3.2使用PreparedStatement实现增、删、改操作
//通用的增、删、改操作(体现一:增、删、改 ; 体现二:针对于不同的表)
public void update(String sql,Object ... args){
Connection conn = null;
PreparedStatement ps = null;
try {
//1.获取数据库的连接
conn = JDBCUtils.getConnection();
//2.获取PreparedStatement的实例 (或:预编译sql语句)
ps = conn.prepareStatement(sql);
//3.填充占位符
for(int i = 0;i < args.length;i++){
ps.setObject(i + 1, args[i]);
}
//4.执行sql语句
ps.execute();
} catch (Exception e) {
e.printStackTrace();
}finally{
//5.关闭资源
JDBCUtils.closeResource(conn, ps);
}
}
3.4 使用PreparedStatement实现查询操作
// 通用的针对于不同表的查询:返回一个对象 (version 1.0)
public <T> T getInstance(Class<T> clazz, String sql, Object... args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 1.获取数据库连接
conn = JDBCUtils.getConnection();
// 2.预编译sql语句,得到PreparedStatement对象
ps = conn.prepareStatement(sql);
// 3.填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
// 4.执行executeQuery(),得到结果集:ResultSet
rs = ps.executeQuery();
// 5.得到结果集的元数据:ResultSetMetaData
ResultSetMetaData rsmd = rs.getMetaData();
// 6.1通过ResultSetMetaData得到columnCount,columnLabel;通过ResultSet得到列值
int columnCount = rsmd.getColumnCount();
if (rs.next()) {
T t = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {// 遍历每一个列
// 获取列值
Object columnVal = rs.getObject(i + 1);
// 获取列的别名:列的别名,使用类的属性名充当
String columnLabel = rsmd.getColumnLabel(i + 1);
// 6.2使用反射,给对象的相应属性赋值
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t, columnVal);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 7.关闭资源
JDBCUtils.closeResource(conn, ps, rs);
}
return null;
}
ResultSetMetaData
- 可用于获取关于 ResultSet 对象中列的类型和属性信息的对象
- ResultSetMetaData meta = rs.getMetaData();
- getColumnName(int column):获取指定列的名称
- getColumnLabel(int column):获取指定列的别名
- getColumnCount():返回当前 ResultSet 对象中的列数。
- getColumnTypeName(int column):检索指定列的数据库特定的类型名称。
- getColumnDisplaySize(int column):指示指定列的最大标准宽度,以字符为单位。
- isNullable(int column):指示指定列中的值是否可以为 null。
- isAutoIncrement(int column):指示是否自动为指定列进行编号,这样这些列仍然是只读的。
JDBC CRUD操作小结
###
资源的释放
- 释放ResultSet, Statement,Connection。
- 数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
- 可以在finally中关闭,保证及时其他代码出现异常,资源也一定能被关闭。
四、操作BLOB类型字段
MySQL BLOB类型
- MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。
- 插入BLOB类型的数据必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串拼接写的。
- MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的)
类型 大小(单位字节)
TinyBlob 最大255
Blob 最大65K
MediumBlob 最大16M
LongBlob 最大4G
向数据表中插入大数据类型
//获取连接
Connection conn = JDBCUtils.getConnection();
String sql = "insert into customers(name,email,birth,photo)values(?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
// 填充占位符
ps.setString(1, "徐海强");
ps.setString(2, "xhq@126.com");
ps.setDate(3, new Date(new java.util.Date().getTime()));
// 操作Blob类型的变量
FileInputStream fis = new FileInputStream("xhq.png");
ps.setBlob(4, fis);
//执行
ps.execute();
fis.close();
JDBCUtils.closeResource(conn, ps);