由于最近使用jdbc使用的比较频繁,在使用的过程做了一些简单的封装。
  在这里简单的记录一下,方便以后使用。迷路的大神请勿见笑。
  数据库使用的Oracle。
使用时用dao层类extends类BaseDaoImpl.java

  1. 获取数据库连接的类
    DBConn.java
package com.utils;import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;/*** @author yxln* @function 获取数据库连接*      获取方式   DBConn.getInstance.getConn();*/
public class DBConn {private DBConn() {}// 数据库连接private static DBConn instance = null ;// 数据库配置文件private static Properties props = null ;// 数据池private static BasicDataSource ds = null ;static {try {// 创建本类实例instance = new DBConn() ;props = new Properties() ;// 加载数据库配置文件props.load(DBConn.class.getResourceAsStream("/db.properties"));// 加载驱动类ds = new BasicDataSource() ;ds.setDriverClassName(props.getProperty("driver"));ds.setUsername(props.getProperty("username"));ds.setPassword(props.getProperty("password"));ds.setUrl(props.getProperty("url"));// 设置数据库最大活动数ds.setMaxActive(Integer.parseInt(props.getProperty("maxActive")));} catch (IOException e) {e.printStackTrace();}}/*** 获取数据库连接* @return*/public Connection getConn() {Connection conn = null ;try {// 数据库连接conn = ds.getConnection();} catch (SQLException e) {e.printStackTrace();}return conn ;}/*** @author yxln* @function 关闭数据库操作先关的一些的* @date 2018年9月29日* @param conn 数据库连接Connection* @param sm 执行sql的Statement* @param rs 结果集REsultSet*/public static void closeConn(Connection conn, Statement sm,ResultSet rs ) {try {if(rs != null) {rs.close();}} catch (SQLException e1) {e1.printStackTrace();}finally {if(null != sm) {try {sm.close();} catch (SQLException e) {e.printStackTrace();}finally {try {if(null != conn) {conn.close();}} catch (SQLException e) {e.printStackTrace();}}}}}/*** @author yxln* @function 关闭数据库操作先关的一些的* @date 2018年9月29日* @param conn 数据库连接Connection* @param sm 执行sql的PreparedStatement* @param rs 结果集REsultSet*/public static void closeConn(Connection conn, PreparedStatement ps,ResultSet rs ) {try {if(rs != null) {rs.close();}} catch (SQLException e1) {e1.printStackTrace();}finally {if(null != ps) {try {ps.close();} catch (SQLException e) {e.printStackTrace();}finally {try {if(null != conn) {conn.close();}} catch (SQLException e) {e.printStackTrace();}}}}}public static DBConn getInstance() {return instance;}
}
  1. 数据库中查询的数据ResultSet映射到实体类
    ObjectMapping.java
package com.utils;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** 将数据库中查询的数据ResultSet映射到实体类 * @author YinXilin* @param <T> 要转换的实体类*/
@SuppressWarnings("unchecked")
public class ObjectMapping<T> {CommonUtils<T> common = new CommonUtils<>() ;/*** 将ResultSet类型的数据转换成实体类domain* @param rs 从数据库中的查询到的结果集* @param domain 结果数据的实体类* @return*/public List<T> mapping(ResultSet rs,Class<?> domain) {List<T> list = null ;T t = null ;if(null != rs) {try {// 实体类中的属性Field[] fields = null ;// 利用反射执行实行实体类中的方法Method method = null ;// 从结果集中的获取的值String value = "" ;// 遍历结果集list = new ArrayList<T>() ;while(rs.next()) {// 实例化实体类t = (T) domain.newInstance() ;try {// 获取实体类中的所有属性fields = domain.getDeclaredFields() ;// 循环遍历实体类中的属性for(int i = 0 ; i < fields.length ; i++) {// 获得属性名String fieldName = fields[i].getName() ;// 如果属性名为 serialVersionUID , 不行执行操作,跳过此次循环if("serialVersionUID".equals(fieldName)) {continue ;}// 获取属性的类型Class<?> fieldType = fields[i].getType() ;// 获取实体类中的方法method = domain.getMethod(common.getMethodName(fieldName),fieldType) ;// 从结果集中获取实体类的属性对应的字段的值String str = common.attributeNameToFieldName(fieldName) ;value = rs.getString(str) ;if(value != null && value.length() > 0 && !"null".equals(value)) {// 实体类的对象t 利用反射调用实体类中的方法(将结果集中的值value映射到实体类中)// 如果这里报argument type mismatch异常,有可能是 convert方法没有对这种数据进行转换method.invoke(t, convert(fieldType, value)) ; }}} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();}list.add(t) ;}} catch (SQLException e) {e.printStackTrace();} catch (InstantiationException e2) {e2.printStackTrace();} catch (IllegalAccessException e2) {e2.printStackTrace();}}return list ;}/*** 将源数据转换成制定的类型* @param fieldType 需要转换成的制定的类型* @param origin 需要转换的源数据* @return 转换成目标类型后的数据*/public Object convert(Class<?> targetType,String origin){// 转换的目标类型或元数据为空,则无法转换,直接返回源数据if(null == targetType || null == origin) {return origin ;}// 将源数据转换成Integer类型if(targetType.equals(Integer.class)) {return Integer.parseInt(origin) ;// 将源数据转换成Date类型}else if(targetType.equals(Date.class)) {Date date = null ;try {date = new SimpleDateFormat("yyyy-MM-dd").parse(origin) ;} catch (ParseException e) {e.printStackTrace();}return date ;}else if(targetType.equals(Double.class)) {return Double.parseDouble(origin) ;}return origin ;}
}
  1. CRUD基本操作接口
    IBaseDao.java
package com.dao;import java.util.List;
import java.util.Map;/*** @author yxln* @function * @date 2018年10月18日*/
public interface IBaseDao<T> {/** 插入单条数据 */public int insert(String sql,Object... args);/** 通过po插入单条数据*/public int insertPo(T po);/** 查询单条数据*/public T query(String sql ,Object... paras) ;/** 分页查找数据*/public List<T> queryListByPage_Oralce(String sql ,Map<String,Object> map)  ;/** 多条件、单次数据删除*/public int delete(String sql , Object... args) ;/** 批量删除*/public void deleteBatches(String sql,Object[]... args) ;/** 修改数据*/public int update(String sql,Object... paras) ;}
  1. CRUD实现类
    BaseDaoImpl.java
package com.dao.impl;import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
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 java.util.Map;
import java.util.Set;import com.dao.IBaseDao;
import com.utils.CommonUtils;
import com.utils.DBConn;
import com.utils.ObjectMapping;/*** @author yxln* @param <T>* @function * @date 2018年10月18日*/
public class BaseDaoImpl<T> implements IBaseDao<T>{// 数据库连接Connection conn = null ;// sql预处理对象PreparedStatement ps = null ;// 结果集对象ResultSet rs = null ;// 工具类CommonUtils<T> common = null ;// 结果集映射对象ObjectMapping<T> objMapping = new ObjectMapping<T>() ;private Class clazz ;/*** @author yxln* @function 添加数据* @date 2018年10月18日* @param sql* @return*/public int insert(String sql,Object... args) {// 获取数据库连接conn = DBConn.getInstance().getConn() ;int flag = 0 ;try {// 对sql语句进行预处理ps = conn.prepareStatement(sql) ;if(args != null) {int paramIndex = 1 ;for(Object obj:args) {// 当前的值如果为java时间(java.util.Date())类型,需要转换成java.sql.Date()if("java.util.Date".equals(obj.getClass().getName())) {ps.setObject(paramIndex++, new java.sql.Date(((java.util.Date) obj).getTime()));}else {ps.setObject(paramIndex++, obj);}}}flag = ps.executeUpdate() ;} catch (SQLException e) {e.printStackTrace();}finally {DBConn.closeConn(conn, ps, null);}return flag;}/*** @author yxln* @function 将实体类中的数据插入到数据库中* @date 2018年10月18日* @param po 实体类对象(持久对象) *          -- 实体类名一定要和数据库表明一样,*             -- 实体类中的属性和数据库字段对应,属性必须采用驼峰命名法,数据库中_后面的字母大写   * @return*/public int insertPo(T po) {common = new CommonUtils<>() ;// 取出实体类中的属性名与对应的值Map<String,Object> attrs = common.getObjectAttribute(po) ;// 获取实体类的类名String className = po.getClass().getSimpleName().toUpperCase() ;// 错做数据数据库结果int flag = 0 ;// 将实体类中的数据插入数据库的sql语句 的前半段StringBuffer sqlHalf1 = new StringBuffer("insert into "+ className + "(");// sql 语句的后半段StringBuffer sqlHalf2 = new StringBuffer("values(");// 根据实体类中的属性拼接sql语句for(String key:attrs.keySet()) {sqlHalf1.append(common.attributeNameToFieldName(key).toUpperCase() + ",") ;sqlHalf2.append("?,") ;}sqlHalf1.deleteCharAt(sqlHalf1.length()-1).append(") ") ;sqlHalf2.deleteCharAt(sqlHalf2.length()-1).append(") ") ;// 获取数据连接conn = DBConn.getInstance().getConn() ;try {// 对sql语句进行预处理ps = conn.prepareStatement(sqlHalf1.append(sqlHalf2).toString()) ;int paramIndex = 1 ;// 遍历attrs,将其中的值设置到预处理sql中对应的占位符上for(Object obj:attrs.values()) {// 当前的值如果为java时间(java.util.Date())类型,需要转换成java.sql.Date()if("java.util.Date".equals(obj.getClass().getName())) {ps.setObject(paramIndex++, new java.sql.Date(((java.util.Date) obj).getTime()));}else {ps.setObject(paramIndex++, obj);}}// 执行查询的sql语句flag = ps.executeUpdate() ;} catch (SQLException e) {e.printStackTrace();}finally {DBConn.closeConn(conn, ps, null);}return flag;}/*** @author yxln* @function 查询单条数数据并将结果映射到实体类* @param sql* @param paras* @return* @date 2018年10月31日*/public T query(String sql ,Object... paras) {conn = DBConn.getInstance().getConn() ;ResultSet rs = null ;T t = null ;try {ps = conn.prepareStatement(sql) ;if(paras != null && paras.length > 0) {for(int i = 0 ; i < paras.length ; i++)ps.setObject(i + 1, paras[i]);}rs = ps.executeQuery() ;Type type = (ParameterizedType) this.getClass().getGenericSuperclass();if(type instanceof ParameterizedType) {this.clazz = (Class) ((ParameterizedType)type).getActualTypeArguments()[0];}else {System.out.println("【异常】没有给定泛型的类型");}t = (T) objMapping.mapping(rs, clazz).get(0) ;} catch (SQLException e) {e.printStackTrace();}finally {DBConn.closeConn(conn, ps, rs);}return t ;}/*** @author yxln* @function  分页查找数据* @param sql* @param pageNo* @param pageSize* @return* @date 2018年10月23日*/public List<T> queryListByPage_Oralce(String sql ,Map<String,Object> map) {// map、pageNo、pageSize 中任何一个为空,则不能完成分页查询,if(map == null || map.get("pageNo") == null || map.get("pageSize") == null) {System.out.println("map、pageNo、pageSize 中任何一个为空,则不能完成分页查询");return null;}conn = DBConn.getInstance().getConn() ;ResultSet rs = null ;List<T> list = null ;int pageNo = 1 ;int pageSize = 5 ;Type type = (ParameterizedType) this.getClass().getGenericSuperclass();if(type instanceof ParameterizedType) {this.clazz = (Class) ((ParameterizedType)type).getActualTypeArguments()[0];}else {System.out.println("【异常】没有给定泛型的类型");}if(map.get("pageNo") != null) {pageNo = Integer.parseInt(map.get("pageNo") + "") ;map.remove("pageNo") ;}if(map.get("pageSize") != null) {pageSize = Integer.parseInt(map.get("pageSize") + "") ;map.remove("pageSize") ;}sql = " select * from ( select all_data.*,rownum all_data_row  from ("+sql+") all_data where ROWNUM <= "+(pageNo * pageSize)+") where all_data_row > " +((pageNo - 1) * pageSize) ;try {ps = conn.prepareStatement(sql) ;if(map != null) {Set<String> keySet = map.keySet() ;}rs = ps.executeQuery() ;list = new ArrayList<T>() ;while(rs.next()) {list = objMapping.mapping(rs, this.clazz) ;}} catch (SQLException e) {e.printStackTrace();}finally {DBConn.closeConn(conn, ps, rs);}return list ;}/*** * @author yxln* @function 多条件、单次数据删除(注意此方法传进多个参数并不是用于批量删除,批量删除使用本类中的方法deleteBatches())* @param sql 删除的sql语句* @param args 参数,与sql语句中占位符对应*       例子1:deleteBatches("delete from employee where id = ? and name = ?",new String[] {"6","yxln4"}) *      例子1:deleteBatches("delete from employee where id = ? and name = ?","6","yxln4") * @return* @date 2018年10月30日*/public int delete(String sql , Object... args) {//获取数据库连接conn = DBConn.getInstance().getConn() ;int flag = 0 ;try {// 获取sql预处理对象ps = conn.prepareStatement(sql) ;// 判断是否有参数if(args != null && args.length > 0) {for(int i = 0 ; i < args.length ; i++) {// 将参数设置到对应的占位符ps.setObject(i + 1, args[i]);}}flag = ps.executeUpdate() ;} catch (SQLException e) {e.printStackTrace();}finally {DBConn.closeConn(conn, ps, rs);}return flag;}/*** * @author yxln* @function  批量删除 * @param sql 执行批量删除的sql* @param args 每一组参数(参数个数与占位符对应)*       例子1:deleteBatches("delete from employee where id = ? ",*                       new String[] {"4","6"}) *       例子2:deleteBatches("delete from employee where id = ? ","4","6") *      例子3:deleteBatches("delete from employee where id = ? and name = ?",*                      new String[] {"4","yxln3"},new String[] {"6","yxln4"}) *        例子4:deleteBatches("delete from employee where id = ? and name = ?",*                         new String[][] {new String[] {"23","yxln9"},new String[] {"24","yxln9"}}) * @date 2018年10月31日*/public void deleteBatches(String sql,Object[]... args) {conn = DBConn.getInstance().getConn() ;int[] flag = new int[] {};try {//不自动提交conn.setAutoCommit(false); ps = conn.prepareStatement(sql) ;// 判断是否有参数if(args != null && args.length > 0) {// 判断参数中的对象是否为数组if(args[0].getClass().isArray() && ((Object[])args[0]).length > 0) {Object[] obj = null ;for(int i = 0 ; i < args.length ; i++) {obj = (Object[]) args[i] ;for(int j = 0 ; j < obj.length ; j++) {ps.setObject(j + 1, obj[j]);}ps.addBatch();}flag = ps.executeBatch() ;conn.commit(); // 只想sql语句传入一个参数}else {for(int i = 0 ; i < args.length ; i++) {ps.setObject(1, args[i]);ps.addBatch();}flag = ps.executeBatch() ;conn.commit(); }}} catch (SQLException e) {// 捕获到执行过程的中的异常,回滚try {conn.rollback();} catch (SQLException e1) {e1.printStackTrace();}e.printStackTrace();}finally {try {conn.setAutoCommit(true);} catch (SQLException e) {e.printStackTrace();}finally {DBConn.closeConn(conn, ps, rs);}}}/*** @author yxln* @function 修改单条数据 * @param sql 执行修改的sql语句* @param paras 参数* @return* @date 2018年10月31日*/public int update(String sql,Object... paras) {conn = DBConn.getInstance().getConn() ;int flag = 0 ;try {ps = conn.prepareStatement(sql) ;if(paras != null && paras.length > 0) {for(int i = 0 ; i < paras.length ; i++) {ps.setObject(i +1, paras[i]);}}flag = ps.executeUpdate() ;} catch (SQLException e) {e.printStackTrace();}finally {DBConn.closeConn(conn, ps, rs);}return flag ;}
}

对JDBC进行简单的封装相关推荐

  1. Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发

    Spring JDBC     * Spring框架对JDBC的简单封装.提供了一个JDBCTemplate对象简化JDBC的开发     * 步骤:         1. 导入jar包        ...

  2. JDBC 的代码逻辑封装

    JDBC 的代码逻辑封装 目录 JDBC 的代码逻辑封装 1.前言 2.定义统一接口 3. 封装针对用户相关各种操作的类 4.针对于各种操作的封装 5.代码测试 5.1 查询操作 5.2 增加操作 5 ...

  3. sqlsugar 链接mysql_SqlSugar简单使用封装

    一.SqlSugar简单使用封装 1.  封装读取数据库的方法: public staticSqlSugarClient GetInstance() {//SqlSugarClient db = ne ...

  4. 二、SQL注入使用占位符解决、JDBC工具类、封装

    一.SQL注入使用占位符解决 //使用jdbc发送sql语句, 到数据库tb_user 查询是否有该用户名和密码的用户Connection conn = null;PreparedStatement ...

  5. jdbc中递归树封装查询数据

    jdbc中递归树封装查询 一.递归树封装多次查询 数据库驱动包.jar文件: ①数据库数据准备(使用IDEA(64位)软件和phpstudy软件,即小皮系统(64位)) ②实体:为了使用通用 Dao ...

  6. mysql jdbc关闭连接_【B站Java两分钟】JDBC数据库简单使用,封装连接,关闭

    使用DBUtil类,封装两个静态方法,一个得到连接方法,一个关闭连接方法,以MySQL为例: import java.sql.*; public class DBUtil { //创建连接 publi ...

  7. Java JDBC数据库简单使用,封装连接,关闭

    使用DBUtil类,封装两个静态方法,一个得到连接方法,一个关闭连接方法,以MySQL为例: import java.sql.*;public class DBUtil {//创建连接public s ...

  8. JDBC进行简单的增删改查

    一.准备工作(一):MySQL安装配置和基础学习 二.准备工作(二):下载数据库对应的jar包并导入 三.JDBC基本操作 (1)定义记录的类(可选) (2)连接的获取 (3)insert (4)up ...

  9. 通过JDBC进行简单的增删改查(以MySQL为例)

    目录 前言:什么是JDBC 一.准备工作(一):MySQL安装配置和基础学习 二.准备工作(二):下载数据库对应的jar包并导入 三.JDBC基本操作 (1)定义记录的类(可选) (2)连接的获取 ( ...

最新文章

  1. Android 微信支付详解与Demo
  2. 《SAP高级应用开发》---Idoc学习笔记
  3. 窗体之间传值的暴力方法
  4. 洛谷 P1414 又是毕业季II (多个数的最大公因数)
  5. oracle11g memory_target,Oracle11g启动报:ORA-00845: MEMORY_TARGET not supported on this system
  6. (转)2020年网络安全产业图谱
  7. Mac 基本教程和vim + Awesome Mac
  8. Unity使用HDR做天空盒
  9. Maven依赖冲突避坑指北
  10. Python3 L13
  11. html5 observer api,转: HTML5新特性之Mutation Observer
  12. halcon 20.11.02 深度学习语义分割例程报错
  13. 全国低碳日·绿色低碳出行比赛-步数打卡小程序
  14. CRC-CCITT16(0xFFFF、XModem、0x1D0F、Kermit)
  15. Sicily 1140. 国王的遗产
  16. VMware Tools (ubuntu系统)安装详细过程与使用
  17. 游戏党注意了,超80款Steam游戏可在优麒麟上畅玩
  18. 第1次作业:软件工程之计算机生涯序言
  19. 可能我也没有想到,我能把写文章这件事因为一个小小的念头而坚持下来!
  20. HTTP资料整理 -- 干货满满

热门文章

  1. php mkdir没有权限不能创建成功的问题
  2. Software--IoC 依赖倒置 控制反转
  3. 两个Listbox的关联(省名 和 该省城市的对应)
  4. N35-第十四周作业
  5. 蚂蚁金服 SOFAArk 0.6.0 新特性介绍 | 模块化开发容器...
  6. Dubbo即将毕业,晋升为Apache顶级项目?
  7. Safetype Config使用
  8. 升级的Electric Cloud平台增添了大型机和微服务功能
  9. Ehcache整合spring配置
  10. quot;数据结构翻转课堂quot;答疑实录——链表