JdbcUtil类,jdbcl连接Oracle数据库,封装增删改查方法

import java.sql.ResultSet;

import java.sql.ResultSetMetaData;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;

import java.util.Properties;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

/**

  • @author 超伟

  • @2019年5月29日 下午3:48:26

  • @博客:https://blog.csdn.net/MacWx

*/

public class JdbcUtil {

public static DataSource ds;

public static final ThreadLocal tl = new ThreadLocal();

// 把流操作提取到静态代码块里面。

static {

InputStream in = null;

// 创建连接池对象

try {

// 创建出Properties对象

Properties prop = new Properties();

in = JdbcUtil.class.getResourceAsStream(“/druid.properties”);

// 读取文件中的数据

prop.load(in);

// 创建连接池对象

ds = DruidDataSourceFactory.createDataSource(prop);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

throw new RuntimeException(e);

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

throw new RuntimeException(e);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally {

if (in != null) {

try {

in.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

/**

  • @return

*/

public static Connection getConnection() {

//优先从线程中获取连接

Connection conn = tl.get();

// 如果没有拿到这个线程,就说明是业务类在调用

//如果从线程中获取失败,则再新建和数据库的连接

if (conn == null) {

try {

// 用数据库连接池来获取数据库连接

conn = ds.getConnection();

tl.set(conn);

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

throw new RuntimeException(e);

}

}

return conn;

}

/**

  • @param conn

  • @param ps

  • @param rs

*/

public static void toClose(Connection conn, PreparedStatement ps,

ResultSet rs) {

try {

// 代码不用改,但是含义改变了,把这个连接归还给数据库连接池

// //为了代码的健壮性,需要增加非空判断

if (rs != null) {

rs.close();

}

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// 释放ps对象,关闭资源的时候需要注意顺序,后创建的对象,要先关闭。

try {

if (ps != null) {

ps.close();

}

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

try {

if (conn != null) {

conn.close();

//关闭连接,要从线程中移除

tl.remove();

}

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

/**

  • 使用jdbc对于增删改方法的封装

  • 对于增删改方法,仍有大部分的冗余代码,但在这些冗余代码中又有一些是不同的

  • 例如sql语句,以及传入的参数,所以可把相同的代码封装,不同的代码抽取

  • 这只是代码的简化,并不是程序的优化

  • @param sql 对于sql语句的抽取

  • @param obj 可变长参数

  • 可变长参数必须是最后一个形参,也只能有一个这样的形参

  • 在该方法内部,将obj当成一个数组使用。

  • @throws SQLException

*/

public static void update(String sql,Object…obj) throws SQLException{

Connection conn = null;

PreparedStatement ps = null;

try{

//调用本类中的获取连接方法

conn = getConnection();

ps = conn.prepareStatement(sql);

//再判断传入的参数是否为空

if (obj != null) {

//如果不为空则挨个赋值

for (int i = 0; i < obj.length; i++) {

ps.setObject(i+1, obj[i]);

}

}

ps.executeUpdate();

//这里不用catch异常是因为要在dao中去处理

}finally{

//这里的conn连接不要关,在services层中去关闭!在services中处理事务!

toClose(null, ps, null);

}

}

/*

  • 反射:

  • 什么是类对象和类的对象?

  • Student s = new Student();

s是类的对象,是某一个类创建出来的对象,这个类是Student

//1.在运行期加载一个类到虚拟机中

Class c = Class.forName(“com.macw.Student”);

//c就是Student的类对象

//2. 通过反射创建Student类的对象

Object o = c.newInstance();

//o 是Student类的对象

//3.获取Student类指定的方法 和 获取所有的方法

Method method = c.getMethod(“方法名”,形参类型);

//method指某一个方法

method.invoke(对象,实参); //动态调用该方法

Method[] methods = c.getMethods();

//methods指类中所有的方法

*/

/**

  • 查询多条

  • 是用来规范泛型的,

  • @throws SQLException

  • @throws IllegalAccessException

  • @throws InstantiationException

  • @throws InvocationTargetException

  • @throws IllegalArgumentException

*/

public static List select(String sql,Class clz,Object…obj) throws SQLException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{

Connection conn = null;

PreparedStatement ps = null;

ResultSet rs = null;

List list = null;

try {

conn = getConnection();

// 1,预加载SQL语句

ps = conn.prepareStatement(sql);

// 2,设置占位符

if (obj != null) {

for (int i = 0; i < obj.length; i++) {

ps.setObject(i+1, obj[i]);

}

}

// 3,执行SQL语句

rs = ps.executeQuery();

// 获取查询结果集中的元数据

// 元数据可以理解为查询结果中的列名

ResultSetMetaData md = rs.getMetaData();

// 获取查询到的列的个数;

int columnCount = md.getColumnCount();

// System.out.println(columnCount);

list = new ArrayList<>();

T t = null;

while(rs.next()){//while每循环一次,代表一行数据。

//clz代表实体类对象,

// 创建实体类的对象

t = clz.newInstance();

for (int i = 0; i < columnCount; i++) {//一行数据有几列就循环几次

// 根据下标获取列名

String columnName = md.getColumnName(i+1);

// 再根据列名获取对应列的值

Object value = rs.getObject(columnName);

// 要将每一列的值赋值给t对象的属性,要要求表中的列名和实体类属性名必须一致!

// 这是通过字符串拼接成 setName();方法

String methodName = “set” + columnName.substring(0, 1).toUpperCase()+

columnName.substring(1).toLowerCase();

// 获取当前实体类中传递过来的所有方法

Method[] methods = clz.getMethods();

// 进行for循环获取所有的set方法

for (Method m : methods) {

// 判断所有的方法中有没有查询结果列名拼成的set方法

// 获取实体类中所有的方法名用:m.getName()方法

if (m.getName().equals(methodName)) {

// Oracle中的number类型对应java中的java.math.BigDecimal类型

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-huRp93mp-1714857790251)]

[外链图片转存中…(img-eA4PZHy9-1714857790252)]

[外链图片转存中…(img-LOeCCjcu-1714857790252)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 29
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值