原生Jdbc获取库、表、字段

news2024/11/8 13:45:57

文章目录

    • 一、简介
      • 1、概述
      • 2、Jdbc获取连接
      • 3、执行器
    • 二、获取链接
      • 1、获取链接
      • 2、关闭连接
      • 3、Statement
      • 4、PrepatedStatement
      • 5、 ResultSet
      • 6、ResultSetMetaData
    • 三、执行SQL
      • 2.1 增/删/改
      • 2.2 查询
    • 四、获取库、表结构
      • 1、获取Catalog
      • 2、获取库列表
      • 3、获取表名
      • 4、获取字段


一、简介

1、概述

  • JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。
  • JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
  • JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。

在这里插入图片描述

2、Jdbc获取连接

在这里插入图片描述

  • 1、加载驱动
  • 2、建立连接
  • 3、创建Statement对象
  • 4、执行SQL
  • 5、关闭连接
String jdbcdriver = "";
String url = "";
String username = "";
String password = "";
String sql = "";
//    1、加载驱动
Class.forName(jdbcdriver);
//    2、建立连接
Connection conn = DriverManager.getConnection(url, username, password);
//    3、创建Statement对象
PreparedStatement ps = conn.prepareStatement(sql);
//    4、执行SQL
ps.executeQuery();
//    5、关闭连接
conn.close();
ps.close();
closeConn(conn, ps);

3、执行器

在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:

  • Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
  • PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。
  • CallableStatement:用于执行 SQL 存储过程

在这里插入图片描述

二、获取链接

1、获取链接

 //    1、加载驱动
 Class.forName(jdbcdriver);
 //    2、建立连接
 Connection conn = DriverManager.getConnection(url, username, password);

2、关闭连接

//    5、关闭连接
conn.close();
ps.close();
closeConn(conn, ps);
public static <T> void close(T... t) {
    for (T one : t) {
        if (one instanceof AutoCloseable) {
            try {
                ((AutoCloseable) one).close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

方式二:

/**
 * 
 * @Description 关闭资源操作
 * @author shkstart
 * @date 上午10:21:15
 * @param conn
 * @param ps
 * @param rs
 */
public static void closeResource(Connection conn,Statement ps,ResultSet rs){
	try {
		if(ps != null)
			ps.close();
	} catch (SQLException e) {
		e.printStackTrace();
	}
	try {
		if(conn != null)
			conn.close();
	} catch (SQLException e) {
		e.printStackTrace();
	}
	try {
		if(rs != null)
			rs.close();
	} catch (SQLException e) {
		e.printStackTrace();
	}
}

3、Statement

Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。

但是使用Statement操作数据表存在弊端:

  • 问题一:存在拼串操作,繁琐
  • 问题二:存在SQL注入问题
// 1、加载驱动
Class.forName(driverClass);
// 2、获取连接
Connection conn = DriverManager.getConnection(url, user, password);
//	3、获取执行器
Statement st = conn.createStatement();
//	4、执行查询
ResultSet rs = st.executeQuery(sql);
//	5、获取结果集的元数据
ResultSetMetaData rsmd = rs.getMetaData();

4、PrepatedStatement

PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。

  • 可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取 PreparedStatement 对象

  • PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句

  • PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值

使用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);
			
		}
	}

使用PreparedStatement实现查询操作


5、 ResultSet

问题1:得到结果集后, 如何知道该结果集中有哪些列 ? 列名是什么?

​ 需要使用一个描述 ResultSet 的对象, 即 ResultSetMetaData

在这里插入图片描述

  • 查询需要调用PreparedStatement 的 executeQuery() 方法,查询结果是一个ResultSet 对象

  • ResultSet 对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商提供实现

  • ResultSet 返回的实际上就是一张数据表。有一个指针指向数据表的第一条记录的前面。

  • ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 next() 方法移动到下一行。调用 next()方法检测下一行是否有效。若有效,该方法返回 true,且指针下移。相当于Iterator对象的 hasNext() 和 next() 方法的结合体。

  • 当指针指向一行时, 可以通过调用 getXxx(int index) 或 getXxx(int columnName) 获取每一列的值。

    • 例如: getInt(1), getString(“name”)
    • 注意:Java与数据库交互涉及到的相关Java API中的索引都从1开始。
  • ResultSet 接口的常用方法:

    • boolean next()

    • getString()

    在这里插入图片描述

6、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):指示是否自动为指定列进行编号,这样这些列仍然是只读的。

在这里插入图片描述

三、执行SQL

2.1 增/删/改

	//通用的增、删、改操作(体现一:增、删、改 ; 体现二:针对于不同的表)
	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);
			
		}
	}

2.2 查询

使用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;

	}

四、获取库、表结构

1、获取Catalog

/**
 * 获取catalog
 *
 * @param jdbcdriver 驱动类(DriverClass)(com.mysql.cj.jdbc.Driver)
 * @param url        地址(jdbc:mysql://10.20.30.40:3306)
 * @param username   用户名
 * @param password   密码
 */
public List<String> getCatalogs(String jdbcdriver, String url, String username, String password) throws ClassNotFoundException, SQLException {
    ArrayList<String> list = new ArrayList<>();
    //    1、加载驱动
    Class.forName(jdbcdriver);
    //    2、建立连接
    Connection conn = DriverManager.getConnection(url, username, password);
    try {
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet resultSet = metaData.getCatalogs();
        while (resultSet.next()) {
            String string = resultSet.getString("TABLE_CAT");
            list.add(string);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        conn.close();
    }
    return list;
}

2、获取库列表

/**
 * 获取数据库
 *
 * @param jdbcdriver 驱动类(DriverClass)(com.mysql.cj.jdbc.Driver)
 * @param url        地址(jdbc:mysql://10.20.30.40:3306)
 * @param username   用户名
 * @param password   密码
 * @param catalogs   catalogs
 */
public List<String> getDatabase(String jdbcdriver, String url, String username, String password, String catalogs) throws ClassNotFoundException, SQLExcepti
    ArrayList<String> list = new ArrayList<>();
    //    1、加载驱动
    Class.forName(jdbcdriver);
    //    2、建立连接
    Connection conn = DriverManager.getConnection(url, username, password);
    try {
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet resultSet = metaData.getSchemas(catalogs, null);
        //  没有catalog可以采用下面这种方式
        //  ResultSet resultSet = metaData.getSchemas();
        while (resultSet.next()) {
            String string = resultSet.getString("TABLE_SCHEM");
            list.add(string);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        conn.close();
    }
    return list;
}

3、获取表名

/**
 * 获取表
 *
 * @param jdbcdriver 驱动类(DriverClass)(com.mysql.cj.jdbc.Driver)
 * @param url        地址(jdbc:mysql://10.20.30.40:3306)
 * @param username   用户名
 * @param password   密码
 * @param catalogs   catalogs
 * @param database   数据库
 */
public List<String> getTables(String jdbcdriver, String url, String username, String password, String catalogs, String database) throws ClassNotFoundException, SQLException {
    List<String> list = new ArrayList<>();
    //    1、加载驱动
    Class.forName(jdbcdriver);
    //    2、建立连接
    Connection conn = DriverManager.getConnection(url, username, password);
    try {
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet tables = metaData.getTables(
                catalogs,
                database,
                "%",
                new String[]{"TABLE", "VIEW"});
        while (tables.next()) {
            String name = tables.getString("TABLE_NAME");
            list.add(name);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        conn.close();
    }
    return list;
}

4、获取字段

/**
 * 获取字段
 *
 * @param jdbcdriver 驱动类(DriverClass)(com.mysql.cj.jdbc.Driver)
 * @param url        地址(jdbc:mysql://10.20.30.40:3306)
 * @param username   用户名
 * @param password   密码
 * @param catalogs   catalogs
 * @param database   库
 * @param table      表
 */
public List<JSONObject> getColumns(String jdbcdriver, String url, String username, String password, String catalogs, String database) throws ClassNotFoundException, SQLException {
    List<JSONObject> list = new ArrayList<>();
    //    1、加载驱动
    Class.forName(jdbcdriver);
    //    2、建立连接
    Connection conn = DriverManager.getConnection(url, username, password);
    try {
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet rs = metaData.getColumns(catalogs, database, table, "%");
        while (rs.next()) {
            JSONObject json = new JSONObject();
            //  列明
            json.put("columnName", rs.getString("COLUMN_NAME"));
            //  列类型
            json.put("typeName", rs.getString("TYPE_NAME"));
            //  列备注
            json.put("remarks", rs.getString("REMARKS"));
            list.add(json);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        conn.close();
    }
    return list;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/672016.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么本地部署的低代码平台更有优势?

编者按&#xff1a;快速发展的企业需要跟上不断变化的市场趋势。在这种环境下&#xff0c;低代码开发平台可以成为企业快速进入市场的利器。低代码开发的优势可以影响新软件的交付速度&#xff0c;而可视化开发是推动这种无与伦比的速度的关键功能。私有化部署方案和源码交付机…

27-2BP_Adaboost强分类器公司财务预管建模——强分类器和弱分类器(附matlab程序)

1.简述 Adaboost算法的思想是合并多个“弱”分类器的输出以产生有效分类。其主要步骤为&#xff1a;首先给出弱学习算法和样本空间&#xff08;x,y&#xff09;&#xff0c;从样本空间中找出m组训练数据&#xff0c;每组训练数据的权重都是1/m。然后用弱学习算法迭代运算T次&am…

SIP协议学习笔记

SIP 协议(Session initialization Protocol)会话发起协议 是IETF制定的多媒体通信协议&#xff0c;是一个基于文本的应用层控制协议&#xff0c;用于建立&#xff0c;修改和终止IP网上的双方或多方的多媒体会话,支持代理、重定向、登记定位用户等功能 支持用户的移动&#xff…

Packet Tracer - 使用思科 IOS 配置 DHCP

Packet Tracer - 使用思科 IOS 配置 DHCP 地址分配表 设备 接口 IPv4 地址 子网掩码 默认网关 R1 G0/0 192.168.10.1 255.255.255.0 不适用 S0/0/0 10.1.1.1 255.255.255.252 不适用 R2 G0/0 192.168.20.1 255.255.255.0 不适用 G0/1 已分配 DHCP 已分配 …

python安装/卸载模块方法步骤详解(附详细图解)

在日常工作中会需要安装或者卸载Python模块.于是我整理了一下,下面这篇文章主要给大家介绍了关于python安装/卸载模块的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下 以pygame模块举例 1&#xff0c;通过pycharm导入 &#xff08;1&#xff09;直接点击install …

Redis 2023面试5题(三)

一、Redis集群数据hash分片算法是怎么回事&#xff1f; Redis集群数据hash分片算法是一种将数据分散存储在不同的节点上来实现的机制。具体来说&#xff0c;Redis集群将数据分成16384个槽位&#xff0c;每个槽位对应一个节点。当需要访问某个key时&#xff0c;Redis会根据key的…

nginx主配置文件及实战案例

文章目录 一.nginx主配置文件nginx.conf1.认识nginx服务的主配置文件2.全局配置3.I/O事件配置4.HTTP配置&#xff15;.检查配置文件是否正确&#xff16;.浏览器测试&#xff17;.总配置文件图示&#xff17;.1 nginx总配置文件的三个模块&#xff17;.2 HTTP文件配置的图示&am…

【Matlab】语音信号分析与处理实验报告

一、目的 使用Matlab分析与设计实验&#xff0c;理解与掌握以下知识点&#xff1a; 1、信号的采样、频谱混叠 2、信号的频谱分析 3、信号的幅度调制与解调方法 4、理想滤波器的时域和频域特性 5、数字滤波器的设计与实现 二、内容 1、录制一段个人的语音信号 2、采用合适的频…

Unity3D制作一个会移动的方块(还不会移动照相机)

学习Unity3D这么久了&#xff0c;如果你还不会制作一个按下WASD就可以移动的方块的话&#xff0c;那么你的学习将没有一点成就感&#xff0c;我学习的时候&#xff0c;我决定先学习移动&#xff0c;这样我就会对Unity更加感兴趣&#xff0c;学习起来的动力会更为充足 先创建一…

Nseeus安装及使用教程

Nessus是一款目前使用较多的系统漏洞扫描与分析软件 文章目录 Nessus下载安装使用启动:https://localhost:8834/ Nessus Nessus是一款目前使用较多的系统漏洞扫描与分析软件 下载 下载链接&#xff1a;https://www.tenable.com/downloads/nessus 安装 傻瓜式安装 使用 最…

Baumer工业相机堡盟工业相机如何使用新版本NEOAPI SDK控制相机数据流的开启和关闭(C++)

Baumer工业相机堡盟工业相机如何使用新版本NEOAPI SDK控制相机数据流的开启和关闭&#xff08;C&#xff09; Baumer工业相机Baumer工业相机NEOAPI SDK的技术背景Baumer工业相机使用NEOAPISDK控制相机数据流的方式1.引用合适的类文件2.使用NEOAPISDK控制相机数据流的方式2.使用…

Xshell 连接虚拟机Ubuntu系统失败解决方案

背景知识&#xff1a; Xshell 是一个强大的安全终端模拟软件&#xff0c;可以进行远程登录&#xff0c;它支持 SSH1, SSH2, 以及 Microsoft Windows 平台的 TELNET 协议。 xshell通过ip连接&#xff0c;所以需要知道虚拟机的IP地址 使用XShell的主要目的是在Windows环境下登…

leetcode111. 二叉树的最小深度(java)

二叉树的最小深度 leetcode111. 二叉树的最小深度题目描述 DFS 深度优先遍历解题思路代码演示 BFS 广度优先遍历解题思路代码演示 往期经典 leetcode111. 二叉树的最小深度 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problem…

基于立创EDA的原理图设计

目录 学习目标 一、开发中原理图的作用 1.1 原理图 1.2 产品开发原理图设计阶段 1.3 原理图中的具体工作内容 二、 立创EDA软件使用基础 2.1 立创EDA电路设计软件 2.2 新建工程 2.3 设计元件原理图封装 三、项目实战&#xff08;单片机最小系统&#xff09; 学习目标…

Kaggle 比赛总结:BirdCLEF 2023

赛题名称&#xff1a;BirdCLEF 2023赛题任务&#xff1a;识别音景中的鸟叫声赛题类型&#xff1a;语音识别 https://www.kaggle.com/competitions/birdclef-2023文章目录 一、比赛背景二、比赛任务三、评价方法四、优胜方案4.1 第一名4.2 第二名4.3 第三名4.4 第四名4.5 第五名…

SpringCloud Alibaba入门2之用户子模块开发

在上一章的基础上进行子模块的开发SpringCloud Alibaba入门之创建多模块工程_qinxun2008081的博客-CSDN博客 一、引入SpringBoot 我们在父项目统一管理引入的jar包的版本。我们采用父项目中以depencyMangement方式引入spring-boot&#xff0c;子项目依赖parent父配置即可。 &…

CTFshow-pwn入门-前置基础pwn29-pwn31

什么是PIE 由于ASLR是一种操作系统层面的技术&#xff0c;而二进制程序本身是不支持随机化加载的&#xff0c;便出现了一些绕过方法&#xff0c;例如ret2plt、GOT劫持、地址爆破等。于是&#xff0c;人们于2003年引入了位置无关可执行文件&#xff08;Position-Independent Ex…

24. Vue防抖,禁止double click

Vue 防抖 如果按钮不做防抖限制&#xff0c;用户手滑或者其他场景大概率会出现重复调用接口的情况&#xff0c;比如编辑角色时&#xff0c;多次点击submit&#xff0c;会出现非预期请求。 为避免重复点击问题&#xff0c;可以加一个自定义组件将按钮禁用一段时间。 监听click时…

详解Java锁对象

1、Synchronized 1.1、synchronized特性 1、互斥 synchronized会起到互斥效果&#xff0c;某个线程执行到某个对象的synchronized中时&#xff0c;其他线程如果也执行到同一个对象synchronized就会阻塞等待。 *进入synchronized修饰的代码块&#xff0c;就相当于加锁。 *退…

10.安装dashboard

有了之前我们部署的 keystone 、 glance 、 nova 、 neutron 服务之后&#xff0c;我们就可以启动云主机了&#xff0c;但是如果只是使用命令来操作OpenStack 的话非常不方便&#xff0c;我们使用OpenStack 搭建云平台就是为了把底层所有资源整合在一起&#xff0c;然后以一种方…