这是DAO层,第一次尝试,如有bug希望能即使反馈,我们共同进步。具体的用法和实现原理我会在前面几篇博客中补充更新。配置文件及项目目录结构会在下一篇中贴出!

  1. package com.javasm.supermarket.dao;
  2. import java.util.List;
  3. import java.util.Map;
  4. public interface DAO {
  5. // 增加
  6. void addObject(Object o);
  7. // 删除
  8. // void deleteObject(Object o);
  9. // 修改
  10. void updateObject(Object o);
  11. /**
  12. * 查询,可实现多查询或单一查询
  13. * @param params
  14. * @param tableName
  15. * @return
  16. */
  17. List<?> queryObject();
  18. void deleteObject();
  19. }

DAOImpl层源码

  1. package com.javasm.supermarket.impl;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.lang.reflect.Field;
  5. import java.sql.Connection;
  6. import java.sql.PreparedStatement;
  7. import java.sql.ResultSet;
  8. import java.sql.ResultSetMetaData;
  9. import java.sql.SQLException;
  10. import java.sql.Timestamp;
  11. import java.text.ParseException;
  12. import java.text.SimpleDateFormat;
  13. import java.util.ArrayList;
  14. import java.util.Date;
  15. import java.util.HashMap;
  16. import java.util.List;
  17. import java.util.Map;
  18. import java.util.Properties;
  19. import com.javasm.supermarket.dao.DAO;
  20. import com.javasm.supermarket.db.DBConnection;
  21. public class DAOImpl implements DAO {
  22. private static Properties objectConfigPath = new Properties();
  23. private static Properties objectConfig = new Properties();
  24. private static String className;
  25. private static Class<?> objectClass;
  26. private static Field[] fields;
  27. private static String tableName;
  28. private static String queryBuilder;
  29. private static String deleteBuilder;
  30. /**
  31. *
  32. * 加载配置文件,从配置文件中获取bean和bean对应的表明
  33. *
  34. */
  35. static {
  36. try {
  37. DAOImpl.class.getClassLoader();
  38. InputStream objectConfigPathInputStream = ClassLoader
  39. .getSystemResourceAsStream("objectConfigPath.properties");
  40. objectConfigPath.load(objectConfigPathInputStream);
  41. InputStream objectConfigInputStream = ClassLoader
  42. .getSystemResourceAsStream(objectConfigPath
  43. .getProperty("objectConfigPath"));
  44. objectConfig.load(objectConfigInputStream);
  45. className = objectConfig.getProperty("className");
  46. tableName = objectConfig.getProperty("tableName");
  47. queryBuilder = objectConfig.getProperty("queryBuilder");
  48. deleteBuilder = objectConfig.getProperty("deleteBuilder");
  49. objectClass = Class.forName(className);
  50. fields = objectClass.getDeclaredFields();
  51. } catch (IOException | ClassNotFoundException e) {
  52. e.printStackTrace();
  53. System.err.println("配置文件加载失败!");
  54. }
  55. }
  56. /**
  57. * 插入数据
  58. */
  59. @Override
  60. public void addObject(Object object) {
  61. StringBuilder sql = new StringBuilder("INSERT " + tableName
  62. + " VALUES(");
  63. Connection connection = null;
  64. PreparedStatement preparedStatement = null;
  65. // 用于存放传入的对象的参数,默认将id值(主键)的key设为0,方便条件设置
  66. Map<Integer, Object> fieldsValues = new HashMap<Integer, Object>();
  67. try {
  68. for (int i = 0; i < fields.length; i++) {
  69. fields[i].setAccessible(true);
  70. fieldsValues.put(i, fields[i].get(object));
  71. sql.append("?");
  72. if (i < (fields.length - 1))
  73. sql.append(", ");
  74. }
  75. sql.append(")");
  76. connection = DBConnection.getConnection();
  77. preparedStatement = connection.prepareStatement(sql.toString());
  78. Class<?> fieldClass = null;
  79. for (int i = 1; i <= fieldsValues.size(); i++) {
  80. /**
  81. * 获取存入map中对象的参数的类类型,根据类类型选择preparedStatement的set方法
  82. */
  83. if (fieldsValues.get(i - 1) != null) {
  84. fieldClass = fieldsValues.get(i - 1).getClass();
  85. // 如果类类型为String.class,则执行setString
  86. if (fieldClass.equals(String.class)) {
  87. preparedStatement.setString(i,
  88. (String) fieldsValues.get(i - 1));
  89. }
  90. // 如果类类型为Float.class,则执行setString
  91. if (fieldClass.equals(Float.class)) {
  92. preparedStatement.setFloat(i,
  93. (Float) fieldsValues.get(i - 1));
  94. }
  95. // 如果类类型为Integer.class,则执行setString
  96. if (fieldClass.equals(Integer.class)) {
  97. preparedStatement.setInt(i,
  98. (Integer) fieldsValues.get(i - 1));
  99. }
  100. // 如果类类型为Timestamp.class,则执行setString
  101. if (fieldClass.equals(Timestamp.class)) {
  102. preparedStatement.setTimestamp(i, new Timestamp(
  103. ((Date) fieldsValues.get(i - 1)).getTime()));
  104. }
  105. } else {
  106. preparedStatement.setObject(i, null);
  107. }
  108. }
  109. // 执行sql语句,返回更新参数
  110. int columnsCount = preparedStatement.executeUpdate();
  111. System.out.println("有" + columnsCount + "条数据被更新!");
  112. } catch (SQLException e) {
  113. e.printStackTrace();
  114. } catch (SecurityException e) {
  115. e.printStackTrace();
  116. } catch (NumberFormatException e) {
  117. e.printStackTrace();
  118. } catch (IllegalArgumentException e) {
  119. e.printStackTrace();
  120. } catch (IllegalAccessException e) {
  121. e.printStackTrace();
  122. } finally {
  123. DBConnection.close(connection, preparedStatement, null);
  124. }
  125. }
  126. /**
  127. *
  128. * 删除数据,条件列表为空时删除所有数据
  129. */
  130. @Override
  131. public void deleteObject() {
  132. StringBuilder sql = new StringBuilder(
  133. "DELETE FROM order_info WHERE 1=1 ");
  134. List<Map<String, Object>> params = builder(deleteBuilder);
  135. Connection connection = null;
  136. PreparedStatement preparedStatement = null;
  137. try {
  138. connection = DBConnection.getConnection();
  139. if (params != null && params.size() > 0) {
  140. for (int i = 0; i < params.size(); i++) {
  141. Map<String, Object> map = params.get(i);
  142. sql.append(" AND " + map.get("name") + " "
  143. + map.get("rela") + " " + map.get("value") + " ");
  144. }
  145. }
  146. connection = DBConnection.getConnection();
  147. preparedStatement = connection.prepareStatement(sql.toString());
  148. preparedStatement.executeLargeUpdate();
  149. } catch (SQLException e) {
  150. e.printStackTrace();
  151. System.out.println("删除失败!");
  152. } catch (IllegalArgumentException e) {
  153. e.printStackTrace();
  154. } finally {
  155. DBConnection.close(connection, preparedStatement, null);
  156. }
  157. }
  158. /**
  159. *
  160. * 修改数据
  161. *
  162. */
  163. @Override
  164. public void updateObject(Object object) {
  165. StringBuilder sql = new StringBuilder("UPDATE " + tableName + " SET ");
  166. Connection connection = null;
  167. PreparedStatement preparedStatement = null;
  168. // 用于存放传入的对象的参数,默认将id值(主键)的key设为0,方便条件设置
  169. Map<Integer, Object> fieldsValues = new HashMap<Integer, Object>();
  170. try {
  171. for (int i = 0; i < fields.length; i++) {
  172. fields[i].setAccessible(true);
  173. if (i == 0) {
  174. fieldsValues.put(fields.length - 1, fields[i].get(object));
  175. continue;
  176. }
  177. sql.append(fields[i].getName());
  178. sql.append("=?");
  179. fieldsValues.put(i - 1, fields[i].get(object));
  180. if (i < (fields.length - 1))
  181. sql.append(", ");
  182. if (i == (fields.length - 1)) {
  183. sql.append(" WHERE ");
  184. sql.append(fields[0].getName());
  185. sql.append("=?");
  186. }
  187. }
  188. connection = DBConnection.getConnection();
  189. preparedStatement = connection.prepareStatement(sql.toString());
  190. Class<?> fieldClass = null;
  191. for (int i = 1; i <= fieldsValues.size(); i++) {
  192. /**
  193. * 获取存入map中对象的参数的类类型,根据类类型选择preparedStatement的set方法
  194. */
  195. fieldClass = fieldsValues.get(i - 1).getClass();
  196. // 如果类类型为String.class,则执行setString
  197. if (fieldClass.equals(String.class)) {
  198. preparedStatement.setString(i,
  199. (String) fieldsValues.get(i - 1));
  200. }
  201. // 如果类类型为Float.class,则执行setString
  202. if (fieldClass.equals(Float.class)) {
  203. preparedStatement.setFloat(i,
  204. (Float) fieldsValues.get(i - 1));
  205. }
  206. // 如果类类型为Integer.class,则执行setString
  207. if (fieldClass.equals(Integer.class)) {
  208. preparedStatement.setInt(i,
  209. (Integer) fieldsValues.get(i - 1));
  210. }
  211. // 如果类类型为Timestamp.class,则执行setString
  212. if (fieldClass.equals(Timestamp.class)) {
  213. preparedStatement.setTimestamp(i, new Timestamp(
  214. ((Date) fieldsValues.get(i - 1)).getTime()));
  215. }
  216. }
  217. // 执行sql语句,返回更新参数
  218. int columnsCount = preparedStatement.executeUpdate();
  219. System.out.println("有" + columnsCount + "条数据被更新!");
  220. } catch (SQLException e) {
  221. e.printStackTrace();
  222. } catch (SecurityException e) {
  223. e.printStackTrace();
  224. } catch (NumberFormatException e) {
  225. e.printStackTrace();
  226. } catch (IllegalArgumentException e) {
  227. e.printStackTrace();
  228. } catch (IllegalAccessException e) {
  229. e.printStackTrace();
  230. } finally {
  231. DBConnection.close(connection, preparedStatement, null);
  232. }
  233. }
  234. /**
  235. *
  236. * 数据查询,查询条件列表为空时查询所有数据
  237. *
  238. */
  239. @Override
  240. public List<?> queryObject() {
  241. List<Map<String, Object>> params = builder(queryBuilder);
  242. List<Object> objectList = new ArrayList<Object>();
  243. StringBuilder sql = new StringBuilder("SELECT * FROM " + tableName
  244. + " WHERE 1=1");
  245. Connection connection = null;
  246. PreparedStatement preparedStatement = null;
  247. ResultSet resultSet = null;
  248. try {
  249. connection = DBConnection.getConnection();
  250. if (params != null && params.size() > 0) {
  251. for (int i = 0; i < params.size(); i++) {
  252. Map<String, Object> map = params.get(i);
  253. sql.append(" AND " + map.get("name") + " "
  254. + map.get("rela") + " " + map.get("value") + " ");
  255. }
  256. }
  257. preparedStatement = connection.prepareStatement(sql.toString());
  258. resultSet = preparedStatement.executeQuery();
  259. ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
  260. // 获取数据列数
  261. int columnsCount = resultSetMetaData.getColumnCount();
  262. Field field = null;
  263. Object object = null;
  264. while (resultSet.next()) {
  265. /**
  266. * 获取实例化对象
  267. */
  268. object = objectClass.newInstance();
  269. String columnName = null;
  270. String columnTypeName = null;
  271. String columnValue = null;
  272. for (int i = 1; i <= columnsCount; i++) {
  273. columnName = resultSetMetaData.getColumnName(i);
  274. columnTypeName = resultSetMetaData.getColumnTypeName(i);
  275. columnValue = resultSet.getString(i);
  276. field = object.getClass().getDeclaredField(columnName);
  277. field.setAccessible(true);
  278. switch (columnTypeName) {
  279. case "INT":
  280. field.set(object, Integer.parseInt(columnValue));
  281. break;
  282. case "TINYINT":
  283. field.set(object, Integer.parseInt(columnValue));
  284. break;
  285. case "VARCHAR":
  286. field.set(object, columnValue);
  287. break;
  288. case "FLOAT":
  289. field.set(object, Float.parseFloat(columnValue));
  290. break;
  291. case "DATETIME":
  292. SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
  293. "yyyy-MM-dd HH:mm:ss");
  294. field.set(object, simpleDateFormat.parse(columnValue));
  295. break;
  296. }
  297. }
  298. objectList.add(object);
  299. }
  300. } catch (SQLException e) {
  301. e.printStackTrace();
  302. } catch (NoSuchFieldException e) {
  303. e.printStackTrace();
  304. } catch (SecurityException e) {
  305. e.printStackTrace();
  306. } catch (NumberFormatException e) {
  307. e.printStackTrace();
  308. } catch (IllegalArgumentException e) {
  309. e.printStackTrace();
  310. } catch (IllegalAccessException e) {
  311. e.printStackTrace();
  312. } catch (ParseException e) {
  313. e.printStackTrace();
  314. } catch (InstantiationException e) {
  315. e.printStackTrace();
  316. } finally {
  317. DBConnection.close(connection, preparedStatement, resultSet);
  318. }
  319. return objectList;
  320. }
  321. /**
  322. * 从配置文件中提取删除或查询条件,如果传入的builder为null,则返回空列表
  323. *
  324. * @param builder
  325. * @return
  326. */
  327. private List<Map<String, Object>> builder(String builder) {
  328. List<Map<String, Object>> paramList = new ArrayList<Map<String, Object>>();
  329. if (builder.equals("null")) {
  330. paramList = null;
  331. } else {
  332. Map<String, Object> param = null;
  333. String[] values = null;
  334. System.out.println(builder.contains(";"));
  335. if (builder.contains(";")) {
  336. String[] mapValue = builder.split(";");
  337. for (String string : mapValue) {
  338. values = string.split(",");
  339. param = new HashMap<String, Object>();
  340. param.put("name", values[0]);
  341. param.put("rela", values[1]);
  342. param.put("value", values[2]);
  343. paramList.add(param);
  344. }
  345. } else {
  346. values = builder.split(",");
  347. param = new HashMap<String, Object>();
  348. param.put("name", values[0]);
  349. param.put("rela", values[1]);
  350. param.put("value", values[2]);
  351. paramList.add(param);
  352. }
  353. }
  354. return paramList;
  355. }
  356. }

反射实现数据库增删改查DAO及DAOImpl源代码(一)的更多相关文章

  1. 反射实现数据库增删改查DAO及DAOImpl源代码(二)

    配置文件源码 配置文件主要用于配置数据库对象(javaBean),配置表名,配置查询条件,配置删除条件 文件名称:objectConfigPath.properties 这个配置文件里面配置的是另外一 ...

  2. Java连接MySQL数据库增删改查通用方法

    版权声明:本文为博主原创文章,未经博主允许不得转载. Java连接MySQL数据库增删改查通用方法 运行环境:eclipse+MySQL 以前我们Java连接MySQL数据库都是一个数据库写一个类,类 ...

  3. mybatis--实现数据库增删改查

    首先,创建一个数据库my,并在数据库中插入一张表user,然后在user表中插入一行数据,代码如下: create database my; use my; create table user( id ...

  4. Yii2.0高级框架数据库增删改查的一些操作(转)

    yii2.0框架是PHP开发的一个比较高效率的框架,集合了作者的大量心血,下面通过用户为例给大家详解yii2.0高级框架数据库增删改查的一些操作 --------------------------- ...

  5. 2. MongoDB基本操作 —— 用Mongo.exe操作数据库增删改查

    一.开篇 传统的关系数据库一般由数据库(database).表(table).记录(record)三个层次概念组成,MongoDB是由数据库(database).集合(collection).文档对象 ...

  6. go——beego的数据库增删改查

    一直都不理解使用go语言的时候,为什么还要自己去装beego,以为使用go便可以解决所有的问题,结果在朋友的点拨下,才意识到: go与beego的关系就好比是nodejs与thinkjs的关系,因此也 ...

  7. (转)SQLite数据库增删改查操作

    原文:http://www.cnblogs.com/linjiqin/archive/2011/05/26/2059182.html SQLite数据库增删改查操作 一.使用嵌入式关系型SQLite数 ...

  8. Yii2.0高级框架数据库增删改查的一些操作

    yii2.0框架是PHP开发的一个比较高效率的框架,集合了作者的大量心血,下面通过用户为例给大家详解yii2.0高级框架数据库增删改查的一些操作 --------------------------- ...

  9. WindowsPhone8 数据库增删改查

    今天第一次在博客园发表文章,如果有的地方写的不对,还请大家指出! 1.这就是一个简单wp8数据库增删改查 1.创建数据表Person [Table] public class Person : INo ...

随机推荐

  1. 手把手编写PHP框架 深入了解MVC运行流程

    1 什么是MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...

  2. Unity3D之Mesh(六)绘制扇形、扇面、环形

    前言: 绘制了圆,就想到绘制与之相关的几何图形,以便更灵活的掌握Mesh动态创建模型的机制与方法. 一.分析: 首先,结合绘制圆的过程绘制环形: 圆形是由segments个等腰三角形组成的(上一篇中, ...

  3. Hibernate映射--基本类映射和对象关系映射(转)

    原文地址:http://blog.csdn.net/lovesummerforever/article/details/20901011   尊重原创,请访问原网址 回想一些我们在没有学习ssh的时候 ...

  4. C#子线程执行完后通知主线程

    其实这个比较简单,子线程怎么通知主线程,就是让子线程做完了自己的事儿就去干主线程的转回去干主线程的事儿. 那么怎么让子线程去做主线程的事儿呢,我们只需要把主线程的方法传递给子线程就行了,那么传递方法就 ...

  5. 文件操作类(QFileDialog、QFileInfo、QDir、QDirIterator、QFile)

    一.QFileDialog 用于弹出打开或保存对话框,然后返回选择的文件或文件夹 1.可以筛选所需要的文件类型 2.可以设置是否多选 3.可以设置保存还是打开 二.QFileInfo 保存了文件相关信 ...

  6. ACM学习历程—BNUOJ3685 Building for UN(构造)

    The United Nations has decided to build a new headquarters in Saint Petersburg, Russia. It will have ...

  7. HEOI2017题解

    Day 1 : T1 : 期末考试 很水的一道题,但是自己搞了大半天过不了大样例. 最后还A了... 主要思想就是枚举最后一个完成的任务的时间 然后对两部分的代价分类讨论统计一下. (考试代码,略丑) ...

  8. 【C/C++】scanf,printf 函数

    摘自http://www.cplusplus.com 1. scanf 函数 int scanf ( const char * format, ... ); Parameters format C s ...

  9. 虚拟机centos系统,停机装第二块网卡,需要更改的配置

    虚拟机centos系统,停机装第二块网卡,需要更改的配置. 问题描述: 虚拟机centos系统,停机装第二块网卡,发现  /etc/sysconfig/network-scripts/ifcfg-et ...

  10. BZOJ3064:CPU监控

    浅谈区间最值操作和历史最值问题:https://www.cnblogs.com/AKMer/p/10225100.html 题目传送门:https://lydsy.com/JudgeOnline/pr ...