简介

开门见山的说,java中有一个类叫Properties。该类主要用于读取Java的配置文件,不同的编程语言有自己所支持的配置文件,配置文件中很多变量是经常改变的,为了方便用户的配置,能让用户够脱离程序本身去修改相关的变量设置。就像在Java中,其配置文件常为.properties文件,是以键值对的形式进行参数配置的。
所以,我们可以尝试使用这个类来自动加载一个我们自定义的配置文件。然后,嘿嘿,我们的JDBC封装类就可以更方便一些了。

具体操作

首先,我们要先知道Properties的具体使用方法。emmmm,,网上代码一大堆,这里就直接给出来了:
在这里创建我们的配置文件:

然后代码如下:

Properties pro = new Properties();
pro.load(ReflectTest.class.getClassLoader().getResourceAsStream("pro.properties"));
String v = pro.getProperty("参数名");

代码解析

好了,那么问题来了,,,这几行代码干了什么?为啥就能找到了我们的配置文件?
首先,我们从反射开始讲起,,算了,太长了,这里直接说:反射可以实现是因为java中有个Class类,它的classLoader()可以把我们的字节码文件(.class)加载到内存中。。
等等,是不是发现了什么?嘿嘿,classLoader既然可以加载我们编译后的.class文件,是不是意味着它拥有我们编译后的文件路径
来我们看看我们的target:

okk,可以发现我们的class文件下,除了我们的包,就是我们的配置文件了。当我们的classLoader加载一个.class文件时,我们是不是要输入完整的包名?那就是不是意味着,我们的classLoader的默认路径是我们的classes文件夹?
哈哈,这就破案了。
所以pro.load(ReflectTest.class.getClassLoader().getResourceAsStream("pro.properties"));
其中,ReflectTest.class.getClassLoader()就是在获取我们classLoader的路径,后面的函数顾名思义,就是获取字节流。而这个函数输入的内容,就是配置文件的相对classLoader的路径。
我们根据图可以知道,我们的配置文件就在classes下面,所以直接输入配置文件名字就可以啦。

合并代码

最后,把我们新功能合并到我们上篇的代码中:

package com.sy;import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;/*** @author :byMJC* @date :Created 2022/1/16 19:04* @description:*/public class JDBCUtilPro {private static final String DB_DEIVER = "com.mysql.jdbc.Driver";private static String DB_URL ;private static String DB_USER ;private static String DB_PWD ;private static Connection connection;/*** 静态代码块,注册驱动*/static {try {Class.forName(DB_DEIVER);} catch (ClassNotFoundException e) {e.printStackTrace();}}/*** 解析配置文件* @param configName 文件名* @throws IOException*/private void parseConfig(String configName) throws IOException {Properties properties = new Properties();properties.load(JDBCUtilPro.class.getClassLoader().getResourceAsStream(configName));DB_URL = properties.getProperty("DB_URL");DB_USER = properties.getProperty("DB_USER");DB_PWD = properties.getProperty("DB_PWD");}/*** 获取连接*/private void getConnection(){try {connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PWD);} catch (SQLException throwables) {throwables.printStackTrace();}}/*** 构造器,传入配置文件名* @param configName*/JDBCUtilPro(String configName){try {parseConfig(configName);} catch (IOException e) {e.printStackTrace();}getConnection();}/*** 查询语句封装,返回值根据实体类成员顺序进行赋值* @param sql sql语句* @param args 参数,用List传* @param tClass 返回值列表里的成员类型* @return 返回查询结果的List*/public <T> List<T> selectResultByOrder(String sql, List<?> args, Class<T> tClass){List<T> resList = new ArrayList<>();int columLen;try {if (connection.isClosed()) {getConnection();}// 利用反射获取属性Field[] declaredFields = tClass.getDeclaredFields();// 创建语句PreparedStatement preparedStatement = connection.prepareStatement(sql);// 赋值参数for (int i = 0; i < args.size(); i++) {preparedStatement.setObject(i+1, args.get(i));}// 执行语句ResultSet resultSet = preparedStatement.executeQuery();// 获取返回值的表数据和它的长度ResultSetMetaData metaData = resultSet.getMetaData();columLen = metaData.getColumnCount();while (resultSet.next()) {// 反射构建类Object res = tClass.getDeclaredConstructor().newInstance();// 遍历resultSet的每个属性值for (int i = 0; i < columLen; i++) {// 获取每一个返回对象的参数名String columnName = metaData.getColumnName(i + 1);// 获取对应名的参数Object object = resultSet.getObject(columnName);// 利用反射给res赋值参数declaredFields[i].setAccessible(true);declaredFields[i].set(res, object);}resList.add((T) res);}} catch (Exception e) {e.printStackTrace();return null;}return resList;}/*** 查询语句封装,返回值根据实体类成员名称进行赋值* @param sql sql语句* @param args 参数,用List传* @param tClass 返回值列表里的成员类型* @return 返回查询结果的List*/public <T> List<T>  selectResultByName(String sql, List<?> args, Class<T> tClass){List<T> resList = new ArrayList<>();try {if (connection.isClosed()) {getConnection();}// 利用反射获取属性Field[] declaredFields = tClass.getDeclaredFields();// 创建语句PreparedStatement preparedStatement = connection.prepareStatement(sql);// 赋值参数for (int i = 0; i < args.size(); i++) {preparedStatement.setObject(i+1, args.get(i));}// 执行语句ResultSet resultSet = preparedStatement.executeQuery();// 获取返回值的表数据和它的长度ResultSetMetaData metaData = resultSet.getMetaData();while (resultSet.next()) {// 反射构建类Object res = tClass.getDeclaredConstructor().newInstance();for (Field declaredField : declaredFields) {Object object = resultSet.getObject(declaredField.getName());declaredField.setAccessible(true);declaredField.set(res, object);}resList.add((T) res);}preparedStatement.close();resultSet.close();} catch (Exception e) {e.printStackTrace();return null;}return resList;}/*** 关闭连接*/public void close(){try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}

测试代码:

        JDBCUtilPro jdbcUtilPro = new JDBCUtilPro("JDBCConfig.properties");List<String> list = new ArrayList();List<User1> list1 = jdbcUtilPro.selectResultByName("select * from user", list, User1.class);System.out.println(list1);jdbcUtilPro.close();

运行效果:

从JDBC到手撸极简版Mybaties(3)JDBC自动解析配置文件相关推荐

  1. 10分钟手撸极简版ORM框架!

    最近很多小伙伴对ORM框架的实现很感兴趣,不少读者在冰河的微信上问:冰河,你知道ORM框架是如何实现的吗?比如像MyBatis和Hibernte这种ORM框架,它们是如何实现的呢? 为了能够让小伙伴们 ...

  2. 很多小伙伴不太了解ORM框架的底层原理,这不,冰河带你10分钟手撸一个极简版ORM框架(赶快收藏吧)

    大家好,我是冰河~~ 最近很多小伙伴对ORM框架的实现很感兴趣,不少读者在冰河的微信上问:冰河,你知道ORM框架是如何实现的吗?比如像MyBatis和Hibernate这种ORM框架,它们是如何实现的 ...

  3. 7句话让Codex给我做了个小游戏,还是极简版塞尔达,一玩简直停不下来

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 梦晨 萧箫 发自 凹非寺 量子位 | 公众号 QbitAI 什么,7 ...

  4. 美团推出极简版 为用户提供“米面粮油”等生活用品采购服务

    近日,有用户反馈,安卓应用商店显示,美团更新推出了极简版,对主应用的功能进行了删减,保留了美团主应用中涉及生活用品采购的相关业务.用户在打开极简版后,首页会呈现出采购蔬果.米面水油等生活用品的购买入口 ...

  5. python3web库_基于 Python3 写的极简版 webserver

    基于 Python3 写的极简版 webserver.用于学习 HTTP协议,及 WEB服务器 工作原理.笔者对 WEB服务器 的工作原理理解的比较粗浅,仅是基于个人的理解来写的,存在很多不足和漏洞, ...

  6. openGauss 极简版安装

    openGauss 官网   openGauss 下载地址 支持的操作系统 ● ARM:   ● openEuler 20.03LTS(推荐采用此操作系统)   ● 麒麟V10   ● Asianux ...

  7. Underscore源码阅读极简版入门

    看了网上的一些资料,发现大家都写得太复杂,让新手难以入门.于是写了这个极简版的Underscore源码阅读. 源码: github.com/hanzichi/un- 一.架构的实现 1.1:架构 (f ...

  8. 《重大人生启示录》极简版

    <重大人生启示录>极简版 献给所有活着和将要死去的人们,献给所有历经悲伤的人们 本文摘录了启示录最重要的内容,不必非要看全本,不必购买书 序言 这是极为特殊的历史转折期,物质文明发展到这一 ...

  9. 【极简版GH60】【GH60剖析】【六】修改配列

    说完了GH60的硬件部分,接下来到软件部分,我觉得,软件部分才是极简版GH60的精髓部分,毕竟仅有硬件的话GH60只是一个有手感可以按动的一堆没有功能的按键,而软件让他变成了灵活多变的键盘.通过对软件 ...

最新文章

  1. mysql帐号,权限管理
  2. 粒子群算法组卷_粒子群(PSO)算法概念及代码实现
  3. 【渝粤题库】广东开放大学 商务合同 形成性考核
  4. 直接拿来用!超实用的Java数组技巧攻略
  5. Wayland 1.0 发布,图形服务器
  6. python dataframe 选取字段 特别慢_从parqu读取dask dataframe列重命名速度较慢(er)
  7. hdu 5150 Sit sit sit
  8. 鹅厂员工平均月薪7万刷屏!公司每天赚9.5亿,养5.46万人
  9. linux修改无线网卡hwaddr,在Linux下改无线网卡的mac的地址
  10. 短信验证码开发教程 - 4.后端篇
  11. Oracle数据库(五)用户 ,角色,权限
  12. 计算机微软云同步怎样安装软件,在windows10/8/7系统安装和设置OneDrive 同步文件...
  13. c 语言 时间间隔(多实例测试)
  14. 前端程序员偷懒工具:emmet语法
  15. vim编辑器删除键失效问题
  16. 燕麦云何洋开讲丨真假海盗?黑客杠上好莱坞,还要把电影变成现实
  17. 超详细的MySQL入门教程(五)
  18. Python利用requests抓取页面源代码(基础)
  19. 清华、北大毕业生都去哪里工作了?/他们是风向标
  20. 大公司高级Android工程师技能要求

热门文章

  1. 【LeetCode717】1比特与2比特字符
  2. 重磅!《2022中国开源发展蓝皮书》正式发布
  3. ArcGIS使用笔记(2)——邻近搜索
  4. 如何使用Python tkinter 设计软件登录界面
  5. Locust的学习笔记(一、环境搭建以及初识locust)
  6. C语言字符型变量sex,全国2003年4月高等教育自学考试计算机软件基础(一)试题...
  7. python调用usb相机_如何从OpenCV/Python/OSX中的PointGrey USB相机捕捉帧?
  8. C语言判断字符串为空
  9. Cows and Cars
  10. java.lang.NoSuchMethodException: com.xxx.xxx.xxxinit()