初探JDBC及简单的查询工具类封装(附带MAVEN的安装及使用)
模块一、maven的下载及安装
-
下载
进入官网 链接在这里
然后点击download -
安装
第一、将下载的文件解压
第二、配置环境变量
可以打开dos命令窗口看是否安装成功,输入mvn -v
如此便是配置成功
第三、配置maven本地仓库
在与你的maven文件同级目录下(这是我的D:\apache)新建maven-repository文件夹,该目录用作maven的本地库。(也就是我前面提到新建的那个maven-repository文件夹)
打开D:\apache\apache-maven-3.6.3\conf\settings.xml文件,查找下面这行代码:
/path/to/local/repo
localRepository节点默认是被注释掉的,需要把它移到注释之外,然后将localRepository节点的值改为我们创建的目录D:\apache\maven-repository。
localRepository节点用于配置本地仓库,本地仓库其实起到了一个缓存的作用,它的默认地址是 C:\Users\用户名.m2。
当我们从maven中获取jar包的时候,maven首先会在本地仓库中查找,如果本地仓库有则返回;如果没有则从远程仓库中获取包,并在本地库中保存。
此外,我们在maven项目中运行mvn install,项目将会自动打包并安装到本地仓库中。
运行一下DOS命令
mvn help:system
如果前面的配置成功,那么D:\apache\maven-repository会出现一些文件。
第四、配置Eclipse的Maven环境
打开Window->Preferences->Maven->Installations,右侧点击Add。
选中并且apply
打开Window->Preferences->Maven->User Settings,配置如下并Apply:
至此,Maven的安装和配置全部结束。
模块二、JDBC
一、JDBC简介
JDBC(Java DataBase Connectivity)是Java和数据库之间的一个桥梁,是一个规范而不是一个实现,能够执行SQL语句。它由一组用Java语言编写的类和接口组成。各种不同类型的数据库都有相应的实现,本文中的代码都是针对MySQL数据库实现的。
二、JDBC编程实现Java程序与MySQL的链接
JDBC编程之前的步骤:
-
创建MAVEN工程
这就是创建出来的MAVEN工程 -
导入依赖
首先查询依赖,链接在这里
之后按我图示的步骤操作
第一次进入的话会对你进行人类验证,哈哈
点击之后会有验证,我就不多说了,如果过不了说明你可能不是人类。。。验证有时候会弹出有点慢,耐心等待,毕竟是国外的网站
那么验证之后会出现如下界面
然后打开eclipse
到这里依赖就建立好了,那么就不用再导MySQL的jar包啦,之后的MAVEN会帮你做的
那么接下来就就进入到我们的JDBC编程部分
JDBC编程步骤
// 第一步,加载驱动,实现与MySQL数据库的连接 Class.forName("com.mysql.jdbc.Driver"); // 第二步,建立连接 //jdbc:mysql 表示jdbc协议 //localhost 表示数据库ip地址 //3306 表示数据库端口号 //db_zhangbo 表示数据库名 //useSSL=false 可以消除SSL警告 //后面的"root","123456"这两参数是代表可以操作db_zhangbo这两个数据库权限的用户 Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_zhangbo?useSSL=false", "root", "123456"); // 第三步,使用PreparedStatement接口引用预处理sql语句,参数为字符串形式的sql语句 PreparedStatement pst = con.prepareStatement("select * from t_p1_user limit 10"); // 第四步,使用ResultSet接口引用执行sql语句 ResultSet rs = pst.executeQuery(); // 第五步,处理执行的sql语句执行结果 while (rs.next()) { System.out.println(rs.getInt("uid") + "::" + rs.getString("userName")); } // 第六步,释放资源(连接、结果集、预定义对象) rs.close(); pst.close(); con.close();
如上代码所示,运行之后的效果图如下,
eclipse运行结果:
MySQL运行结果:
从上面代码来看,可以看到我们确实对数据库进行了操作,现在如果我有几个需求:
- 需要操作其他数据库,并且此数据库的权限在其他用户手上,也就是用户名密码也不相同
- 需要操纵其他的数据库软件或者MySQL版本不同,那么驱动不同
- 需要查询其他表的数据,那么url不同
那么你可能会说,在代码上直接修改及就是了,比如下图代码
1、加载驱动
Class.forName("com.mysql.jdbc.Driver"); // 2、建立链接 Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_zhangbo", "root", "123456"); System.out.println(con); // 3、预处理sql语句 // 查询出最近写的10篇博客的标题及摘要,展示到控制台 // 最新使用博客系统的用户 PreparedStatement pst = con.prepareStatement("select * from t_p1_blog order by loginTime desc limit 20"); // 4、执行sql语句 ResultSet rs = pst.executeQuery(); // 5、处理sql语句执行的结果 while (rs.next()) { System.out.println(rs.getInt("bid") + "::" + rs.getString("title")); } // 6、释放资源(链接、结果集、预定义对象) rs.close(); pst.close(); con.close();
但是这样一来就是我们常说的程序的可拓展性太差,这就是没有拓展性的表现,换个需求就换源代码是不科学的
所以,接下来就是用我们之前的学习javase知识对这个功能封装,接下来就是我的设计思想
-
实现驱动,url,用户名,用户密码,sql查询语句,查询内容,查询存储对象与代码的解耦
包结构如上
再utils包下新建一个DBcontent类,最主要作用用来读取驱动,url,用户名,用户名密码信息
package utils; 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 DBcontent { public static String driver;// 驱动信息 public static String url;// 路径 public static String userName;// 用户名 public static String password;// 密码 public static String sqlQuery;// sql查询语句 public static String sqlQueryObject;// 信息存储对象的绝对路径包路径 // 用于初始话属性 static { // 设置输入流并且指定路径("/properties")将文件数据读取到内存中 InputStream in = DBcontent.class.getResourceAsStream("/properties"); // 创建Properties对象用于读取输入流的信息 Properties p = new Properties(); try { // 调用load方法将输入流中的信息读取到Properties对象中 p.load(in); // 给四个静态属性设置值,这里的getProperty方法类似于按键取值 driver = p.getProperty("driver"); url = p.getProperty("url"); userName = p.getProperty("userName"); password = p.getProperty("password"); sqlQuery = p.getProperty("sqlQuery"); sqlQueryObject = p.getProperty("sqlQueryObject"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 用于创建与数据库连接的Connection接口引用 public static Connection getConnection() throws SQLException, ClassNotFoundException { Class.forName(driver); return DriverManager.getConnection(url, userName, password); } }
写完上述代码之后我们只需要再新建一个properties文件到source文件夹下就ok
下面是建立方法,以及文件的书写规范
建立方法:file=>new=>others=>
然后在sources文件夹下面创建properties文件,右键刚创建的sources文件夹=>new=>others
从上面的图示中,可以看出,我们已经将程序和驱动,url,用户名,用户名密码信息
解耦,那么当我们在这些信息方面有不同的需求时,只需要修改properties中的=号右边的值既可以达到我们的需求
-
将需要查询的内容一对象属性的方式存储,再存储到一个list容器中,不同的查询内容只需要新建一个不同的类
在entity包下新建一个pojo类,类的属性便是你想查询的信息
package entity; public class User { private int uid; private String userName; private String password; public User() { super(); // TODO Auto-generated constructor stub } public User(int uid, String userName, String password) { super(); this.uid = uid; this.userName = userName; this.password = password; } public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } 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 uid + "::" + userName + "::" + password; } }
-
新建一个导出类BaseDao类,用以连接并操纵数据库
在dao包下面新建BaseDao类
package dao; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import utils.DBcontent; //专做查询的工具类 public class BaseDao { public static <T> List<T> executeQuery(String sql, Class clz) throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { // 创建一个泛型类的list容器 List<T> list = new ArrayList<T>(); // 调用DBcontent类的静态getConnection方法建立连接; Connection con = DBcontent.getConnection(); // 通过连接获取预处理sql语句的预处理PreparedStatement接口的引用 PreparedStatement pst = con.prepareStatement(sql); // ResultSet接口引用处理sql语句 ResultSet rs = pst.executeQuery(); // 新建泛型类变量 T t; while (rs.next()) { // 通过反射创建出类实例 t = (T) clz.getConstructor(null).newInstance(null); // 获取类实例的所有属性 Field[] fields = clz.getDeclaredFields(); // 遍历属性 for (Field f : fields) { // 将私有属性设置为可修改 f.setAccessible(true); // 对t对象设置其相应属性 // 利用ResultSet类对象的getObject方法,参数属性的名字,所以这里需要注意 // 在设置属性的时候属性名必须完全对应数据库中的列段名 // 比如我设置的Blog类中的其中一个属性bid就和数据库的第一列的字段是一样的 f.set(t, rs.getObject(f.getName())); } // 将设置号属性的t对象添加到list数组中 list.add(t); } // 释放资源 rs.close(); pst.close(); con.close(); return list; } }
到此,我们实现了以上三点,接下来我们来创建一个测试类来测试下
package com.zhang.jdbc02; import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; import dao.BaseDao; import utils.DBcontent; public class Demo1 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, SQLException { String sql = DBcontent.sqlQuery; String sqlObject = DBcontent.sqlQueryObject; Class clz = Class.forName(sqlObject); BaseDao.executeQuery(sql, clz).forEach(System.out::println); } }
测试类结果
那么到此为止,我们如果还有其他需求,比如我想查询另外一张表,那么我们只需新建一个一个类,并且修改propeties中的配置就ok,不需要去修改源代码
比如我修改之后的properties如图所示
新建一个pojo类,查询数据库中t_p1_blog中的信息
类代码如下:
package entity; public class Blog { private int bid; private String title; private String summary; public Blog() { super(); // TODO Auto-generated constructor stub } public Blog(int bid, String title, String summary) { super(); this.bid = bid; this.title = title; this.summary = summary; } public int getBid() { return bid; } public void setBid(int bid) { this.bid = bid; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } @Override public String toString() { return bid + "::" + title + "::" + summary; } }
properties文件设置如下:
再次在Demo1测试类中运行的结果:
本文地址:https://blog.csdn.net/zb15292082496/article/details/107887532