数据库连接池及DBUtils
1.数据库连接池
1.1数据库连接池的介绍
(1)什么是数据库连接池
- 实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们 采用连接池技术,来共享连接Connection。这样我们就不需要每次都创建连接、释放连接了,这些操作都交 给了连接池.
(2)数据库连接池的介绍
- 用池来管理Connection,这样可以重复使用Connection。 当使用完Connection后,调用Connection的 close()方法也不会真的关闭Connection,而是把Connection“归还”给池。
1.2 JDBC 方式与连接池的方式
-
普通的JDBC 方式
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXMPUD1u-1608535720932)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218074049245.png)]
-
连接池的方式
1.3连接池与Java之间的连接是如何定义的
- Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。
- 这样应用程序可以方便的切换不同厂商的连接池! 常见的连接池有 DBCP连接池, C3P0连接池, Druid连接池, 接下里我们就详细学习一下
1.4 DBCP连接池
DBCP也是一个开源的连接池,是Apache成员之一,在企业开发中也比较常见,tomcat内置的连接池。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h8Z7u0EN-1608535720956)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218075607443.png)]
1.4.1编写工具类
package www.lagou.utils;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/*
* 自定义jdbc—dbcp工具包
* */
public class Jdbc_Utils_BDCP {
private static DataSource dataSource = null;
static {
InputStream resourceAsStream = Jdbc_Utils_BDCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties properties = new Properties();
try {
//工厂模式创建dataSourcr对象
properties.load(resourceAsStream);
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//返回的是数据库的连接 获取连接的方法
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//关闭资源的方法
public static void close (Connection con, PreparedStatement pstate, ResultSet set){
if (con!=null&& pstate!=null&& set!=null){
try {
set.close();
pstate.close();
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
1.4.2编写测试类 工具包的测试
package org.example.jdbc_mysql.lession04;
import org.example.jdbc_mysql.utils.JdbcUtils_DBCP;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/*
* 测试dbcp数据库连接池
* */
public class TestDBCP {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement statement = null;
try {
//获取连接
connection = JdbcUtils_DBCP.getConnection();
//使用? 占位符代替参数
String sql = "insert into `User`(`userid`,`username`,`password`)values (?,?,?)";
//预编译sql 先写sql然后不执行 返回一个PrepareStatment的对象
PreparedStatement st = connection.prepareStatement(sql);
//手动给参数赋值
st.setInt(1, 2);
st.setString(2, "张三");
st.setString(3, "123456");
//执行操作
int i = st.executeUpdate();
if (i > 0) {
System.out.println("插入成功 ");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils_DBCP.release(connection, statement, null);
}
}
}
1.4.3 常见的配置项
属性 | 描述 |
---|---|
driverClassName | 数据库驱动名称 |
url | 数据库地址 |
username | 用户名 |
password | 密码 |
maxActive | 最大连接数量 |
maxIdle | 最大空闲连接 |
minIdle | 最小空闲连接 |
initialSize | 初始化连接 |
1.5 C3P0 连接池
C3P0是一个开源的JDBC连接池,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、 Spring等。
1.5.1导入jar包及配置文件
(1) 将jar包 复制到myJar文件夹即可,IDEA会自动导入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L9V3TAme-1608535720963)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218080919028.png)]
(2) 导入配置文件 c3p0-config.xml
-
文件名不可更改
-
直接放到src下,也可以放到到资源文件夹中
-
c3p0-config.xml 配置文件
<named-config name="MySQL">
<!-- C3P0的默认的配置
//在工具类的导入配置文件时传入xml配置文件的相应的的name
dataSource=new ComboPooledDataSource("MySQL");
-->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/tempdata</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
<property name="checkoutTimeout">3000</property>
</named-config>
</c3p0-config>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cMve6jua-1608535720974)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218081830527.png)]
1.5.2编写工具类
package org.example.jdbc_mysql.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*
* C3P0d的工具包
* */
public class JdbcUtilis_C3P0 {
private static ComboPooledDataSource dataSource=null;
static {
//导入配置文件
dataSource=new ComboPooledDataSource("MySQL");
}
//获取连接的方法
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//释放资源的方法
public static void release(Connection con, Statement sta, ResultSet set) {
try {
if (con != null) {
con.close();
}
if (sta != null) {
sta.close();
}
if (set != null) {
set.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
1.5.3 测试工具类
package org.example.jdbc_mysql.lession04;
import org.example.jdbc_mysql.utils.JdbcUtilis_C3P0;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/*
* 测试使用C3P0连接池的插入数据到数据库中
* */
public class TestC3P0 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement statement = null;
try {
//获取连接3
connection = JdbcUtilis_C3P0.getConnection();
String sql = "insert into `User`(`userid`,`username`,`password`)values(?,?,?)";
//预编译
statement = connection.prepareStatement(sql);
//给参数赋值
statement.setInt(1, 5);
statement.setString(2, "王万");
statement.setString(3, "123456");
//执行
int i = statement.executeUpdate();
if (i>0){
System.out.println("插入成功");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
//释放资源
JdbcUtilis_C3P0.release(connection,statement,null);
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hVP9oaTN-1608535720977)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218083058256.png)]
1.6Druid连接池
Druid(德鲁伊)是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功 能、性能、扩展性方面,都超过其他数据库连接池,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行 情况。
1.6.1 导入jar包及配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6hiQSJxZ-1608535720979)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218083312447.png)]
1.6.2编写工具类
package org.example.jdbc_mysql.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class Jdbc_Utils_Druid {
//声明成员变量
static DataSource dateSource=null;
//初始化数据路连接池对象
static {
Properties p=new Properties();
//Druid连接池不能加载文件主动加载配置文件 需要指定文件
InputStream resourceAsStream = Jdbc_Utils_Druid.class.getClassLoader().getResourceAsStream("druid.properties");
//导入配置文件
try {
p.load(resourceAsStream);
//通过工厂类获取连接池的对象
dateSource = DruidDataSourceFactory.createDataSource(p);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*获取连接的方法
* */
public static Connection getConnection() throws SQLException {
return dateSource.getConnection();
}
//关闭资源的方法
public static void close (Connection con, PreparedStatement pstate, ResultSet set){
if (con!=null&& pstate!=null&& set!=null){
try {
set.close();
pstate.close();
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//关闭资源的方法
public static void close (Connection con, PreparedStatement pstate){
if (con!=null&& pstate!=null){
try {
pstate.close();
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
1.6.3编写测试类
package org.example.jdbc_mysql.lession05;
import org.example.jdbc_mysql.utils.Jdbc_Utils_Druid;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TestDruid {
static Connection con;
static PreparedStatement statement;
public static void main(String[] args) {
try {
//获取连接
con=Jdbc_Utils_Druid.getConnection();
//sql语句
String sql="update`bank` set username ='张发' where userid=1";
statement = con.prepareStatement(sql);
//执行修改的操作
statement.executeUpdate();
} catch (Exception throwables) {
throwables.printStackTrace();
}finally {
Jdbc_Utils_Druid.close(con,statement);
}
}
}
2.DBUtils工具类
2.1DBUtils的简介
使用JDBC我们发现冗余的代码太多了,为了简化开发 我们选择使用 DbUtils Commons
DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程 序的开发,同时也不会影响程序的性能
- 使用方式: DBUtils就是JDBC的简化开发工具包 需要项目导入commons-dbutils-1.6.jar。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NVkzxwRo-1608535720983)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218091809870.png)]
2.1.1 DBUtils 核心功能的介绍
-
QueryRunner 中提供对sql语句操作的API.
-
ResultSetHandler接口,用于定义select操作后,怎样封装结果集.
-
DbUtils类,他就是一个工具类,定义了关闭资源与事务处理相关方法.
2.2 案列相关的知识
2.2.1 表和类之间的关系
-
整个表可以看做是一个类
-
表中的一行记录,对应一个类的实例(对象)
-
表中的一列,对应类中的一个成员属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LOcBnmaA-1608535720985)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218092315228.png)]
2.2.2 JavaBean 组件
(1) JavaBean 就是一个类, 开发中通常用于封装数据,有一下特点
- 需要实现 序列化接口, Serializable (暂时可以省略)
- 提供私有字段: private 类型 变量名;
- 提供 getter 和 setter 4. 提供 空参构造
(2)我们在创建类的时候要对照 要处理的数据库的表中的字段进行创建
- 我们可以创建一个 entity包,专门用来存放 JavaBean类
package org.example.jdbc_mysql.org.example.entity;
对照 user 的表 进行封装一个JavaBean类
/*
`userid` int(3) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`username` varchar(30) NOT NULL COMMENT '用户姓名',
`password` varchar(30) NOT NULL COMMENT '密码',
* */
public class user {
private int userid;
private String username;
private String password;
public user() {
}
public user(int userid, String username, String password) {
this.userid = userid;
this.username = username;
this.password = password;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "user{" +
"userid=" + userid +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
2.3 DBUtils完成 CRUD (增删改查)
2.3.1QueryRunner 核心类
-
构造方法
QueryRunner();
QueryRunner(DataSource ds ) 提供数据库连接池 底层维护了连接数据库的Connection
-
普通的方法
update();用来完成表数据的增加、删除、更新操 作
query ();用来完成表 数据的查询操作
2.3.2QueryRunner的创建
(1)手动创建
QueryRunner qr=new QueryRunner();
// 手动创建的qr在调用update()和query()时需要传入Conneciton
(2)自动创建
Query qr=new Query(Jdbc_Druid.get)
//在工具类中维护 getDateSource
public static DataSource getDateSource(){
return dateSource;
}
2.3.3QueryRunner 增删改
package org.example.jdbc_mysql.org.example.app;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.example.jdbc_mysql.utils.Jdbc_Utils_Druid;
import javax.sql.DataSource;
import java.sql.SQLException;
public class DBUtilsTest {
static DataSource dateSource;
static QueryRunner qr;
static {
//1.获取连接池的对象
dateSource = Jdbc_Utils_Druid.getDateSource();
//2.自动创建QueryRunner 对象
qr=new QueryRunner(dateSource);
}
public static void main(String[] args) {
// TestInsert();
TestDelete();
}
//添加数据到数据库中
public static void TestInsert(){
String sql="insert into `bank` (userid,username,money)values(?,?,?)";
Object[] parm={3,"陈启",5000};
try {
qr.update(sql,parm);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
//修改
public static void TestUpdate(){
try {
String sql="update `bank` set username='赵六' where userid=?";
qr.update(sql,1);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
//删除
public static void TestDelete(){
String sql="delete from `bank` where userid=?";
try {
qr.update(sql,1);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
2.3.4 QueryRunner 查询的操作
2.3.4.1 ResultSetHandler接口简介
- ResultSetHandler可以对查询出来的ResultSet结果集进行处理,达到一些业务上的需求。
2.3.4.2 ResultSetHandler 结果集处理类
ResultSetHandler实现类 | 说明 |
---|---|
ArrayHandler | 将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这 条记录中的每一个字段的值 |
ArrayListHandler | 将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集 合中 |
BeanHandler | 将结果集中第一条记录封装到一个指定的javaBean中 |
BeanListHandler | 将结果集中每一条记录封装到指定的javaBean中,再将这些javaBean在封装到List 集合中 |
ColumnListHandler | 将结果集中指定的列的字段值,封装到一个List集合中 |
KeyedHandler | 将结果集中每一条记录封装到Map,在将这个map集合做为另一个 Map的value,另一个Map集合的key是指定的字段的值 |
MapHandler | 将结果集中第一条记录封装到了Map集合中,key就是字段名称, value就是字段值 |
MapListHandle | 将结果集中每一条记录封装到了Map集合中,key就是字段名称, value就是字段值,在将这些Map封装到List集合中。 |
ScalarHandler | 它是用于封装单个数据。例如 select count(*) from 表操作。 |
测试
package org.example.jdbc_mysql.org.example.app;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.*;
import org.example.jdbc_mysql.org.example.entity.User;
import org.example.jdbc_mysql.utils.Jdbc_Utils_Druid;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
/*
* 测试QueryRunner 类的查询的功能
* */
public class DBUtilsTestQuery {
//设置成员变量
static DataSource dataSource;
static QueryRunner qr;
//初始化 qr
static {
dataSource = Jdbc_Utils_Druid.getDateSource();
qr = new QueryRunner(dataSource);
}
/*
* 查询id为5的记录,封装到数组中
查询所有数据,封装到List集合中
查询id为5的记录,封装到指定JavaBean中
查询薪资大于 3000 的所员工信息,封装到JavaBean中再封装到List集合中
查询姓名是 张百万的员工信息,将结果封装到Map集合中
查询所有员工的薪资总额
* */
public static void main(String[] args) throws SQLException {
// testFinfId();
//testFindAll();
// testFindIdJavaBean();
// testFindBeanAll();
//testFindByName();
//testSum();
testSum();
}
// 1.查询id为3的记录,封装到数组中
public static void testFinfId() {
String sql = "select *from `bank` where userid=?";
try {
Object[] o1 = qr.query(sql, new ArrayHandler(), 3);
System.out.println(Arrays.toString(o1));
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
/*
* 2.查找到所有的用户的信息
* 查询所有数据,封装到List集合中
* ArrayListHandler可以将每条数据先封装到数组中, 再将数组封装到集合中
* */
public static void testFindAll() throws SQLException {
String sql = "select *from `bank`";
List<Object[]> list = qr.query(sql, new ArrayListHandler());
for (Object[] objects :
list) {
System.out.println(Arrays.toString(objects));
}
}
/*
*3.查询id为3的记录,封装到指定JavaBean中
* BeanHandler 将结果集的第一条数据封装到 javaBean中
*/
public static void testFindIdJavaBean() throws SQLException {
//1.编写sql语句
String sql = "select *from `user` where userid=?";
//2.执行查询
User user = qr.query(sql, new BeanHandler<User>(User.class), 3);
System.out.println(user);
}
/*
*4.找到所有的的用户的信息 再将他们保存到集合中
* * 查询所员工信息,封装到JavaBean中再封装到List集合中
* BeanListHandler 将结果集的每一条和数据封装到 JavaBean中 再将JavaBean 放到list集合中
* */
public static void testFindBeanAll() throws SQLException {
String sql = "select *from `user`";
List<User> userList = qr.query(sql, new BeanListHandler<User>(User.class));
for (User user :
userList) {
System.out.println(user);
}
}
/*
* 5.查询姓名是 张百万的用户的信息信息,将结果封装到Map集合中
* * 查询姓名是 张百万的员工信息,将结果封装到Map集合中
* MapHandler 将结果集的第一条记录封装到 Map<String,Object>中
* key对应的是 列名 value对应的是 列的值
*
* */
public static void testFindByName() throws SQLException {
String sql = "select *from `user` where username=?";
Map<String, Object> map = qr.query(sql, new MapHandler(), "王万");
Set<Map.Entry<String, Object>> entries = map.entrySet();
// 遍历集合
for (Map.Entry<String, Object> info :
entries) {
System.out.println(info.getKey()+"="+info.getValue());
}
}
/*6) 查询所有用户的的money总额
* 查询所有员工的薪资总额
* ScalarHandler 用于封装单个的数据
* */
public static void testSum() throws SQLException {
String sql="select Sum(salary)from `bank` ";
Double query = (Double) qr.query(sql, new ScalarHandler<>());
System.out.println(query);
}
}
3.数据库批处理
3.1 什么是批处理
-
批处理(batch) 操作数据库
-
批处理指的是一次操作中执行多条SQL语句,批处理相比于一次一次执行效率会提高很多。
-
当向数据库中添加大量的数据时,需要用到批处理
-
-
举例: 送货员的工作:
- 未使用批处理的时候,送货员每次只能运送 一件货物给商家;
- 使用批处理,则是送货员将所有要运送的货物, 都用车带到发放处派给客户。
3.2 实现批处理
Statement和PreparedStatement都支持批处理操作,
reparedStatement的批处理方式:
(1) 要用到的方法
方法 | 说明 |
---|---|
void addBatch() | 将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中。 通过调用方法 executeBatch 可以批量执行此列表中的命令。 |
int[] executeBatch() | 每次提交一批命令到数据库中执行,如果所有的命令都成功执行了, 那么返回一个数组,这个数组是说明每条命令所影响的行数 |
(2) mysql 批处理是默认关闭的,所以需要加一个参数才打开mysql 数据库批处理,在url中添加
rewriteBatchedStatements=true
例如: url=jdbc:mysql://127.0.0.1:3306/db5?characterEncoding=UTF-8&rewriteBatchedStatements=true
测试批处理
(4) 测试向表中插入 1万条数据
package org.example.jdbc_mysql.org.example.app;
import org.apache.commons.dbutils.QueryRunner;
import org.example.jdbc_mysql.utils.Jdbc_Utils_Druid;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/*
* 测试批处理 插入10000条数据
* */
public class TestBatch {
public static void main(String[] args) {
long start= 0;
try {
Connection con=Jdbc_Utils_Druid.getConnection();
String sql="insert into `testBatch` (name) values(?) ";
//预编译
PreparedStatement statement = con.prepareStatement(sql);
//给参数赋值
for (int i = 0; i <10000 ; i++) {
statement.setString(1,"小强"+i);
statement.addBatch();
}
start = System.currentTimeMillis();
//执行批处理对象
statement.executeBatch();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
long end=System.currentTimeMillis();
System.out.println("插入100万条数据据所需要的时间"+(end-start));
}
}
4.MySql元数据
4.1 什么是元数据
- 除了表之外的数据都是元数据,可以分为三类
- 查询结果信息:
- UPDATE 或 DELETE语句 受影响的记录数。
- 数据库和数据表的信息: 包含了数据库及数据表的结构信息。
- MySQL服务器信息: 包含了数据库服务器的当前状态,版本号等
4.2元数据相关的命令介绍
-- 元数据相关的命令介绍
-- 1.查看服务器当前状态
-- 2.查看MySQl的版本信息
-- 3.查询表中的详细信息
-- 4.显示数据表的详细索引信息
-- 5.列出所有数据库
-- 6.显示当前数据库的所有表
-- 7.获取当前的数据库名
- select version(); 获取mysql服务器的版本信息
- show status; 查看服务器的状态信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OZNQS7Y3-1608535720987)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218152236699.png)]
- show columns from table_name; 显示表的字段信息等,和desc table_name一样
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0lkMBDaq-1608535720988)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218152253582.png)]
- show index from table_name; 显示数据表的详细索引信息,包括PRIMARY KEY(主键)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RJwXHAhX-1608535720992)(C:\Users\syt\AppData\Roaming\Typora\typora-user-images\image-20201218152316698.png)]
- show databases:列出所有数据库
- show tables : 显示当前数据库的所有表
- select database(): 获取当前的数据库名
4.3 使用JDBC 获取元数据
通过JDBC 也可以获取到元数据,比如数据库的相关信息,或者当我们使用程序查询一个不熟悉的表时, 我们可以通过 获取元素据信息,了解表中有多少个字段,字段的名称 和 字段的类型.
4.3.2.1常用类的介绍
元数据类 | 作用 |
---|---|
DatabaseMetaData | 描述数据库的元数据对象 |
ResultSetMetaData | 描述结果集的元数据对象 |
-
获取元数据对象的方法 : getMetaData
-
connection 连接对象, 调用 getMetaData () 方法,获取的是DatabaseMetaData 数据库元数据对象
-
PrepareStatement 预处理对象调用 getMetaData () , 获取的是ResultSetMetaData , 结果集元数据对象
-
-
DatabaseMetaData的常用方法
方法 | 说明 |
---|---|
getURL() | : 获取数据库的URL |
getUserName() | : 获取当前数据库的用户名 |
getDatabaseProductName() | : 获取数据库的产品名称 |
getDatabaseProductVersion() | : 获取数据的版本号 |
getDriverName() | : 返回驱动程序的名称 |
isReadOnly() | : 判断数据库是否只允许只读 true 代表只读 |
4.3.2.2 代码示例
package org.example.jdbc_mysql.org.example.app;
import org.example.jdbc_mysql.utils.Jdbc_Utils_Druid;
import javax.sql.rowset.RowSetMetaDataImpl;
import java.sql.*;
/*
* 获取数据库相关的元数据信息 使用DatabaseMetaData
* */
public class TestMetaData {
public static void main(String[] args) {
try {
testDatabaseMetaData();
testResultSetMetaData();
} catch (Exception throwables) {
throwables.printStackTrace();
}
}
/*
* 获取数据库相关的元数据信息 使用DatabaseMetaData
* */
public static void testDatabaseMetaData() throws SQLException {
//1.获取数据库的连接对象
Connection con = Jdbc_Utils_Druid.getConnection();
//2.获取代表数据库的元数据的对象 DatabaseMetaData
DatabaseMetaData dmd = con.getMetaData();
//3.获取数据库相关的元数据信息
String url = dmd.getURL();
System.out.println("数据库的URL为" + url);
String userName = dmd.getUserName();
System.out.println("用户名" + userName);
String productName = dmd.getDatabaseProductName();
System.out.println("数据库的用户名" + productName);
int version = dmd.getDatabaseMajorVersion();
String driverName = dmd.getDriverName();
System.out.println("数据库的驱动的名称" + driverName);
System.out.println("数据库的版本号" + version);
String driverVersion = dmd.getDriverVersion();
System.out.println("数据库驱动的版本号为" + driverVersion);
//判断数据库是否为只读
boolean b = dmd.isReadOnly();
if (b) {
System.out.println("当前数据库只允许读操作!");
} else {
System.out.println("不是只读的数据库");
}
con.close();
}
//获取查询结果集的元数据信息
public static void testResultSetMetaData() {
Connection con=null;
try {
//1.获取连接Connection
con = Jdbc_Utils_Druid.getConnection();
//2.获取ResltSetMetaDate的对象
PreparedStatement statement = con.prepareStatement("select *from `bank`");
//3.执行sql
statement.executeQuery();
//4.获得结果集的元数据的对象
ResultSetMetaData metaData = statement.getMetaData();
//1.获取结果集的元数据的列数
int columnCount = metaData.getColumnCount();
System.out.println("当前的结果集中共有" + columnCount + "列");
//2.获结果集中 列的名称 和 类型
for (int i = 1; i <=columnCount; i++) {
String ColumName = metaData.getColumnName(i);
System.out.println("列名是" + ColumName);
String ColumType = metaData.getColumnTypeName(i);
System.out.println("类型是" + ColumType);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}