版权声明:转载请注明出处 : https://blog.csdn.net/coder_what/article/details/91373479
Copyright©stonee
光说不练空把式
前言
- 本文适合新手
- 数据库为MySQL8.0
- ida为IDEA
MySQL准备工作
下载
- 到官网下载MySQL,因为老版本许多坑都已经被踩过,所以如果想要入门学习还是不要用新版本。
- 安装的时候建议安装MySQL Server x.0 + Connector J x.0,前者为数据库本身,后者为响应版本对应的JDBC接口
MySQL的常用操作和SQL语言
使用工具连接到数据库
- 通过navicat,使用方式略过
- 通过cmd
- 首先将目录cd到MySQL Server 中的bin目录里面
- 输入
mysql.exe -u root -p
+密码
连接数据库
- 通过IDEA
- 打开IDEA后,默认右侧竖着的框中有一个Database选项
- 点击选项后弹出方框,点击+,新建一个MySQL数据库连接
- 按照提示输入用户名,数据库名,和密码(数据库名不是MySQL,MySQL中有好多数据库,可以使新建的,也可以是自带的)
- 注意:MySQL8.0版本不需要建立SSL连接,所以IDEA默认的会连接不上,我们需要自己改下URL:
jdbc:mysql://localhost:3306/world?useSSL=false&serverTimezone=Hongkong&characterEncoding=utf-8&autoReconnect=true
- 使用MySQL中自带数据库或者通过DDL新建一个专门用于联系的数据库均可
导入MySQL的Jar包
- 参考java servlet,这篇文章中有IDEA导入jar包的方式
JDBC起手式
要想连接到数据库,有固定的方式和必不可少的操作步骤
-
第一步,通过
DriverManage
类注册并管理数据库驱动DriverManage.registerDriver(Driver driver) //MySQL5以后也可以通过下面方式来获取 Class.forName("com.mysql.cj.jdbc.Driver");
-
第二步,通过
Connection
类来建立和数据库的连接Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/world?useSSL=false&serverTimezone=Hongkong&characterEncoding=utf-8&autoReconnect=true","root","password");
-
第三步,通过
Statement
类来执行SQL语句Statement statement = connection.createStatement(); statement.executeQuery("select * from world");
-
第四步,通过
ResultSet
类来获取执行结果ResultSet resultSet = statement.executeQuery("select ID,Name from city"); while (resultSet.next()){ System.out.println(resultSet.getInt("Id") + resultSet.getString("Name")); }
-
第五步,捕获响应异常并关闭连接
statement.close(); connection.close(); resultSet.close();
-
一个栗子
package jdbc; import java.sql.*; public class Demo1 { public static void main(String[] args) throws SQLException { Connection connection = null; Statement statement = null; ResultSet resultSet = null; try{ //注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //建立连接 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/world?useSSL=false&serverTimezone=Hongkong&characterEncoding=utf-8&autoReconnect=true","root","password"); //创建statement statement = connection.createStatement(); //执行查询 resultSet = statement.executeQuery("select ID,Name from city"); while (resultSet.next()){ System.out.println(resultSet.getInt("Id") + resultSet.getString("Name")); } }catch (SQLException | ClassNotFoundException e){ e.printStackTrace(); }finally { try{ if (resultSet != null){ resultSet.close(); } }catch (SQLException e){ e.printStackTrace(); }finally { resultSet = null; } statement.close(); connection.close(); } } }
一个对充复代码的小封装
既然上面的起手式除了数据库用户名密码之外别的都是重复的,那我们可不可以写一个工具类来解决这个问题?
package jdbc;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
private static String driverClass = null;
private static String url = null;
private static String name = null;
private static String password = null;
//读取配置文件
static {
Properties properties = new Properties();
try {
properties.load(new FileInputStream("src\\jdbc\\jdbc.properties"));
} catch (IOException e) {
e.printStackTrace();
}
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
name = properties.getProperty("name");
password = properties.getProperty("password");
}
//注册
static Connection register(){
Connection connection = null;
try {
//4.0之后不用注册
Class.forName(driverClass);
connection = DriverManager.getConnection(url,name,password);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return connection;
}
//关闭资源
public static void close(ResultSet resultSet, Connection connection, Statement statement){
try{
if (resultSet != null){
resultSet.close();
}
if (connection != null){
connection.close();
}
if (statement != null){
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
resultSet = null;
connection = null;
statement = null;
}
}
}
前端只需要:
扫描二维码关注公众号,回复:
6461778 查看本文章
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try{
connection = JDBCUtils.register();
//创建statement
statement = connection.createStatement();
//执行查询
resultSet = statement.executeQuery("select ID,Name from aa");
while (resultSet.next()){
System.out.println(resultSet.getInt("Id") + resultSet.getString("Name"));
}
}catch (SQLException e){
e.printStackTrace();
}finally {
JDBCUtils.close(resultSet, connection, statement);
}
JDBC对SQL注入的防范
大家有兴趣的话可以上网百度,刷刷相关的SQL注入题,就明白了,这里不多讲
注入的例子
String q = scanner.nextLine();
try{
connection = JDBCUtils.register();
String sql = "select * from aa where Name = '" + q + "';";
Statement statement1 = connection.createStatement();
resultSet = statement1.executeQuery(sql);
}
正常逻辑下,当输入的q符合Name中的一个才会返回有效值:
Java
4Java
但是我们可以利用SQL中的语法漏洞,把数据库中的所有内容全部爆出来:
' or 1 = 1 or Id = '
1stonee
2WCX
3coolshell
4Java
5Ruby
6Python
7C#
8PHP
9JavaScript
PrepareStatement
JDBC对SQL注入主要是通过对输入的字符串进行过滤,这是需要引入一个
PrepareStatement
类来实现该功能
String q = scanner.next();
try{
connection = JDBCUtils.register();
//创建statement
String sql = "select * from aa where Name = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//对q进行过滤
preparedStatement.setString(1,q);
}
它会自动对?内的进行过滤,同时因为只是传入了?所以,preparestatement会先将除了?的SQL语句进行预编译,传入不同参数,只编译一次,大大提高了效率。
想要玩SQl注入的同学可以搞个DVWA来试试,DVWA需要依赖XMAPP
JDBC对事物的处理
- JDBC默认自动提交事物,如果想要对事物进行复杂处理可以通过
connection.setAutoCommit(false)
将事物提交设置为手动提交 - 然后可以通过
connection.commit()
和connection.rollback()
对事物进行提交和回滚