我是靠谱客的博主 潇洒菠萝,最近开发中收集的这篇文章主要介绍JdbcUtil类,jdbcl连接Oracle数据库,封装增删改查方法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

JDBCUtil :

package com.macw.util;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
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<Connection> tl = new ThreadLocal<Connection>();
	// 把流操作提取到静态代码块里面。
	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指类中所有的方法
	 * 
	 */
	
	
	/**
	 * 查询多条
	 * <T>  是用来规范泛型的,
	 * @throws SQLException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * 
	 */
	public static <T> List<T> select(String sql,Class<T> clz,Object...obj) throws SQLException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<T> 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类型
							/**
							 * rs.getInt("id"); 那么number类型就被转换成了int类型;
							 * rs.getDouble("price");那么number类型就转换成了double类型
							 * rs.getObject("列名"); 那么返回的实际类型是java.math.BigDecimal;
							 * Bigdecimal 没有精度损失,多用户银行等的金融计算;
							 */
//							value如果是Bigdecimal类型,意味着在数据库中是number类型
//							所以需要强转成int或者double类型
							if (value == null) {//如果有空的数据,不再强转直接跳过
								continue;
							}
							else if (value instanceof BigDecimal) {
									Class<?> c2 = m.getParameterTypes()[0];
									if (c2.getName().equals("java.lang.Integer")) {
										value = ((BigDecimal)value).intValue();
									}else
										if(c2.getName().equals("double")){
										value = ((BigDecimal)value).doubleValue();
									}
									else
										if(c2.getName().equals("int")){
										value = ((BigDecimal)value).intValue();
									}
							}
							//动态执行set方法
							m.invoke(t, value);
						}
					}
					
				}
				//while每循环一次,就创建一个实体类对象,给对象的属性赋值,
//				然后将对象存储到list集合中
				list.add(t);
			}
			
		}finally{
			toClose(null, ps, rs);
		}
		return list;
	}
	
}

jdbcUtil工具类的使用:
如下所示:

查询方法:

public User selectByNameAndPwd(String username, String password) {
		// TODO Auto-generated method stub
		String sql = "select * from t_user where username = ? and password = ?";
		User u = null;
		try {
			List<User> list = JdbcUtil.select(sql, User.class,username,password);
			for (User user : list) {
				u = new User(user.getUser_id(),user.getUsername(),user.getPassword());
			}
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return u;
		
	}
}

增删改方法:
增删改都是一样的,都是调用JdbcUtil的update方法,因为增删改执行的方法都是没有返回值的,所以可以统一处理!
简化jdbc重复代码!

 
	public void updatePwd(int id,String newPassword) {
		// TODO Auto-generated method stub
		try {
			String sql = "update t_user set password = ? where user_id = ?";
			JdbcUtil.update(sql, newPassword,id);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

最后

以上就是潇洒菠萝为你收集整理的JdbcUtil类,jdbcl连接Oracle数据库,封装增删改查方法的全部内容,希望文章能够帮你解决JdbcUtil类,jdbcl连接Oracle数据库,封装增删改查方法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部