Java进阶(二十五)Java连接mysql数据库(底层实现)

前言

很长时间没有系统的使用java做项目了。现在需要使用java完成一个实验,其中涉及到java连接数据库。让自己来写,记忆中已无从搜索。特将之前使用的方法做一简单的总结。也能够在底层理解一下连接数据库的具体步骤。

实现

首先需要导入相关的jar包,我使用的为:mysql-connector-java-5.1.7-bin.jar。

下面来看一下我所使用的数据库连接方法类:

MysqlUtil.java

  1. package cn.edu.ujn.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.ResultSetMetaData;
  9. import java.sql.SQLException;
  10. import java.util.ArrayList;
  11. import java.util.HashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14.  
  15. import cn.edu.ujn.base.Const;
  16. import cn.edu.ujn.dao.UserDao;
  17. import cn.edu.ujn.model.User;
  18.  
  19. public class MysqlUtil {
  20. // 定义数据库的用户名
  21. private final static String USERNAME = Const.USERNAME;
  22. // 定义数据库的密码
  23. private final static String PASSWORD = Const.PASSWORD;
  24. // 定义数据库的驱动信息
  25. private final String DRIVER = Const.DRIVER;
  26. // 定义访问数据库的地址
  27. private final static String URL = Const.URL;
  28. // 定义数据库的链接
  29. private static Connection connection;
  30. // 定义sql语句的执行对象
  31. private static PreparedStatement pstmt;// 只有在获得了Statement之后才可执行SQL语句
  32. // 定义查询返回的结果集合
  33. private static ResultSet resultset;
  34.  
  35. public MysqlUtil() {
  36.  
  37. try {
  38. Class.forName(DRIVER);// 显式地加载 JDBC 驱动程序
  39. System.out.println("注册驱动成功!");
  40. } catch (Exception e) {
  41. System.out.println("注册驱动失败!");
  42. }
  43. }
  44.  
  45. /**
  46. * 定义获得数据库的链接,试图建立到给定数据库 URL 的连接
  47. *
  48. * @return connection
  49. */
  50. public static Connection GetConnection() {
  51.  
  52. try {
  53. connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
  54. System.out.println("数据库连接成功!");
  55. } catch (Exception e) {
  56. System.out.println("数据库连接失败!");
  57. }
  58. return connection;
  59. }
  60.  
  61. /**
  62. * 完成对数据库表的增加、删除、更新操作
  63. *
  64. * @param sql
  65. * @param params
  66. * @return flag
  67. * @throws SQLException
  68. */
  69. public static boolean updateByPreparedStatement(String sql, List<Object> params)// 第二个参数为传输的占位符
  70. throws SQLException {
  71.  
  72. //加载数据库驱动
  73. new MysqlUtil();
  74. //连接数据库
  75. MysqlUtil.GetConnection();
  76. boolean flag = false;
  77.  
  78. // 表示当用户执行添加、删除、修改时所影响数据库的行数
  79. int result = -1;
  80. try {
  81. pstmt = connection.prepareStatement(sql);
  82. } catch (Exception e) {
  83. System.out.println("Error in updateByPreparedStatement!");
  84. }
  85.  
  86. // 表示占位符的第一个位置
  87. int index = 1;
  88.  
  89. // 判断所填充的占位符是否有值;判断集合的标准方式
  90. if (params != null && !params.isEmpty()) {
  91. for (int i = 0; i < params.size(); i++) {
  92. // System.out.println(i+" "+params.get(i));
  93. // 使用给定对象设置指定参数的值。第二个参数必须是Object类型
  94. pstmt.setObject(index++, params.get(i));
  95. }
  96. }
  97. result = pstmt.executeUpdate();// 用于执行DML语句-返回一个整数,代表被SQL语句影响的记录条数
  98. flag = result > 0 ? true : false;
  99. System.out.println("执行SQL语句影响的记录条数为:" + result);
  100. //关闭数据库
  101. MysqlUtil.releaseConn();
  102. return flag;
  103. }
  104. /**
  105. * 查询返回单条记录
  106. *
  107. * @param sql
  108. * @param params
  109. * @return map
  110. * @throws SQLException
  111. */
  112. public static Map<String, Object> findSimpleResult(String sql, List<Object> params)
  113. throws SQLException {
  114.  
  115. //加载数据库驱动
  116. new MysqlUtil();
  117. //连接数据库
  118. MysqlUtil.GetConnection();
  119. // 菱形语法在Java7及以后可用
  120. Map<String, Object> map = new HashMap<String, Object>();
  121.  
  122. // 表示占位符的第一个位置
  123. int index = 1;
  124.  
  125. // 此句很重要,需要进行预编译
  126. pstmt = connection.prepareStatement(sql);
  127.  
  128. // 判断所填充的占位符是否有值;判断集合的标准方式
  129. if (params != null && !params.isEmpty()) {
  130. for (int i = 0; i < params.size(); i++) {
  131.  
  132. // 第一个是指你SQL语句中的第几个参数,第二个是要设置的值
  133. pstmt.setObject(index++, params.get(i));
  134. }
  135. }
  136.  
  137. // 返回查询结果
  138. resultset = pstmt.executeQuery();
  139.  
  140. // 获取此 ResultSet 对象的列的编号、类型和属性。
  141. java.sql.ResultSetMetaData metdata = resultset.getMetaData();
  142.  
  143. // 获取列数
  144. int col_lenth = metdata.getColumnCount();
  145. boolean flag = resultset.next();
  146. if (!flag) {
  147. System.out.println("Found nothing!");
  148. }
  149. while (resultset.next()) {
  150. for (int i = 0; i < col_lenth; i++) {
  151.  
  152. // 获取指定列的名称
  153. String cols_name = metdata.getColumnName(i + 1);
  154.  
  155. // 通过列名获得指定列的属性值
  156. Object cols_value = resultset.getObject(cols_name);
  157. if (cols_value == null) {
  158.  
  159. // 由此可见,数据表中字段值不能为空
  160. cols_value = "";
  161. }
  162.  
  163. // 将指定的值与此映射中的指定键关联(可选操作)。
  164. map.put(cols_name, cols_value);
  165. }
  166. }
  167. //关闭数据库
  168. MysqlUtil.releaseConn();
  169. return map;
  170. }
  171.  
  172. /**
  173. * 通过反射机制访问数据库,查询前几页的内容
  174. *
  175. * @param sql
  176. * @param params
  177. * @param cls
  178. * @return
  179. * @throws Exception
  180. */
  181. public static <T> List<T> queryEvamall(String sql, List<Object> params,
  182. Class<T> cls) throws Exception {
  183.  
  184. //加载数据库驱动
  185. new MysqlUtil();
  186. //连接数据库
  187. MysqlUtil.GetConnection();
  188. // 构造一个初始容量为 10 的空列表。
  189. List<T> list = new ArrayList<T>();
  190.  
  191. // 表示占位符的第一个位置
  192. int index = 1;
  193.  
  194. pstmt = connection.prepareStatement(sql);
  195.  
  196. // 判断所填充的占位符是否有值;判断集合的标准方式
  197. if (params != null && !params.isEmpty()) {
  198. for (int i = 0; i < params.size(); i++) {
  199.  
  200. // 使用给定对象设置指定参数的值。第二个参数必须是Object类型
  201. pstmt.setObject(index++, params.get(i));
  202.  
  203. }
  204. }
  205.  
  206. // 返回查询结果
  207. resultset = pstmt.executeQuery();
  208.  
  209. // 获取列的相关信息
  210. java.sql.ResultSetMetaData metdata = resultset.getMetaData();
  211.  
  212. // 获取列数
  213. int col_lenth = metdata.getColumnCount();
  214. while (resultset.next()) {
  215.  
  216. // 通过反射机制创建一个实例
  217. T resultObject = cls.newInstance();
  218. for (int i = 0; i < col_lenth; i++) {
  219. String cols_name = metdata.getColumnName(i + 1);
  220. Object cols_value = resultset.getObject(cols_name);
  221. if (cols_value == null) {
  222. cols_value = "";
  223. }
  224.  
  225. // 通过列名获得反射
  226. Field field = cls.getDeclaredField(cols_name);
  227.  
  228. // 打开javabean的私有访问权限
  229. field.setAccessible(true);
  230. field.set(resultObject, cols_value);
  231. }
  232. list.add(resultObject);
  233. }
  234. //关闭数据库
  235. MysqlUtil.releaseConn();
  236. return list;
  237. }
  238. /**
  239. * 查询返回多条查询记录
  240. *
  241. * @param sql
  242. * @param params
  243. * @return
  244. * @throws SQLException
  245. */
  246. public static List<Map<String, Object>> findMoreResult(String sql,
  247. List<Object> params) throws SQLException {
  248. //加载数据库驱动
  249. new MysqlUtil();
  250. //连接数据库
  251. MysqlUtil.GetConnection();
  252. System.out.println("JJ");
  253. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  254. // 表示占位符的第一个位置
  255. int index = 1;
  256. pstmt = connection.prepareStatement(sql);
  257. // 判断所填充的占位符是否有值;判断集合的标准方式
  258. if (params != null && !params.isEmpty()) {
  259. for (int i = 0; i < params.size(); i++) {
  260. pstmt.setObject(index++, params.get(i));// 使用给定对象设置指定参数的值。第二个参数必须是
  261. // Object类型
  262. }
  263. }
  264. try {
  265. resultset = pstmt.executeQuery();// 返回查询结果
  266. } catch (Exception e) {
  267. System.out.println("Error1!");// 调试用
  268. }
  269. ResultSetMetaData metdata = resultset.getMetaData();// 获取列的相关信息
  270. int col_lenth = metdata.getColumnCount();// 获取列数
  271. System.out.println("数据表列数为:" + col_lenth);// 调试用
  272. while (resultset.next()) {
  273. Map<String, Object> map = new HashMap<String, Object>();
  274. for (int i = 0; i < col_lenth; i++) {
  275. String cols_name = metdata.getColumnName(i + 1);// 获取列的名称,列从1开始
  276. Object cols_value = resultset.getObject(cols_name);
  277. if (cols_value == null) {
  278. cols_value = "";
  279. }
  280. map.put(cols_name, cols_value);
  281. }
  282. list.add(map);
  283. }
  284. //关闭数据库
  285. MysqlUtil.releaseConn();
  286. return list;
  287. }
  288.  
  289. /**
  290. * jdbc的封装可以使用反射机制来封装 使用泛型方法
  291. *
  292. * @param sql
  293. * @param params
  294. * @param cls
  295. * @return
  296. * @throws Exception
  297. */
  298. public static <T> T findSimpleRefResult(String sql, List<Object> params,
  299. Class<T> cls) throws Exception {
  300. //加载数据库驱动
  301. new MysqlUtil();
  302. //连接数据库
  303. MysqlUtil.GetConnection();
  304. T resultObject = null;
  305.  
  306. // 表示占位符的第一个位置
  307. int index = 1;
  308. pstmt = connection.prepareStatement(sql);
  309.  
  310. // 判断所填充的占位符是否有值;判断集合的标准方式
  311. if (params != null && !params.isEmpty()) {
  312. for (int i = 0; i < params.size(); i++) {
  313.  
  314. // 第一个是指你SQL语句中的第几个参数,第二个是要设置的值
  315. pstmt.setObject(index++, params.get(i));
  316. }
  317. }
  318.  
  319. // 返回查询结果
  320. resultset = pstmt.executeQuery();
  321.  
  322. // 获取列的相关信息
  323. java.sql.ResultSetMetaData metdata = resultset.getMetaData();
  324.  
  325. // 获取列数
  326. int col_lenth = metdata.getColumnCount();
  327. while (resultset.next()) {
  328.  
  329. // 通过反射机制创建一个实例
  330. resultObject = cls.newInstance();
  331.  
  332. for (int i = 0; i < col_lenth; i++) {
  333. String cols_name = metdata.getColumnName(i + 1);
  334. Object cols_value = resultset.getObject(cols_name);
  335. if (cols_value == null) {
  336. cols_value = "";
  337. }
  338. Field field = cls.getDeclaredField(cols_name);
  339.  
  340. // 打开javabean的私有访问权限
  341. field.setAccessible(true);
  342. field.set(resultObject, cols_value);
  343. }
  344.  
  345. }
  346. //关闭数据库
  347. MysqlUtil.releaseConn();
  348. return resultObject;
  349. }
  350.  
  351. /**
  352. * 通过反射机制访问数据库
  353. *
  354. * @param sql
  355. * @param params
  356. * @param cls
  357. * @return
  358. * @throws Exception
  359. */
  360. public static <T> List<T> findMoreRefResult(String sql, List<Object> params, Class<T> cls) throws Exception {
  361.  
  362. //加载数据库驱动
  363. new MysqlUtil();
  364. //连接数据库
  365. MysqlUtil.GetConnection();
  366. // 构造一个初始容量为 10 的空列表。
  367. List<T> list = new ArrayList<T>();
  368.  
  369. // 表示占位符的第一个位置
  370. int index = 1;
  371.  
  372. pstmt = connection.prepareStatement(sql);
  373.  
  374. System.out.println("MysqlUtil:" + params);
  375. // 判断所填充的占位符是否有值;判断集合的标准方式
  376. if (params != null && !params.isEmpty()) {
  377. for (int i = 0; i < params.size(); i++) {
  378.  
  379. // 使用给定对象设置指定参数的值。第二个参数必须是Object类型
  380. pstmt.setObject(index++, params.get(i));
  381.  
  382. }
  383. }
  384.  
  385. // 返回查询结果
  386. System.out.println("SHQ");
  387. resultset = pstmt.executeQuery();
  388. // 获取列的相关信息
  389. java.sql.ResultSetMetaData metdata = resultset.getMetaData();
  390.  
  391. // 获取列数
  392. int col_lenth = metdata.getColumnCount();
  393. while (resultset.next()) {
  394.  
  395. // 通过反射机制创建一个实例
  396. T resultObject = cls.newInstance();
  397. for (int i = 0; i < col_lenth; i++) {
  398. String cols_name = metdata.getColumnName(i + 1);
  399. Object cols_value = resultset.getObject(cols_name);
  400. if (cols_value == null) {
  401. cols_value = "";
  402. }
  403.  
  404. // 通过列名获得反射
  405. Field field = cls.getDeclaredField(cols_name);
  406.  
  407. // 打开javabean的私有访问权限
  408. field.setAccessible(true);
  409. field.set(resultObject, cols_value);
  410. }
  411. list.add(resultObject);
  412. }
  413. //关闭数据库
  414. MysqlUtil.releaseConn();
  415. return list;
  416. }
  417.  
  418. /**
  419. * 关闭数据库的链接
  420. *
  421. */
  422. public static void releaseConn() {
  423.  
  424. if (resultset != null) {
  425. try {
  426. resultset.close();
  427. } catch (SQLException e) {
  428. e.printStackTrace();
  429. }
  430. }
  431. if (pstmt != null) {
  432. try {
  433. pstmt.close();
  434. } catch (SQLException e) {
  435. e.printStackTrace();
  436. }
  437. }
  438. if (connection != null) {
  439. try {
  440. connection.close();
  441. } catch (SQLException e) {
  442. e.printStackTrace();
  443. }
  444. }
  445. }
  446.  
  447. /**
  448. * 查询返回总页数
  449. *
  450. * @param sql
  451. * @param params
  452. * @return int
  453. * @throws SQLException
  454. */
  455. public static int cluPage(String sql, List<Object> params)
  456. throws SQLException {
  457.  
  458. //存储总页数
  459. int countPage = 0;
  460. //设置每页显示的记录数
  461. int size = 10;
  462. //加载数据库驱动
  463. new MysqlUtil();
  464. //连接数据库
  465. MysqlUtil.GetConnection();
  466. // 表示占位符的第一个位置
  467. int index = 1;
  468. // 此句很重要,需要进行预编译
  469. pstmt = connection.prepareStatement(sql);
  470. // 判断所填充的占位符是否有值;判断集合的标准方式
  471. if (params != null && !params.isEmpty()) {
  472. for (int i = 0; i < params.size(); i++) {
  473.  
  474. // 第一个是指你SQL语句中的第几个参数,第二个是要设置的值
  475. pstmt.setObject(index++, params.get(i));
  476. }
  477. }
  478.  
  479. // 返回查询结果
  480. resultset = pstmt.executeQuery();
  481. if (resultset.next()) {
  482. int total = resultset.getInt("total");
  483. countPage = (total%size == 0 ? total/size : total/size + 1);
  484. }
  485. //关闭数据库
  486. MysqlUtil.releaseConn();
  487. System.out.println("总页数为:" + countPage);
  488. return countPage;
  489. }
  490. /**
  491. * 测试模块
  492. *
  493. * @param args
  494. */
  495. public static void main(String[] args) {
  496. User user = new User();
  497. user.setUid("18353102068");
  498. user.setLogin_time("1");
  499. user.setOut_time("1");
  500. user.setLast_time(10);
  501. System.out.println(new UserDao().add(user));
  502. }
  503. }

以上介绍了数据库的连接方法及常用的查询操作。

其中的常量如下定义:

Const.java

  1. package cn.edu.ujn.base;
  2.  
  3. public class Const {
  4. // 定义数据库的IP
  5. public final static String IP = "localhost";
  6. // 定义数据库的端口
  7. public final static String DBPORT = "3308";
  8. // 定义数据库的名称
  9. public final static String DBNAME = "lab";
  10. // 定义数据库的用户名
  11. public final static String USERNAME = "lmapp";
  12. // 定义数据库的密码
  13. public final static String PASSWORD = "lmapp";
  14. // 定义数据库的驱动信息
  15. public final static String DRIVER = "com.mysql.jdbc.Driver";
  16. // 定义访问数据库的地址
  17. public final static String URL = "jdbc:mysql://" + IP + ":" + DBPORT + "/" + DBNAME;
  18. }

以上只是实现了java连接到数据库,要实现数据的插入等操作,还需要以下方法:

UserDao.java

  1. package cn.edu.ujn.dao;
  2.  
  3. import java.sql.SQLException;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6.  
  7. import cn.edu.ujn.model.User;
  8. import cn.edu.ujn.util.MysqlUtil;
  9.  
  10. public class UserDao {
  11.  
  12. MysqlUtil mysqlUtil = new MysqlUtil();
  13.  
  14. /**
  15. * 添加用户信息
  16. *
  17. * @param user
  18. * @return
  19. */
  20. public int add(User user) {
  21. try {
  22. String sql = "insert into lab_static_attribute(uid,login_time,out_time,last_time) values(?,?,?,?)";
  23. List<Object> params = new ArrayList<Object>();
  24. params.add(user.getUid());
  25. params.add(user.getLogin_time());
  26. params.add(user.getOut_time());
  27. params.add(user.getLast_time());
  28. return MysqlUtil.updateByPreparedStatement(sql, params) ? 1 : 0;
  29. }catch (SQLException e) {
  30. return 0;
  31. }
  32. }
  33. }

这里只是介绍了数据的增加方法,数据库的CRUD其它三种操作方法,请读者自行练习。

总结

相比于框架实现数据库的操作,这里介绍的方法确实需要完成更多的代码。但是对于初学者来说,还是建议通过这种方法来完成数据库的操作。这样可以更多的了解数据库操作的底层操作行为。学知识讲究“知其然,更要知其所以然”。

美文美图

Java进阶(二十五)Java连接mysql数据库(底层实现)的更多相关文章

  1. Java进阶(三十五)java int与integer的区别

    Java进阶(三十五)java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象 ...

  2. Java进阶(四十五)java 字节流与字符流的区别

    java 字节流与字符流的区别(转载)   字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?   实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作 ...

  3. Java进阶(二十四)Java List集合add与set方法原理简介

    Java List集合add与set方法原理简介 add方法 add方法用于向集合列表中添加对象. 语法1 用于在列表的尾部插入指定元素.如果List集合对象由于调用add方法而发生更改,则返回 tr ...

  4. Java进阶(三十九)Java集合类的排序,查找,替换操作

    Java进阶(三十九)Java集合类的排序,查找,替换操作 前言 在Java方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList来表示动态数组.获取到ArrayList对 ...

  5. python3.4学习笔记(二十五) Python 调用mysql redis实例代码

    python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...

  6. 夯实Java基础(二十五)——JDBC使用详解

    1.JDBC介绍 JDBC的全称是Java Data Base Connectivity(Java数据库连接).是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问(例如MyS ...

  7. Navicat 或者Java的JDBC通过SSH Tunnel连接MySQL数据库

    JDBC通过SSH Tunnel连接MySQL数据库 - 明明 - CSDN博客https://blog.csdn.net/a351945755/article/details/21782693 Na ...

  8. 学以致用二十九-----python3连接mysql

    在前面安装好mysql后,在一个项目中需要连接mysql,python是3.6版本 python3连接mysql需要安装pymysql模块 可以通过pip安装 查看pip 版本 pip --versi ...

  9. 第二百七十五节,MySQL数据库安装和介绍

    MySQL数据库安装 一.概述 1.什么是数据库 ? 答:数据的仓库,称其为数据库 2.什么是 MySQL.Oracle.SQLite.Access.MS SQL Server等 ? 答:他们均是一种 ...

随机推荐

  1. 解决Mysql数据库拒绝远程连接和忘记密码的问题

    解决数据库忘记密码的问题 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 编辑m ...

  2. eclipse安装和配置Gradle插件

    配置: 首先下载Gradle:https://gradle.org/gradle-download/ 设置Gradle环境变量: GRADLE_HOME %GRADLE_HOME%\bin" ...

  3. Luogu P1257 平面上的最接近点对_暴力

    这道题数据不大 两点距离用勾股定理求 #include<iostream> #include<cmath> using namespace std; struct node{ ...

  4. markdowm写博客测试

    markdowm测试文档 #include <bits/stdc++.h> using namespace std; int main() { printf("Hello Wor ...

  5. 利用Filter和拦截器,将用户信息动态传入Request方法

    前言: 在开发当中,经常会验证用户登录状态和获取用户信息.如果每次都手动调用用户信息查询接口,会非常的繁琐,而且代码冗余.为了提高开发效率,因此就有了今天这篇文章. 思路: 用户请求我们的方法会携带一 ...

  6. log file sync 因为数据线有问题而造成高等侍的表现

    这是3月份某客户的情况,原因是服务器硬件故障后进行更换之后,业务翻译偶尔出现提交缓慢的情况.我们先来看下awr的情况. 我们可以看到,该系统的load profile信息其实并不高,每秒才21个tra ...

  7. Spark:聚类算法之LDA主题模型算法

    http://blog.csdn.net/pipisorry/article/details/52912179 Spark上实现LDA原理 LDA主题模型算法 [主题模型TopicModel:隐含狄利 ...

  8. Android Multimedia框架总结(十八)Camera2框架从Java层到C++层类关系

    Agenda: getSystemService(Context.CAMERA_SERVICE) CameraManager.getCameraIdList() ICameraService.aidl ...

  9. EBS业务学习之应付管理

    应付款系统是供应链管理的最后一个环节,它使公司能够支付供应商提供的货物和服务的费用.供应链管理的目标是保持低库存量但又有充足的存货以满足要求,仓库中的库存就等于钱,因此,应付款管理的目标是尽可能地推迟 ...

  10. 20 ViewPager Demo4自动轮播

    MainActivity.java 思想:才用非常大的数 让其看起来可以循环轮播图片并且用户可以从尽头滑到首图的特点 . package com.qf.day20_viewpager_demo4; i ...