Java进阶(二十五)Java连接mysql数据库(底层实现)
Java进阶(二十五)Java连接mysql数据库(底层实现)
前言
很长时间没有系统的使用java做项目了。现在需要使用java完成一个实验,其中涉及到java连接数据库。让自己来写,记忆中已无从搜索。特将之前使用的方法做一简单的总结。也能够在底层理解一下连接数据库的具体步骤。
实现
首先需要导入相关的jar包,我使用的为:mysql-connector-java-5.1.7-bin.jar。
下面来看一下我所使用的数据库连接方法类:
MysqlUtil.java
- package cn.edu.ujn.util;
- import java.lang.reflect.Field;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.ResultSetMetaData;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import cn.edu.ujn.base.Const;
- import cn.edu.ujn.dao.UserDao;
- import cn.edu.ujn.model.User;
- public class MysqlUtil {
- // 定义数据库的用户名
- private final static String USERNAME = Const.USERNAME;
- // 定义数据库的密码
- private final static String PASSWORD = Const.PASSWORD;
- // 定义数据库的驱动信息
- private final String DRIVER = Const.DRIVER;
- // 定义访问数据库的地址
- private final static String URL = Const.URL;
- // 定义数据库的链接
- private static Connection connection;
- // 定义sql语句的执行对象
- private static PreparedStatement pstmt;// 只有在获得了Statement之后才可执行SQL语句
- // 定义查询返回的结果集合
- private static ResultSet resultset;
- public MysqlUtil() {
- try {
- Class.forName(DRIVER);// 显式地加载 JDBC 驱动程序
- System.out.println("注册驱动成功!");
- } catch (Exception e) {
- System.out.println("注册驱动失败!");
- }
- }
- /**
- * 定义获得数据库的链接,试图建立到给定数据库 URL 的连接
- *
- * @return connection
- */
- public static Connection GetConnection() {
- try {
- connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
- System.out.println("数据库连接成功!");
- } catch (Exception e) {
- System.out.println("数据库连接失败!");
- }
- return connection;
- }
- /**
- * 完成对数据库表的增加、删除、更新操作
- *
- * @param sql
- * @param params
- * @return flag
- * @throws SQLException
- */
- public static boolean updateByPreparedStatement(String sql, List<Object> params)// 第二个参数为传输的占位符
- throws SQLException {
- //加载数据库驱动
- new MysqlUtil();
- //连接数据库
- MysqlUtil.GetConnection();
- boolean flag = false;
- // 表示当用户执行添加、删除、修改时所影响数据库的行数
- int result = -1;
- try {
- pstmt = connection.prepareStatement(sql);
- } catch (Exception e) {
- System.out.println("Error in updateByPreparedStatement!");
- }
- // 表示占位符的第一个位置
- int index = 1;
- // 判断所填充的占位符是否有值;判断集合的标准方式
- if (params != null && !params.isEmpty()) {
- for (int i = 0; i < params.size(); i++) {
- // System.out.println(i+" "+params.get(i));
- // 使用给定对象设置指定参数的值。第二个参数必须是Object类型
- pstmt.setObject(index++, params.get(i));
- }
- }
- result = pstmt.executeUpdate();// 用于执行DML语句-返回一个整数,代表被SQL语句影响的记录条数
- flag = result > 0 ? true : false;
- System.out.println("执行SQL语句影响的记录条数为:" + result);
- //关闭数据库
- MysqlUtil.releaseConn();
- return flag;
- }
- /**
- * 查询返回单条记录
- *
- * @param sql
- * @param params
- * @return map
- * @throws SQLException
- */
- public static Map<String, Object> findSimpleResult(String sql, List<Object> params)
- throws SQLException {
- //加载数据库驱动
- new MysqlUtil();
- //连接数据库
- MysqlUtil.GetConnection();
- // 菱形语法在Java7及以后可用
- Map<String, Object> map = new HashMap<String, Object>();
- // 表示占位符的第一个位置
- int index = 1;
- // 此句很重要,需要进行预编译
- pstmt = connection.prepareStatement(sql);
- // 判断所填充的占位符是否有值;判断集合的标准方式
- if (params != null && !params.isEmpty()) {
- for (int i = 0; i < params.size(); i++) {
- // 第一个是指你SQL语句中的第几个参数,第二个是要设置的值
- pstmt.setObject(index++, params.get(i));
- }
- }
- // 返回查询结果
- resultset = pstmt.executeQuery();
- // 获取此 ResultSet 对象的列的编号、类型和属性。
- java.sql.ResultSetMetaData metdata = resultset.getMetaData();
- // 获取列数
- int col_lenth = metdata.getColumnCount();
- boolean flag = resultset.next();
- if (!flag) {
- System.out.println("Found nothing!");
- }
- while (resultset.next()) {
- for (int i = 0; i < col_lenth; i++) {
- // 获取指定列的名称
- String cols_name = metdata.getColumnName(i + 1);
- // 通过列名获得指定列的属性值
- Object cols_value = resultset.getObject(cols_name);
- if (cols_value == null) {
- // 由此可见,数据表中字段值不能为空
- cols_value = "";
- }
- // 将指定的值与此映射中的指定键关联(可选操作)。
- map.put(cols_name, cols_value);
- }
- }
- //关闭数据库
- MysqlUtil.releaseConn();
- return map;
- }
- /**
- * 通过反射机制访问数据库,查询前几页的内容
- *
- * @param sql
- * @param params
- * @param cls
- * @return
- * @throws Exception
- */
- public static <T> List<T> queryEvamall(String sql, List<Object> params,
- Class<T> cls) throws Exception {
- //加载数据库驱动
- new MysqlUtil();
- //连接数据库
- MysqlUtil.GetConnection();
- // 构造一个初始容量为 10 的空列表。
- List<T> list = new ArrayList<T>();
- // 表示占位符的第一个位置
- int index = 1;
- pstmt = connection.prepareStatement(sql);
- // 判断所填充的占位符是否有值;判断集合的标准方式
- if (params != null && !params.isEmpty()) {
- for (int i = 0; i < params.size(); i++) {
- // 使用给定对象设置指定参数的值。第二个参数必须是Object类型
- pstmt.setObject(index++, params.get(i));
- }
- }
- // 返回查询结果
- resultset = pstmt.executeQuery();
- // 获取列的相关信息
- java.sql.ResultSetMetaData metdata = resultset.getMetaData();
- // 获取列数
- int col_lenth = metdata.getColumnCount();
- while (resultset.next()) {
- // 通过反射机制创建一个实例
- T resultObject = cls.newInstance();
- for (int i = 0; i < col_lenth; i++) {
- String cols_name = metdata.getColumnName(i + 1);
- Object cols_value = resultset.getObject(cols_name);
- if (cols_value == null) {
- cols_value = "";
- }
- // 通过列名获得反射
- Field field = cls.getDeclaredField(cols_name);
- // 打开javabean的私有访问权限
- field.setAccessible(true);
- field.set(resultObject, cols_value);
- }
- list.add(resultObject);
- }
- //关闭数据库
- MysqlUtil.releaseConn();
- return list;
- }
- /**
- * 查询返回多条查询记录
- *
- * @param sql
- * @param params
- * @return
- * @throws SQLException
- */
- public static List<Map<String, Object>> findMoreResult(String sql,
- List<Object> params) throws SQLException {
- //加载数据库驱动
- new MysqlUtil();
- //连接数据库
- MysqlUtil.GetConnection();
- System.out.println("JJ");
- List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
- // 表示占位符的第一个位置
- int index = 1;
- pstmt = connection.prepareStatement(sql);
- // 判断所填充的占位符是否有值;判断集合的标准方式
- if (params != null && !params.isEmpty()) {
- for (int i = 0; i < params.size(); i++) {
- pstmt.setObject(index++, params.get(i));// 使用给定对象设置指定参数的值。第二个参数必须是
- // Object类型
- }
- }
- try {
- resultset = pstmt.executeQuery();// 返回查询结果
- } catch (Exception e) {
- System.out.println("Error1!");// 调试用
- }
- ResultSetMetaData metdata = resultset.getMetaData();// 获取列的相关信息
- int col_lenth = metdata.getColumnCount();// 获取列数
- System.out.println("数据表列数为:" + col_lenth);// 调试用
- while (resultset.next()) {
- Map<String, Object> map = new HashMap<String, Object>();
- for (int i = 0; i < col_lenth; i++) {
- String cols_name = metdata.getColumnName(i + 1);// 获取列的名称,列从1开始
- Object cols_value = resultset.getObject(cols_name);
- if (cols_value == null) {
- cols_value = "";
- }
- map.put(cols_name, cols_value);
- }
- list.add(map);
- }
- //关闭数据库
- MysqlUtil.releaseConn();
- return list;
- }
- /**
- * jdbc的封装可以使用反射机制来封装 使用泛型方法
- *
- * @param sql
- * @param params
- * @param cls
- * @return
- * @throws Exception
- */
- public static <T> T findSimpleRefResult(String sql, List<Object> params,
- Class<T> cls) throws Exception {
- //加载数据库驱动
- new MysqlUtil();
- //连接数据库
- MysqlUtil.GetConnection();
- T resultObject = null;
- // 表示占位符的第一个位置
- int index = 1;
- pstmt = connection.prepareStatement(sql);
- // 判断所填充的占位符是否有值;判断集合的标准方式
- if (params != null && !params.isEmpty()) {
- for (int i = 0; i < params.size(); i++) {
- // 第一个是指你SQL语句中的第几个参数,第二个是要设置的值
- pstmt.setObject(index++, params.get(i));
- }
- }
- // 返回查询结果
- resultset = pstmt.executeQuery();
- // 获取列的相关信息
- java.sql.ResultSetMetaData metdata = resultset.getMetaData();
- // 获取列数
- int col_lenth = metdata.getColumnCount();
- while (resultset.next()) {
- // 通过反射机制创建一个实例
- resultObject = cls.newInstance();
- for (int i = 0; i < col_lenth; i++) {
- String cols_name = metdata.getColumnName(i + 1);
- Object cols_value = resultset.getObject(cols_name);
- if (cols_value == null) {
- cols_value = "";
- }
- Field field = cls.getDeclaredField(cols_name);
- // 打开javabean的私有访问权限
- field.setAccessible(true);
- field.set(resultObject, cols_value);
- }
- }
- //关闭数据库
- MysqlUtil.releaseConn();
- return resultObject;
- }
- /**
- * 通过反射机制访问数据库
- *
- * @param sql
- * @param params
- * @param cls
- * @return
- * @throws Exception
- */
- public static <T> List<T> findMoreRefResult(String sql, List<Object> params, Class<T> cls) throws Exception {
- //加载数据库驱动
- new MysqlUtil();
- //连接数据库
- MysqlUtil.GetConnection();
- // 构造一个初始容量为 10 的空列表。
- List<T> list = new ArrayList<T>();
- // 表示占位符的第一个位置
- int index = 1;
- pstmt = connection.prepareStatement(sql);
- System.out.println("MysqlUtil:" + params);
- // 判断所填充的占位符是否有值;判断集合的标准方式
- if (params != null && !params.isEmpty()) {
- for (int i = 0; i < params.size(); i++) {
- // 使用给定对象设置指定参数的值。第二个参数必须是Object类型
- pstmt.setObject(index++, params.get(i));
- }
- }
- // 返回查询结果
- System.out.println("SHQ");
- resultset = pstmt.executeQuery();
- // 获取列的相关信息
- java.sql.ResultSetMetaData metdata = resultset.getMetaData();
- // 获取列数
- int col_lenth = metdata.getColumnCount();
- while (resultset.next()) {
- // 通过反射机制创建一个实例
- T resultObject = cls.newInstance();
- for (int i = 0; i < col_lenth; i++) {
- String cols_name = metdata.getColumnName(i + 1);
- Object cols_value = resultset.getObject(cols_name);
- if (cols_value == null) {
- cols_value = "";
- }
- // 通过列名获得反射
- Field field = cls.getDeclaredField(cols_name);
- // 打开javabean的私有访问权限
- field.setAccessible(true);
- field.set(resultObject, cols_value);
- }
- list.add(resultObject);
- }
- //关闭数据库
- MysqlUtil.releaseConn();
- return list;
- }
- /**
- * 关闭数据库的链接
- *
- */
- public static void releaseConn() {
- if (resultset != null) {
- try {
- resultset.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (pstmt != null) {
- try {
- pstmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (connection != null) {
- try {
- connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * 查询返回总页数
- *
- * @param sql
- * @param params
- * @return int
- * @throws SQLException
- */
- public static int cluPage(String sql, List<Object> params)
- throws SQLException {
- //存储总页数
- int countPage = 0;
- //设置每页显示的记录数
- int size = 10;
- //加载数据库驱动
- new MysqlUtil();
- //连接数据库
- MysqlUtil.GetConnection();
- // 表示占位符的第一个位置
- int index = 1;
- // 此句很重要,需要进行预编译
- pstmt = connection.prepareStatement(sql);
- // 判断所填充的占位符是否有值;判断集合的标准方式
- if (params != null && !params.isEmpty()) {
- for (int i = 0; i < params.size(); i++) {
- // 第一个是指你SQL语句中的第几个参数,第二个是要设置的值
- pstmt.setObject(index++, params.get(i));
- }
- }
- // 返回查询结果
- resultset = pstmt.executeQuery();
- if (resultset.next()) {
- int total = resultset.getInt("total");
- countPage = (total%size == 0 ? total/size : total/size + 1);
- }
- //关闭数据库
- MysqlUtil.releaseConn();
- System.out.println("总页数为:" + countPage);
- return countPage;
- }
- /**
- * 测试模块
- *
- * @param args
- */
- public static void main(String[] args) {
- User user = new User();
- user.setUid("18353102068");
- user.setLogin_time("1");
- user.setOut_time("1");
- user.setLast_time(10);
- System.out.println(new UserDao().add(user));
- }
- }
以上介绍了数据库的连接方法及常用的查询操作。
其中的常量如下定义:
Const.java
- package cn.edu.ujn.base;
- public class Const {
- // 定义数据库的IP
- public final static String IP = "localhost";
- // 定义数据库的端口
- public final static String DBPORT = "3308";
- // 定义数据库的名称
- public final static String DBNAME = "lab";
- // 定义数据库的用户名
- public final static String USERNAME = "lmapp";
- // 定义数据库的密码
- public final static String PASSWORD = "lmapp";
- // 定义数据库的驱动信息
- public final static String DRIVER = "com.mysql.jdbc.Driver";
- // 定义访问数据库的地址
- public final static String URL = "jdbc:mysql://" + IP + ":" + DBPORT + "/" + DBNAME;
- }
以上只是实现了java连接到数据库,要实现数据的插入等操作,还需要以下方法:
UserDao.java
- package cn.edu.ujn.dao;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.List;
- import cn.edu.ujn.model.User;
- import cn.edu.ujn.util.MysqlUtil;
- public class UserDao {
- MysqlUtil mysqlUtil = new MysqlUtil();
- /**
- * 添加用户信息
- *
- * @param user
- * @return
- */
- public int add(User user) {
- try {
- String sql = "insert into lab_static_attribute(uid,login_time,out_time,last_time) values(?,?,?,?)";
- List<Object> params = new ArrayList<Object>();
- params.add(user.getUid());
- params.add(user.getLogin_time());
- params.add(user.getOut_time());
- params.add(user.getLast_time());
- return MysqlUtil.updateByPreparedStatement(sql, params) ? 1 : 0;
- }catch (SQLException e) {
- return 0;
- }
- }
- }
这里只是介绍了数据的增加方法,数据库的CRUD其它三种操作方法,请读者自行练习。
总结
相比于框架实现数据库的操作,这里介绍的方法确实需要完成更多的代码。但是对于初学者来说,还是建议通过这种方法来完成数据库的操作。这样可以更多的了解数据库操作的底层操作行为。学知识讲究“知其然,更要知其所以然”。
美文美图
Java进阶(二十五)Java连接mysql数据库(底层实现)的更多相关文章
- Java进阶(三十五)java int与integer的区别
Java进阶(三十五)java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象 ...
- Java进阶(四十五)java 字节流与字符流的区别
java 字节流与字符流的区别(转载) 字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢? 实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作 ...
- Java进阶(二十四)Java List集合add与set方法原理简介
Java List集合add与set方法原理简介 add方法 add方法用于向集合列表中添加对象. 语法1 用于在列表的尾部插入指定元素.如果List集合对象由于调用add方法而发生更改,则返回 tr ...
- Java进阶(三十九)Java集合类的排序,查找,替换操作
Java进阶(三十九)Java集合类的排序,查找,替换操作 前言 在Java方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList来表示动态数组.获取到ArrayList对 ...
- python3.4学习笔记(二十五) Python 调用mysql redis实例代码
python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...
- 夯实Java基础(二十五)——JDBC使用详解
1.JDBC介绍 JDBC的全称是Java Data Base Connectivity(Java数据库连接).是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问(例如MyS ...
- Navicat 或者Java的JDBC通过SSH Tunnel连接MySQL数据库
JDBC通过SSH Tunnel连接MySQL数据库 - 明明 - CSDN博客https://blog.csdn.net/a351945755/article/details/21782693 Na ...
- 学以致用二十九-----python3连接mysql
在前面安装好mysql后,在一个项目中需要连接mysql,python是3.6版本 python3连接mysql需要安装pymysql模块 可以通过pip安装 查看pip 版本 pip --versi ...
- 第二百七十五节,MySQL数据库安装和介绍
MySQL数据库安装 一.概述 1.什么是数据库 ? 答:数据的仓库,称其为数据库 2.什么是 MySQL.Oracle.SQLite.Access.MS SQL Server等 ? 答:他们均是一种 ...
随机推荐
- 解决Mysql数据库拒绝远程连接和忘记密码的问题
解决数据库忘记密码的问题 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 编辑m ...
- eclipse安装和配置Gradle插件
配置: 首先下载Gradle:https://gradle.org/gradle-download/ 设置Gradle环境变量: GRADLE_HOME %GRADLE_HOME%\bin" ...
- Luogu P1257 平面上的最接近点对_暴力
这道题数据不大 两点距离用勾股定理求 #include<iostream> #include<cmath> using namespace std; struct node{ ...
- markdowm写博客测试
markdowm测试文档 #include <bits/stdc++.h> using namespace std; int main() { printf("Hello Wor ...
- 利用Filter和拦截器,将用户信息动态传入Request方法
前言: 在开发当中,经常会验证用户登录状态和获取用户信息.如果每次都手动调用用户信息查询接口,会非常的繁琐,而且代码冗余.为了提高开发效率,因此就有了今天这篇文章. 思路: 用户请求我们的方法会携带一 ...
- log file sync 因为数据线有问题而造成高等侍的表现
这是3月份某客户的情况,原因是服务器硬件故障后进行更换之后,业务翻译偶尔出现提交缓慢的情况.我们先来看下awr的情况. 我们可以看到,该系统的load profile信息其实并不高,每秒才21个tra ...
- Spark:聚类算法之LDA主题模型算法
http://blog.csdn.net/pipisorry/article/details/52912179 Spark上实现LDA原理 LDA主题模型算法 [主题模型TopicModel:隐含狄利 ...
- Android Multimedia框架总结(十八)Camera2框架从Java层到C++层类关系
Agenda: getSystemService(Context.CAMERA_SERVICE) CameraManager.getCameraIdList() ICameraService.aidl ...
- EBS业务学习之应付管理
应付款系统是供应链管理的最后一个环节,它使公司能够支付供应商提供的货物和服务的费用.供应链管理的目标是保持低库存量但又有充足的存货以满足要求,仓库中的库存就等于钱,因此,应付款管理的目标是尽可能地推迟 ...
- 20 ViewPager Demo4自动轮播
MainActivity.java 思想:才用非常大的数 让其看起来可以循环轮播图片并且用户可以从尽头滑到首图的特点 . package com.qf.day20_viewpager_demo4; i ...