DBHelper.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. package com.yihu.mysql.jdbc;
  2. import com.yihu.mysql.enums.DBType;
  3. import org.apache.commons.dbutils.QueryRunner;
  4. import org.apache.commons.dbutils.handlers.*;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.config.ConfigurableBeanFactory;
  7. import org.springframework.context.annotation.Scope;
  8. import org.springframework.stereotype.Service;
  9. import java.beans.BeanInfo;
  10. import java.beans.Introspector;
  11. import java.beans.PropertyDescriptor;
  12. import java.lang.reflect.Method;
  13. import java.sql.Connection;
  14. import java.sql.DriverManager;
  15. import java.sql.Statement;
  16. import java.text.SimpleDateFormat;
  17. import java.util.*;
  18. /**
  19. * JDBC数据库操作类
  20. * Created by hzp on 2015/11/26.
  21. */
  22. @Service
  23. @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  24. public class DBHelper {
  25. @Autowired
  26. ConnectionFactory factory;
  27. private String name = "";
  28. public DBType dbType = DBType.Mysql; //当前连接数据库类型
  29. /**
  30. * 获取当前连接
  31. */
  32. private Connection getConn() throws Exception {
  33. if (name.length() > 0) {
  34. return factory.getConnection(name);
  35. } else {
  36. return factory.getConnection();
  37. }
  38. }
  39. /**
  40. * 关闭连接
  41. */
  42. private void close(Connection conn) throws Exception{
  43. if(conn != null) {
  44. conn.close();
  45. }
  46. }
  47. /**
  48. * 抛出自定义异常
  49. * @param msg
  50. * @param e
  51. */
  52. private void rethrow(String msg, Exception e) throws Exception{
  53. throw new Exception(msg,e);
  54. }
  55. private String UNDERLINE = "_";
  56. /**
  57. * 驼峰表达式转下划线
  58. */
  59. private String camelToUnderline(String val){
  60. if (val == null || "".equals(val.trim())){
  61. return "";
  62. }
  63. int len=val.length();
  64. StringBuilder sb=new StringBuilder(len);
  65. for (int i = 0; i < len; i++) {
  66. char c=val.charAt(i);
  67. if (Character.isUpperCase(c)) {
  68. sb.append(UNDERLINE);
  69. sb.append(Character.toLowerCase(c));
  70. } else{
  71. sb.append(c);
  72. }
  73. }
  74. return sb.toString();
  75. }
  76. /**
  77. * Map数据转驼峰表达式
  78. * @param map
  79. * @return
  80. */
  81. private <T> T MaptoBean( Class<T> cls, Map<String, Object> map) throws Exception{
  82. Object obj = cls.newInstance();
  83. BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
  84. PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
  85. for (PropertyDescriptor property : propertyDescriptors) {
  86. Method setter = property.getWriteMethod();
  87. if (setter != null) {
  88. String name = property.getName();
  89. Object val = null;
  90. if(map.containsKey(name))
  91. {
  92. val = map.get(name);
  93. }
  94. else if(map.containsKey(name.toLowerCase()))
  95. {
  96. val = map.get(name.toLowerCase());
  97. }
  98. else if(map.containsKey(name.toUpperCase()))
  99. {
  100. val = map.get(name.toUpperCase());
  101. }
  102. else {
  103. //驼峰命名转下划线
  104. String newName = camelToUnderline(name).toLowerCase();
  105. if(map.containsKey(newName))
  106. {
  107. val = map.get(newName);
  108. }
  109. else if(map.containsKey(newName.toUpperCase()))
  110. {
  111. val = map.get(newName.toUpperCase());
  112. }
  113. }
  114. if(val != null) {
  115. String type = val.getClass().getName();
  116. if (type.indexOf("Date") > 0 || type.indexOf("Timestamp") > 0) //时间格式
  117. {
  118. SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  119. String re = formatter.format(val);
  120. val = re;
  121. }
  122. }
  123. else{
  124. val = "";
  125. }
  126. setter.invoke(obj, val);
  127. }
  128. }
  129. return (T)obj;
  130. }
  131. /*******************************************/
  132. /**
  133. * 初始化连接
  134. */
  135. public void connect() throws Exception
  136. {
  137. factory.getConnection();
  138. dbType = factory.getDbType();
  139. }
  140. /**
  141. * 自定义连接
  142. * uri包含用户名/密码
  143. */
  144. public void connect(String name,String uri) throws Exception
  145. {
  146. this.name = name;
  147. factory.getConnection(name, uri);
  148. dbType = factory.getDbType(uri);
  149. }
  150. /**
  151. * 自定义连接
  152. */
  153. public void connect(String name,String uri,String user,String password) throws Exception
  154. {
  155. this.name = name;
  156. factory.getConnection(name,uri, user, password);
  157. dbType = factory.getDbType(uri);
  158. }
  159. /****************************** 查询操作 *******************************************/
  160. /**
  161. * 查询第一个字段
  162. */
  163. public Object scalar(String sql) throws Exception
  164. {
  165. return scalar(sql,(Objects[])null);
  166. }
  167. /**
  168. * 查询第一行第一个字段(参数SQL防注入)
  169. */
  170. public Object scalar(String sql,Object... params) throws Exception
  171. {
  172. Connection conn = getConn();
  173. try{
  174. QueryRunner qr = new QueryRunner();
  175. return qr.query(conn, sql, new ScalarHandler(), params);
  176. }
  177. catch (Exception e)
  178. {
  179. this.rethrow("SQL:" + sql + ",Parameters:" + Arrays.deepToString(params), e);
  180. return null;
  181. }
  182. finally {
  183. this.close(conn);
  184. }
  185. }
  186. /******************** Map查询 *******************************/
  187. /**
  188. * 获取单条记录
  189. */
  190. public Map<String,Object> load(String sql) throws Exception {
  191. return load(sql,(Object[])null);
  192. }
  193. /**
  194. * 获取单条记录(参数SQL防注入)
  195. */
  196. public Map<String,Object> load(String sql, Object... params) throws Exception {
  197. Connection conn = getConn();
  198. try{
  199. QueryRunner qr = new QueryRunner();
  200. return qr.query(conn, sql, new MapHandler(), params);
  201. }
  202. catch (Exception e)
  203. {
  204. this.rethrow("SQL:" + sql + ",Parameters:" + Arrays.deepToString(params), e);
  205. return null;
  206. }
  207. finally {
  208. close(conn);
  209. }
  210. }
  211. /**
  212. * List<JSONObject>获取多条记录
  213. */
  214. public List<Map<String,Object>> query(String sql) throws Exception
  215. {
  216. return query(sql, (Object[])null);
  217. }
  218. /**
  219. * List<JSONObject>获取多条记录(参数SQL防注入)
  220. */
  221. public List<Map<String,Object>> query(String sql,Object... params) throws Exception
  222. {
  223. Connection conn = getConn();
  224. try{
  225. QueryRunner qr = new QueryRunner();
  226. return qr.query(conn, sql, new MapListHandler(), params);
  227. }
  228. catch (Exception e)
  229. {
  230. this.rethrow("SQL:" + sql + ",Parameters:" + Arrays.deepToString(params), e);
  231. return null;
  232. }
  233. finally {
  234. close(conn);
  235. }
  236. }
  237. /*************************** 实体查询(转驼峰) ********************************/
  238. /**
  239. * 获取单个实体
  240. */
  241. public <T> T load(Class<T> cls, String sql) throws Exception
  242. {
  243. return load(cls, sql, (Object[])null);
  244. }
  245. /**
  246. * 获取单个实体
  247. */
  248. public <T> T load(Class<T> cls, String sql, Object... params) throws Exception {
  249. Map<String,Object> map = this.load(sql, params);
  250. return this.MaptoBean(cls,map);
  251. }
  252. /**
  253. * 获取实体列表
  254. */
  255. public <T> List<T> query(Class<T> cls, String sql) throws Exception
  256. {
  257. return query(cls, sql, (Object[]) null);
  258. }
  259. /**
  260. * 获取实体列表
  261. */
  262. public <T> List<T> query(Class<T> cls, String sql, Object... params) throws Exception {
  263. List<Map<String,Object>> mapList = this.query(sql, params);
  264. List<T> list = new ArrayList<>();
  265. if(mapList!=null && mapList.size()>0)
  266. {
  267. for(Map<String,Object> map : mapList)
  268. {
  269. list.add(this.MaptoBean(cls,map));
  270. }
  271. }
  272. return list;
  273. }
  274. /******************************* 非查询操作 ***********************************/
  275. /**
  276. * 测试连接
  277. */
  278. public static boolean test(String uri) throws Exception{
  279. try {
  280. Properties info = new Properties();
  281. Connection conn = DriverManager.getDriver(uri).connect(uri,info);
  282. Boolean re = true;
  283. if (conn == null) {
  284. re = false;
  285. } else {
  286. if(conn.isClosed())
  287. {
  288. re = false;
  289. }
  290. conn.close();
  291. }
  292. return re;
  293. }
  294. catch (Exception ex)
  295. {
  296. return false;
  297. }
  298. }
  299. /**
  300. * 单条增删改操作
  301. * @param sql
  302. * @return
  303. */
  304. public boolean execute(String sql) throws Exception{
  305. return execute(sql,null);
  306. }
  307. /**
  308. * 单条增删改操作
  309. * @param sql
  310. * @return
  311. */
  312. public boolean execute(String sql,Object... params) throws Exception{
  313. Connection conn = getConn();
  314. try{
  315. QueryRunner qr = new QueryRunner();
  316. int re = qr.update(conn, sql,params);
  317. if(re>0)
  318. return true;
  319. else {
  320. this.rethrow("SQL:" + sql + ",Parameters:" + Arrays.deepToString(params), null);
  321. return false;
  322. }
  323. }
  324. catch (Exception e)
  325. {
  326. this.rethrow("SQL:" + sql + ",Parameters:" + Arrays.deepToString(params), e);
  327. return false;
  328. }
  329. finally {
  330. close(conn);
  331. }
  332. }
  333. /**
  334. * 批量操作(同一条SQL语句)
  335. * @return
  336. */
  337. public boolean executeBatch(String sql,Object[][] params) throws Exception
  338. {
  339. Connection conn = getConn();
  340. try{
  341. QueryRunner qr = new QueryRunner();
  342. conn.setAutoCommit(false);
  343. int re = qr.batch(conn, sql, params).length;
  344. conn.commit();
  345. if(re>0)
  346. return true;
  347. else {
  348. this.rethrow("SQL:" + sql + ",Parameters:" + Arrays.deepToString(params), null);
  349. return false;
  350. }
  351. }
  352. catch (Exception e)
  353. {
  354. if (conn != null) {
  355. conn.rollback();
  356. }
  357. this.rethrow("SQL:" + sql + ",Parameters:" + Arrays.deepToString(params), e);
  358. return false;
  359. }
  360. finally {
  361. close(conn);
  362. }
  363. }
  364. /**
  365. * 批量操作(最多1000条执行一次)
  366. * @param sqls
  367. * @return
  368. */
  369. public boolean executeBatch(String[] sqls) throws Exception
  370. {
  371. Connection conn = getConn();
  372. try{
  373. conn.setAutoCommit(false);
  374. Statement statemenet = conn.createStatement();
  375. final int batchSize = 1000;
  376. int count = 0;
  377. for (String sql : sqls) {
  378. statemenet.addBatch(sql);
  379. if(++count % batchSize == 0) {
  380. statemenet.executeBatch();
  381. }
  382. }
  383. statemenet.executeBatch();
  384. conn.commit();
  385. statemenet.close();
  386. return true;
  387. }
  388. catch (Exception e)
  389. {
  390. if (conn != null) {
  391. conn.rollback();
  392. }
  393. this.rethrow("SQL:" + Arrays.deepToString(sqls), e);
  394. return false;
  395. }
  396. finally {
  397. close(conn);
  398. }
  399. }
  400. }