可重用性较强的JDBC封装

以下为代码,注释中写了主要思想

主类

com.util.JDBCUtil.java

  1. package com.util;
  2.  
  3. import java.lang.reflect.Field;
  4. import java.sql.Connection;
  5. import java.sql.DriverManager;
  6. import java.sql.PreparedStatement;
  7. import java.sql.ResultSet;
  8. import java.sql.SQLException;
  9. import java.util.ArrayList;
  10. import java.util.Arrays;
  11. import java.util.List;
  12.  
  13. public class JDBCUtil {
  14. private final static String driver="com.mysql.jdbc.Driver";
  15. private final static String url="jdbc:mysql://192.168.137.11:3306/db_test?useUnicode=true&characterEncoding=utf8";
  16. private final static String user="root";
  17. private final static String password="123456";
  18. //获取JDBC连接
  19. public static Connection getConnection(){
  20. Connection conn=null;
  21. try {
  22. Class.forName(driver);
  23. conn=DriverManager.getConnection(url,user,password);
  24.  
  25. } catch (ClassNotFoundException e) {
  26. // TODO 自动生成的 catch 块
  27. e.printStackTrace();
  28. } catch (SQLException e) {
  29. // TODO 自动生成的 catch 块
  30. e.printStackTrace();
  31. }
  32. return conn;
  33. }
  34. //关闭连接
  35. public static void close(Connection conn,PreparedStatement pstmt,ResultSet rs){
  36. if(rs!=null){
  37. try {
  38. rs.close();
  39. } catch (SQLException e) {
  40. // TODO 自动生成的 catch 块
  41. e.printStackTrace();
  42. }
  43. }
  44. if(pstmt!=null){
  45. try {
  46. pstmt.close();
  47. } catch (SQLException e) {
  48. // TODO 自动生成的 catch 块
  49. e.printStackTrace();
  50. }
  51. }
  52. if(conn!=null){
  53. try {
  54. conn.close();
  55. } catch (SQLException e) {
  56. // TODO 自动生成的 catch 块
  57. e.printStackTrace();
  58. }
  59. }
  60. }
  61. //增、删、改
  62. /*
  63. * sql语句参数部分应改为?替代,代码中使用PreparedStatement类来注入参数,防止sql注入
  64. * 因不确定sql语句参数个数,类型,所以使用动态参数Object... objects
  65. * 将objects使用PreparedStatement中setObject方法注入
  66. * 调用时可以这样调用
  67. * update("insert into user values(?,?)","ads","asdsa");
  68. * 这样封装使得此方法可重用性强
  69. */
  70. public static int update(String sql,Object... objects ){
  71. Connection conn=getConnection();
  72. PreparedStatement pstmt=null;
  73. int result =0;
  74.  
  75. try {
  76. pstmt=conn.prepareStatement(sql);
  77. if(objects!=null){
  78. for(int i=0;i<objects.length;i++){
  79. pstmt.setObject(i+1, objects[i]);
  80. }
  81. }
  82. result=pstmt.executeUpdate();
  83. } catch (SQLException e) {
  84. // TODO 自动生成的 catch 块
  85. e.printStackTrace();
  86. }finally {
  87. close(conn, pstmt, null);
  88. }
  89.  
  90. return result;
  91. }
  92.  
  93. //添加对象
  94. /*
  95. * 不确定未来编程时向数据库中添加对象是什么,固使用泛型T
  96. * 可以使用自定义注解的方式实现javabean与相应数据表的映射
  97. * 此方法封装时代码晦涩难懂,使用时不用自己去写sql语句较为方便且复用性强
  98. * 类似于hibernate
  99. */
  100. public static <T> int insert(T t){
  101. //列名数组,即javabean的属性,用于拼接sql语句
  102. List<String> columns=new ArrayList<>();
  103. //用于拼接sql语句,存放‘?’,若javabean有4个属性,则此数组为[?,?,?,?]
  104. List<String> values=new ArrayList<>();
  105. //存放javabean各个属性的值,最后使用PreparedStatement注入
  106. List<Object> params=new ArrayList<>();
  107.  
  108. Class clz=t.getClass();
  109. //TableUtil自定义注解,用于javabean与表名的映射
  110. TableUtil ann=(TableUtil)clz.getAnnotation(TableUtil.class);
  111. //获取该javabean的属性
  112. Field[] fields=clz.getDeclaredFields();
  113. //for循环对columns values数组赋值
  114. /*
  115. * ColumnUtil自定义注解,用于javabean属性与表的列名映射
  116. * IDUtil自定义注解,用于表的自增长主键与相应javabean属性映射
  117. */
  118. for (Field field : fields) {
  119. //若数据表中设置了自增长主键,使用insert语句时须跳过相应的主属性,所以应执行此if语句判断
  120. if(!field.isAnnotationPresent(IDUtil.class)){
  121. //判断是使用ColumnUtil将此属性映射
  122. if(field.isAnnotationPresent(ColumnUtil.class)){
  123. //获取列名
  124. ColumnUtil column= field.getAnnotation(ColumnUtil.class);
  125. //columns数组添加相应列名
  126. columns.add(column.value());
  127. //获取一列,便向values数组中添加一个‘?’,即有多少列就有多少个‘?’
  128. values.add("?");
  129. //一般javabean属性为private,使用此方法可访问private属性
  130. field.setAccessible(true);
  131. try {
  132. //列相应的值,存放入params数组
  133. params.add(field.get(t));
  134. } catch (IllegalArgumentException | IllegalAccessException e) {
  135. // TODO Auto-generated catch block
  136. e.printStackTrace();
  137. }
  138. }
  139. }
  140. }
  141. /*
  142. * 拼接sql语句
  143. * ann.value()即注解的表名
  144. * list数组转化为String,结果为[...],为拼接sql语句需将"[]"变"()"
  145. */
  146. String sql="insert into "+ann.value()+Arrays.toString(columns.toArray()).replaceAll("\\[", "(").replaceAll("\\]", ")")+" values"+Arrays.toString(values.toArray()).replaceAll("\\[", "(").replaceAll("\\]", ")");
  147. //System.out.println(Arrays.toString(params.toArray()) );
  148. //System.out.println(sql);
  149.  
  150. //以下为执行sql语句过程
  151. //思想同上面的update方法
  152. Connection connection=getConnection();
  153. PreparedStatement preparedStatement=null;
  154. int result=0;
  155. try {
  156. preparedStatement=connection.prepareStatement(sql);
  157. for (int i=0;i<params.size();i++) {
  158. preparedStatement.setObject(i+1,params.get(i));
  159. }
  160. result=preparedStatement.executeUpdate();
  161.  
  162. } catch (SQLException e) {
  163. // TODO 自动生成的 catch 块
  164. e.printStackTrace();
  165. }finally {
  166. close(connection, preparedStatement, null);
  167. }
  168.  
  169. return result;
  170.  
  171. }
  172.  
  173. //查询,获取对象列表
  174. /*
  175. * 此方法调用时,使用匿名内部类,程序员可以自己写ResultSet结果集,具有好的复用性
  176. * sql语句中参数部分使用?替代,并使用动态参数,思想同上
  177. */
  178. public static <T> List<T> executeQuery(String sql,RowMap<T> rowMap,Object...objects ){
  179. List<T> list=new ArrayList<>();
  180. Connection connection=getConnection();
  181. PreparedStatement preparedStatement=null;
  182. ResultSet rSet=null;
  183. try {
  184. preparedStatement=connection.prepareStatement(sql);
  185. if(objects!=null) {
  186. for (int i=0;i<objects.length;i++) {
  187. preparedStatement.setObject(i+1, objects[i]);
  188.  
  189. }
  190. }
  191. rSet=preparedStatement.executeQuery();
  192. while (rSet.next()) {
  193. T t=rowMap.rowMapping(rSet);
  194. list.add(t);
  195. }
  196. } catch (SQLException e) {
  197. // TODO 自动生成的 catch 块
  198. e.printStackTrace();
  199. }finally {
  200. close(connection, preparedStatement, rSet);
  201. }
  202.  
  203. return list;
  204. }
  205.  
  206. }

以下为相关工具类

com.util.ColumnUtil.java

  1. package com.util;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. @Target(ElementType.FIELD)
  7. @Retention(RetentionPolicy.RUNTIME)
  8. public @interface ColumnUtil {
  9. //相应列名
  10. String value();
  11. }

com.util.IDUtil.java

  1. package com.util;
  2.  
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7.  
  8. @Target(ElementType.FIELD)
  9. @Retention(RetentionPolicy.RUNTIME)
  10. //自增主键注解
  11. public @interface IDUtil {
  12.  
  13. }

com.util.TableUtil.java

  1. package com.util;
  2.  
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7.  
  8. @Target(ElementType.TYPE)
  9. @Retention(RetentionPolicy.RUNTIME)
  10. public @interface TableUtil {
  11. //映射相应表名
  12. String value();
  13. }

com.util.RowMap.java

  1. package com.util;
  2.  
  3. import java.sql.ResultSet;
  4.  
  5. public interface RowMap<T> {
  6. //自定义result结果集
  7. //使用了匿名内部类的思想
  8. public T rowMapping(ResultSet rs);
  9. }

以下为测试类:

com.model.User.java

  1. package com.model;
  2.  
  3. import com.util.ColumnUtil;
  4. import com.util.TableUtil;
  5.  
  6. @TableUtil("t_user")
  7. //此javabean映射表名为"t_user"
  8. public class User {
  9. @ColumnUtil("c_username")
  10. //属性username对应表中的c_username列
  11. private String username;
  12. //属性password对应表中的c_password列
  13. @ColumnUtil("c_password")
  14. private String password;
  15. public String getUsername() {
  16. return username;
  17. }
  18. public String getPassword() {
  19. return password;
  20. }
  21. public void setUsername(String username) {
  22. this.username = username;
  23. }
  24. public void setPassword(String password) {
  25. this.password = password;
  26. }
  27.  
  28. }

tests.JDBCUtilTest.java

  1. package tests;
  2.  
  3. import java.sql.ResultSet;
  4. import java.sql.SQLException;
  5. import java.util.List;
  6. import java.util.UUID;
  7.  
  8. import com.model.User;
  9. import com.util.JDBCUtil;
  10. import com.util.RowMap;
  11.  
  12. public class JDBCUtilTest {
  13.  
  14. public static void main(String[] args) {
  15. User newUser=new User();
  16. newUser.setUsername(UUID.randomUUID().toString());
  17. newUser.setPassword("asd");
  18. JDBCUtil.insert(newUser);
  19. List<User> users=JDBCUtil.executeQuery("select * from t_user where c_username!=?",new RowMap<User>() {
  20. @Override
  21. //匿名内部类 定义resultset结果集
  22. public User rowMapping(ResultSet rs) {
  23. User user=new User();
  24. try {
  25. user.setUsername(rs.getString("c_username"));
  26. user.setPassword(rs.getString("c_password"));
  27. } catch (SQLException e) {
  28. e.printStackTrace();
  29. }
  30. return user;
  31. }
  32. }, "JDBCUtil");//查找用户名不为JDBCUtil的用户
  33. for (User user : users) {
  34. System.out.println(user.getUsername()+"&&"+user.getPassword());
  35. }
  36.  
  37. }
  38.  
  39. }

测试结果:

相应数据库:

优化JDBC封装的更多相关文章

  1. 优化JDBC开发

    一.元数据 元数据:数据库.表.列的定义信息 1.DataBaseMetaData对象 getURL():返回一个String类对象,代表数据库的URL. getUserName():返回连接当前数据 ...

  2. 优化JDBC编程-多提提意见

    优化JDBC编程这是我根据MS SQL SERVER 2000 JDBC DRIVER HELP,并参考其它资料整理而成.ms的这个帮助文件实在有失大家风范,示例代码很.....有兴趣者可以去下载ht ...

  3. jdbc封装代码

    jdbc封装代码 package jdbcUtil; import java.sql.Connection; import java.sql.DriverManager; import java.sq ...

  4. JDBC封装的工具类

    1. JDBC封装的工具类 public class JDBCUtil { private static Properties p = new Properties(); private static ...

  5. Spring+SpringMVC+MyBatis+easyUI整合优化篇(九)数据层优化-jdbc连接池简述、druid简介

    日常啰嗦 终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和da ...

  6. 数据层优化-jdbc连接池简述、druid简介

    终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和dao层的优化 ...

  7. IOS实现自动循环滚动广告--ScrollView的优化和封装

    一.问题分析 在许多App中,我们都会见到循环滚动的视图,比如广告,其实想实现这个功能并不难,用ScrollView就可以轻松完成,但是在制作的过程中还存在几个小问题,如果能够正确的处理好这些小问题, ...

  8. 高性能jdbc封装工具 Apache Commons DbUtils 1.6(转载)

    转载自原文地址:http://gao-xianglong.iteye.com/blog/2166444 前言 关于Apache的DbUtils中间件或许了解的人并不多,大部分开发人员在生成环境中更多的 ...

  9. Mysql,JDBC封装

    1.完成对数据库的表的增删改的操作 2.查询返回单条记录 3.查询返回多行记录 4.可以使用反射机制来封装,查询单条记录 5.反射机制,查询多条记录 package myjdbc; import ja ...

随机推荐

  1. spark[源码]-sparkContext概述

    SparkContext概述 sparkContext是所有的spark应用程序的发动机引擎,就是说你想要运行spark程序就必须创建一个,不然就没的玩了.sparkContext负责初始化很多东西, ...

  2. spring + groovy 转

    http://www.ibm.com/developerworks/cn/java/j-groovierspring2.html http://blog.csdn.net/qq362228416/ar ...

  3. 不允许有匹配 "[xX][mM][lL]" 的处理指令目标

    八月 , :: 上午 org.apache.tomcat.util.digester.SetPropertiesRule begin 警告: [SetPropertiesRule]{Server/Se ...

  4. Python --之练习题

    一,两个小组对战,对战规则如下:team1 = ['a','b','c']team2 = ['x','y','z'] #a 不和x对战,b 不和y,z 对战# for i in team1: #法一# ...

  5. Linux中LVM2原理

    一.LVM原理 [MD]:Multi Device 多设备 Mdadm是一个用户空间工具,是RAID的管理工具,与真正的RAID工作没有太大关系.真正的RAID集成在linux内核中 [DM]Devi ...

  6. 【c++ primer, 5e】函数指针

    简单的示例: #include <iostream> using namespace std; int sum(int x, int y) { return x + y; } int ma ...

  7. DDR4中的so-dimm 和component

    so-dimm :Small Outline Dual In-line Memory Module (小型双列直插式内存模块) component:直接焊接的ddr4芯片

  8. Hive查询Join

    Select a.val,b.val From a [Left|Right|Full Outer] Join b On (a.key==b.key); 现有两张表:sales 列出了人名及其所购商品的 ...

  9. ContOs 将SpringBoot的jar制作成系统服务

    将jar包上传到  你想要的目录下 如 /java/service/demo.jar 进入 /etc/systemd/system 目录下 新建  demo.service 内容如下 -------- ...

  10. 【TensorFlow/简单网络】MNIST数据集-softmax、全连接神经网络,卷积神经网络模型

    初学tensorflow,参考了以下几篇博客: soft模型 tensorflow构建全连接神经网络 tensorflow构建卷积神经网络 tensorflow构建卷积神经网络 tensorflow构 ...