当前位置: 首页 > news >正文

Java连接MySQL数据库

Java连接数据库目录

  • 一、查找数据库
    • 1.写入到普通的Java文件中
    • 2. 写入到servlet文件中
    • 3. 在Servlat中直接调方法
    • 4. 涉及到的知识点
  • 二、删除数据库
  • 三、添加/修改数据库
  • 四、精简代码
    • 1. 分装加载驱动
    • 2. 分装增删改查操作
      • 涉及到的知识点
  • 五、JDBC
    • JDBC核心组件

一、查找数据库

1.写入到普通的Java文件中

  1. 放jar包:将MySQL驱动jar包放到WebContent->WEB-INF->lib
    放入对应的驱动:
    • MySQL版本为5.几的可以使用mysql-connector-java-5.1.5.jar
    • MySQL版本为8.几的可以使用mysql-connector-j-8.1.0.jar
  2. 加载驱动:固定写法,会报错,原因有二:
    • 忘记放入响应的jar包
    • 异常,有两种处理方式
      • throws ClassNotFoundException:异常抛出,抛给它的调用者->main方法,main方法还不做处理,继续向上抛出
      • try{}catch(){e.printStackTrace();}:自己捕获,执行try中的操作,如果出错,catch会捕获没有找到的异常
  3. 驱动管理类调方法进行连接
    • 接受参数url、user、password,数据库不一定存在,会报异常,也进行捕获
    • 返回一个连接类接口Connection,由于DriverManager是父类,Connection是子类,需要强制转换
  4. 连接对象调用方法 创建执行sql的对象:返回Statement,由于Connection是父类,Statement是子类,需要强制转换
  5. 执行sql的对象调用方法 执行sql语句:返回ResultSet结果集
  6. 处理结果:获取返回结果中的所有字段;可以用字符串拼接,将返回的数据分装为json格式,装到数组中
    • 注意:json格式可以使用json解析工具,将想要的字段写好,直接复制过来即可,这样不易出错
  7. 关闭资源:倒着关闭,后开辟的先关闭;做判断,如果不为空,就让这个对象关闭
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class JavaMysql {public static void main(String[] args) {String sql = "select * from student";String aa= search(sql);System.out.println(aa);}//查找public static String search(String sql) {//加载驱动try {Class.forName("com.mysql.jdbc.Driver");//固定写法//com.mysql.jdbc.Driver:mysql版本5.几的写法//com.mysql.cj.jdbc.Driver:mysql版本8.几的写法String url="jdbc:mysql://localhost:3306/mysqltest";//数据库名修改为自己创建的String user = "root";String password = "root";//驱动管理类调用方法进行连接 得到连接对象  需要强制类型转换Connection connection = (Connection)DriverManager.getConnection(url, user, password);//连接对象调用方法 创建执行sql的对象Statement statement = (Statement) connection.createStatement();//执行sql的对象调用方法 执行sql语句 executeQuery查找 返回查找的结果ResultSet resultSet =  statement.executeQuery(sql);//处理结果String res = "[";while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");String sex = resultSet.getString("sex");int age = resultSet.getInt("age");int classid = resultSet.getInt("classid");System.out.println(id+" "+name+" "+sex+" "+age+" "+classid);res+="{\"id\":"+id+",\"name\":\""+name+"\",\"sex\":\""+sex+"\",\"age\":"+age+",\"classid\":"+classid+"},";	}res = res.substring(0,res.length()-1);//去掉末尾的逗号res+="]";//关闭资源if(resultSet!=null) {resultSet.close();}if(statement!=null) {statement.close();}if(connection!=null) {connection.close();}return res;} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();return "";}}

2. 写入到servlet文件中

  1. 写入到doGet中类中
  2. sql会报错,是因为在main方法中中传的参数,所有要加一个sql变量
  3. 返回return会报错,是因为在servlet中,返回数据使用的是response,使用getWriter().write()写入返回的数据
  4. 变量res写在了try中,所有将其写入到外面
  5. setContentType()设置返回的数据为json格式,并设置编码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String sql = "select * from student";String res = "";//加载驱动try {Class.forName("com.mysql.jdbc.Driver");//固定写法//com.mysql.jdbc.Driver:mysql版本5.几的写法//com.mysql.cj.jdbc.Driver:mysql版本8.几的写法String url="jdbc:mysql://localhost:3306/mysqltest";String user = "root";String password = "root";//驱动管理类调用方法进行连接 得到连接对象  需要强制类型转换Connection connection = (Connection)DriverManager.getConnection(url, user, password);//连接对象调用方法 创建执行sql的对象Statement statement = (Statement) connection.createStatement();//执行sql的对象调用方法 执行sql语句 executeQuery查找 返回查找的结果ResultSet resultSet =  statement.executeQuery(sql);//处理结果res = "[";while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");String sex = resultSet.getString("sex");int age = resultSet.getInt("age");int classid = resultSet.getInt("classid");System.out.println(id+" "+name+" "+sex+" "+age+" "+classid);res+="{\"id\":"+id+",\"name\":\""+name+"\",\"sex\":\""+sex+"\",\"age\":"+age+",\"classid\":"+classid+"},";	}res = res.substring(0,res.length()-1);//去掉末尾的逗号res+="]";//关闭资源if(resultSet!=null) {resultSet.close();}if(statement!=null) {statement.close();}if(connection!=null) {connection.close();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}response.setContentType("text/json,charset=utf-8");response.getWriter().write(res);
}

3. 在Servlat中直接调方法

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String sql = "select * from student";//直接调用写好的JavaMysql类中的search方法String res = JavaMysql.search(sql);response.setContentType("text/json,charset=utf-8");response.getWriter().write(res);
}

4. 涉及到的知识点

  1. Class.forName("com.mysql.jdbc.Driver");:加载驱动的固定写法
  2. DriverManager:为数据库建立连接的
    • getConnection(String url, String user, String password)方法:使用用户名和密码建立连接
  3. Connection:连接类接口,用于执行sql语句
    • createStatement()方法:用于创建一个 Statement 对象,该对象用于向数据库发送并执行静态sql语句
  4. Statement:执行sql语句并返回结果的接口
    • 获取执行结果:
      • 查询返回ResultSet(结果集)
      • 更新返回int(受影响的行数)
    • executeQuery()方法:执行查找,返回ResultSet
    • executeUpdate()方法:执行更新(如 INSERT, UPDATE, DELETE),返回int
  5. ResultSet:表示从数据库查询返回的结果集(类似一个数据表格)
    • next()方法:获取下一行数据,返回true表示有数据
  6. substring(开始, 结束)方法:截取,用于截取字符串中的一部分,范围:左闭右开

二、删除数据库

  1. 删除流程与查找流程大致一样
  2. 执行sql的对象调用方法 执行sql语句,返回的是int受影响的行数
  3. 不需要处理结果
//删除
public static int delete(String sql) {try {Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://localhost:3306/mysqltest";String user = "root";String password = "root";Connection connection = (Connection)DriverManager.getConnection(url, user, password);Statement statement = (Statement) connection.createStatement();int num = statement.executeUpdate(sql);if(statement!=null) {statement.close();}if(connection!=null) {connection.close();}return num;} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();return 0;}
}

三、添加/修改数据库

添加和修改的代码与删除是完全一样的

//添加
public static int add(String sql) {try {Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://localhost:3306/mysqltest";String user = "root";String password = "root";Connection connection = (Connection)DriverManager.getConnection(url, user, password);Statement statement = (Statement) connection.createStatement();int num = statement.executeUpdate(sql);if(statement!=null) {statement.close();}if(connection!=null) {connection.close();}return num;} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();return 0;}
}
//修改
public static int update(String sql) {try {Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://localhost:3306/mysqltest";String user = "root";String password = "root";Connection connection = (Connection)DriverManager.getConnection(url, user, password);Statement statement = (Statement) connection.createStatement();int num = statement.executeUpdate(sql);if(statement!=null) {statement.close();}if(connection!=null) {connection.close();}return num;} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();return 0;}
}

四、精简代码

通过上面的代码可以得出有2个问题:

  • 有许多重复的代码,导致代码冗余
  • 针对查找有一点局限,查找代码中的处理结果写的是student表解析,但凡换一张表就出错

解决方案:

  • 将重复的加载驱动部分的代码单独拎出来,分装为一个类,后续可直接调用;
  • 动态获取字段:传数组存字段,读取字段存入到数组中

1. 分装加载驱动

import java.sql.Connection;
import java.sql.DriverManager;public class DBConnection {String driver = "com.mysql.jdbc.Driver";String url = "jdbc:mysql://localhost:3306/mysqltest";String user = "root";String password = "root";public Connection conn;public DBConnection() {try {Class.forName(driver);conn = (Connection) DriverManager.getConnection(url, user, password);} catch (Exception e) {e.printStackTrace();}}public void close() {try {this.conn.close();} catch (Exception e) {e.printStackTrace();}}
}

2. 分装增删改查操作

import java.rmi.StubNotFoundException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MysqlUtil {//添加public static int add(String sql) {int i=0;DBConnection db = new DBConnection();// 创建数据库连接对象try {        PreparedStatement preStmt = (PreparedStatement) db.conn.prepareStatement(sql);//连接对象调用方法 创建执行sql的对象 获取结果集i=preStmt.executeUpdate();//执行sql语句preStmt.close();//关闭资源db.close();} catch (Exception e) {e.printStackTrace();}return i;}//修改public static int update(String sql) {int i =0;DBConnection db = new DBConnection();try {PreparedStatement preStmt = (PreparedStatement) db.conn.prepareStatement(sql);i = preStmt.executeUpdate();preStmt.close();db.close();} catch (SQLException e) {e.printStackTrace();}return i;}//删除public static int del(String delstr) {int i=0;DBConnection db = new DBConnection();try {    PreparedStatement preStmt = (PreparedStatement) db.conn.prepareStatement(delstr);i=preStmt.executeUpdate();preStmt.close();db.close();} catch (SQLException e){e.printStackTrace();}return i;}//查数量public static int getCount(String sql) {int sum = 0;DBConnection db = new DBConnection();// 创建数据库连接对象try {Statement stmt = (Statement) db.conn.createStatement();//连接对象调用方法 创建执行sql的对象ResultSet rs = (ResultSet) stmt.executeQuery(sql);//执行sql的对象调用方法 执行sql语句 获取结果集while (rs.next()) {//遍历结果集每一行 累加第一列的值sum += rs.getInt(1);}rs.close();//关闭资源db.close();} catch (Exception e) {}return sum;}//查找public static String getJsonBySql( String sql,String[] colums){ArrayList<String[]> result = new ArrayList<String[]>();DBConnection db = new DBConnection();try {Statement stmt = (Statement) db.conn.createStatement();ResultSet rs = (ResultSet) stmt.executeQuery(sql);while(rs.next()){String[] dataRow = new String[colums.length];for( int i = 0; i < dataRow.length; i++ ) {dataRow[i] = rs.getString( colums[i] );}result.add(dataRow);}rs.close();db.close();} catch (SQLException e) {e.printStackTrace();}return listToJson(result,colums);}public static String listToJson( ArrayList<String[]> list,String[] colums) {//分装格式代码}
}

涉及到的知识点

  1. prepareStatement()方法:可以防止sql注入,用法与statement用法一样
  2. sql注入:一种网络安全攻击技术,攻击者通过在应用程序的输入字段中插入恶意的SQL代码片段,从而操纵后端数据库查询,获取未授权访问或执行危险操作。其类型有:
    • 未授权访问型
    -- 原始语句
    SELECT * FROM accounts WHERE account_id = '[用户输入]'
    -- 攻击输入
    1001' OR '1'='1
    -- 最终执行
    SELECT * FROM accounts WHERE account_id = '1001' OR '1'='1'
    -- 返回所有账户数据
    
    • 数据泄露行
    -- 攻击输入
    1001' UNION SELECT username, password FROM users ---- 最终执行
    SELECT * FROM accounts WHERE account_id = '1001' 
    UNION SELECT username, password FROM users --'
    -- 返回账户数据+所有用户凭证
    
    • 数据篡改型
    -- 攻击输入
    1001'; UPDATE users SET password = 'hacked' WHERE username = 'admin' ---- 最终执行
    SELECT * FROM accounts WHERE account_id = '1001'; 
    UPDATE users SET password = 'hacked' WHERE username = 'admin' --'
    -- 修改管理员密码
    
    • 数据库删除行
    -- 攻击输入
    1001'; DROP TABLE accounts ---- 最终执行
    SELECT * FROM accounts WHERE account_id = '1001'; DROP TABLE accounts --'
    -- 删除整个账户表
    

五、JDBC

是Java连接数据库的桥梁。
JDBC(Java Database Connectivity)是Java语言中用来规范客户端程序如何访问数据库的标准应用程序接口(API),它为Java开发者提供了与各种关系型数据库交互的统一方式。

JDBC核心组件

组件作业重要方法
DriverManager管理数据库驱动getConnection():建立与指定数据库的连接,参数有urluserpassword
Connection表示与特定数据库的会话createStatement():创建用于发送静态SQL语句的Statement对象
prepareStatement():创建预编译的PreparedStatement对象,防止 SQL注入
setAutoCommit():设置事务是否自动提交
commit():提交当前事务
Statement用于执行静态SQL语句executeQuery():执行查询语句,返回ResultSet对象
executeUpdate():执行DML/DDL语句,返回受影响的行数
execute():执行任意SQL语句,返回boolean表示结果类型;其中:true:执行的是查询语句,有ResultSet返回;false:执行的是更新语句或没有结果
PreparedStatement预编译SQL语句,防止SQL注入setInt():设置指定位置的整型参数
setString():设置指定位置的字符串参数
等参数绑定方法
ResultSet表示数据库结果集的数据表next():获取下一行数据
getString():获取字符串值
getInt():获取整数值
DataSource更优的连接获取方式(连接池基础)getConnection():从连接池获取数据库连接
http://www.dtcms.com/a/328650.html

相关文章:

  • Socket 套接字常用方法
  • Java多源AI接口融合框架:动态模型切换与智能路由实战
  • pybind11绑定C++项目心得
  • Sentinel 和 Hystrix
  • MySQL 存储过程终止执行的方法
  • 力扣热题100------279.完全平方数
  • XGBoost 的适用场景以及与 CNN、LSTM 的区别
  • AQS的原理与ReentrantLock的关系
  • 基于Rocky Linux 9的容器化部署方案,使用Alpine镜像实现轻量化
  • 企业高性能web服务器(3)
  • Linux学习-应用软件编程(文件IO)
  • 【科研绘图系列】R语言绘制特定区域颜色标记散点图
  • Pytest项目_day13(usefixture方法、params、ids)
  • 【不动依赖】Kali Linux 2025.2 中安装mongosh
  • 【数据结构】二叉树详细解析
  • 安路Anlogic FPGA下载器的驱动安装与测试教程
  • C++联合体的定义
  • 数据结构 二叉树(2)堆
  • 带宽受限信道下的数据传输速率计算:有噪声与无噪声场景
  • C++方向知识汇总(四)
  • PyCATIA高级建模技术:等距平面、点云重命名与棱柱体创建的工业级实现
  • 基于Java与Vue搭建的供应商询报价管理系统,实现询价、报价、比价全流程管理,功能完备,提供完整可运行源码
  • Python训练营打卡Day30-文件的规范拆分和写法
  • 树与二叉树
  • NY198NY203美光固态闪存NY215NY216
  • 串口通信学习
  • Xshell远程连接Ubuntu 24.04.2 LTS虚拟机
  • 模型 霍特林法则
  • 自动驾驶 HIL 测试:构建 “以假乱真” 的实时数据注入系统
  • 【JavaEE】多线程之线程安全(上)