前言
在JavaWeb开发中DBUtil的书写总会存在很多坑,一不小心就会让我们代码跑不通,明明跟案例一模一样,为什么他行我不行呢?今天遇到一个数据源读取不到的情况,拿出来和大家分享一下,希望能对遇到该类问题朋友提供一点点点帮助,话不多说!开整
一、druid是什么?
Druid是一个为大型数据集上的高性能切片和OLAP分析而设计的数据存储,是阿里巴巴旗下的开源的操作数据库的一个数据库连接池,它高性能且简单的操作使它在众多操作数据库的jar文件中占下了一席之地,那么我们该怎么在JavaWeb的项目中正确引用他呢?怎么样避免数据源读取不到的问题呢?
二、使用步骤
1、基本的JavaWeb项目的结构
1.1 创建一个JavaWeb项目
![](https://img-blog.csdnimg.cn/35319afa1eb74a7bb8ec8064142bd5af.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAT2xpT19DSEVO,size_20,color_FFFFFF,t_70,g_se,x_16)
1.2 配置文件的配置
在创建好JavaWeb项目之后,分别在创建WEB-INF中创建一个lib文件夹存放我们的jar包,和一个config文件夹存放我们的properties配置文件(这两个文件夹一定是放在WEB-INF文件夹下面,不然会出现NullPointException异常或无法读取到的情况)
![](https://img-blog.csdnimg.cn/4101d95a30dc46d9b58db3f0cc7bc30f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAT2xpT19DSEVO,size_16,color_FFFFFF,t_70,g_se,x_16)
1.3 !!!重点来了!!!
书写druid.properties里面的内容时,不需要分号结尾,千万不要加' ; ',也不要有其它多余的空格!! 将下面的内容写入文件中
![](https://img-blog.csdnimg.cn/cd30108e2348483aae4b925b5cffc962.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAT2xpT19DSEVO,size_18,color_FFFFFF,t_70,g_se,x_16)
2、DBUtil的代码内容:
package com.olio.Demo.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class DBUtil {
//数据源
static DataSource dataSource;
static {
//加载配置文件
Properties properties = new Properties();
InputStream resourceAsStream = DBUtil.class.getClassLoader().getResourceAsStream("druid.properties");
try {
properties.load(resourceAsStream);
//根据配置文件获取一个数据源
dataSource = DruidDataSourceFactory.createDataSource(properties);
//通过数据源获取连接
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 使用连接池去做
* ① 导入jar包
* ② 提供配置文件【就是需要连接的数据库以及用户名和密码】
* ③ 得到一个数据源DataSource对象
* ④ 获取连接
*/
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
/**
*将所有数据表的操作,抽离成一个公用的方法
* @param sql sql语句
* @param params sql语句对应的参数
* @return
*/
public static boolean executeDML(String sql,Object...params){
try{
//获取连接
Connection connection = getConnection();
//获取预处理的对象
PreparedStatement ps = connection.prepareStatement(sql);
//设置参数
if(null != params){
for (int i = 0; i < params.length; i++) {
//1.给占位符设置参数 2.获取参数
ps.setObject(i+1,params[i]);
}
}
int i = ps.executeUpdate();
return i > 0;
}catch (SQLException sqlException){
sqlException.printStackTrace();
}
return false;
}
/**
*通用的查询;查询一个
* @param sql 查询语句
* @param cls 实体类的字节码对象
* @param params 查询语句里面的占位符
* @param <T> 实体类类型泛型
* @return 就是我们查询到的数据集合
*/
public static <T> T executeDQLGetOne(String sql, Class<T> cls , Object...params){
List<T> ts = executeDQL(sql,cls,params);
if (ts != null && ts.size() > 0){
return ts.get(0);//直接获取第一个结果
}
return null;
}
/**
*通用的查询;需要将我们的数据表信息,封装到List里面进行返回
* @param sql 查询语句
* @param cls 实体类的字节码对象
* @param params 查询语句里面的占位符
* @param <T> 实体类类型泛型
* @return 就是我们查询到的数据集合
*/
public static <T> List<T> executeDQL(String sql, Class<T> cls , Object...params){
try{
Connection connection = getConnection();//获取连接
//预处理sql
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//设置参数
if (null != params){
for (int i = 0; i < params.length ; i++) {
preparedStatement.setObject(i+1,params[i]);
}
}
//执行查询 得到结果集
ResultSet resultSet = preparedStatement.executeQuery();
//获取元素据(我们的列名)
ResultSetMetaData metaData = resultSet.getMetaData();
//列的总数
int columnCount = metaData.getColumnCount();
//用来保存我们所有的表数据
List<T> list = new ArrayList<T>();
T t;//用来保存我们一条数据
//遍历结果集
while(resultSet.next()){//每一行记录的遍历过程中
t = cls.newInstance();//根据字节码文件,构建一个实体类的对象
//获取所有的数据
for (int i = 0; i <= columnCount ; i++) {
//你的查询语句有时候有别名
String columnLabel = metaData.getColumnLabel(i);
//根据列名获取我们的记录
Object object = resultSet.getObject(columnLabel);
//需要将拿到的这一列的记录,放到t对象指定的属性里面;
//需要拿到这个t对象的属性,然后赋值;
//解决方案2:如果Object是NULL没有必要设置了
if (null != object){
try{
Field declaredField = cls.getDeclaredField(columnLabel);;
declaredField.setAccessible(true);
declaredField.set(t,object);
}catch (NoSuchFieldException e){
//代表我们当前这个实体类里面,没有这个属性
e.printStackTrace();
}
}
}
//需要将t对象保存到list
list.add(t);
}
}catch (SQLException sqlException){
sqlException.printStackTrace();
}catch (IllegalAccessException e){
e.printStackTrace();
}catch (InstantiationException e){
e.printStackTrace();
}
return null;
}
}
(以上还包含了DML和DQL的方法),可以忽略或自己做其它的修改
3、测试
写一个Test类测试一下能不能成功获取到数据,或者获取到返回的结果,我这里测试的是登录,我把带码也一并发下,仅供借鉴
![](https://img-blog.csdnimg.cn/278b027097a64582b2ee7e856fa00d71.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAT2xpT19DSEVO,size_20,color_FFFFFF,t_70,g_se,x_16)
![](https://img-blog.csdnimg.cn/ca9f593dc3594bfd9372f67ecab5dcdb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAT2xpT19DSEVO,size_20,color_FFFFFF,t_70,g_se,x_16)
![](https://img-blog.csdnimg.cn/84698abe722044da86c7e34fc0c26e3b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAT2xpT19DSEVO,size_20,color_FFFFFF,t_70,g_se,x_16)
![](https://img-blog.csdnimg.cn/f267478c21c04b29b5c6e17923ce0749.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAT2xpT19DSEVO,size_20,color_FFFFFF,t_70,g_se,x_16)
返回结果:
![](https://img-blog.csdnimg.cn/54f63ad344b548ad81036f97ce77da33.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAT2xpT19DSEVO,size_20,color_FFFFFF,t_70,g_se,x_16)
总结
以上是我在做JavaWeb项目中出现的无法读取数据源,读取的数据源为null的问题,就这个问题本人也是找了很久,最后发现是在druid.properties书写上多了两个分号,导致它读取值为null。问题很小,自己要找也非常花时间,所以也发出来希望对有类似问题的朋友提供一些参考和帮助,以上就是我的全部内容啦,我也会不定期的分享一下自己在项目上遇到的问题和解决方法,希望大家一起进步!