创建项目前的准备工作
1.软件IDEA
2.安装了数据库mysql
3.mysql数据库连接驱动jar包
一.现在我们开始在IDEA下创建Java项目
1.首先点击Create New Project
2.在点击Java,点击Next,再点击Next
3.最后给项目起个名字,点击Finish完成项目创建
二:数据库连接Jar包导入并且加载到项目中:
1.右键点击项目名依次点击new–>Directory 创建文件夹lib
2.把mysql-connector-java-5.1.48-bin.jar包粘贴到lib目录中
3.把数据库连接jar包导入到项目中
注意的是未导入到项目前,点击mysql-connector-java-5.1.48-bin.jar是不会出现任何子文件夹。接下来完成第3步,我们要右键点击该jar包,再点击Add as Library,最后点击OK即可
这时我们可以点击mysql-connector-java-5.1.48-bin.jar,并且可以看到内部的子文件,说明jar包导入项目成功。
三.书写Java代码,连接数据库且完成增删改查
1.在src文件夹下创建JDBCTEST文件夹,并且创建名为Test的类
2.运行数据库java代码放到该类中(对应代码做了注释)
3.点击运行查看结果
代码如下:
package JDBCTEST;
import java.sql.*;
public class Test {
public static void main(String[] args) {
// 加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
String url = "jdbc:mysql://localhost:3306/usejdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String user = "root";
String password = "123456";
try {
// 连接对象输入三个参数
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println(connection);
//定义sql语句
// 插入
String sql = "insert into student(username,password) values ('王五','111111')";
// Statement statement = connection.createStatement();
// int count = statement.executeUpdate(sql);
// System.out.println(count);
//------------------------------------------------------------
// 查询
String sql1 = "select * from student";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql1);
System.out.println(resultSet);
while(resultSet.next()){
// 下标或者字段
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String password1= resultSet.getString(3);
System.out.println(id+"-"+username+"-"+password1);
}
// ----------------------------------------------------------------
// 释放资源
statement.close();
connection.close();
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
点击运行按钮,控制台输出如下的结果:查询后台数据表内的数据:
4.JDBC使用步骤
1.加载数据库的驱动,它是java和数据库之间的桥梁
2.获取Connection,java和数据库的一次连接
3.创建Statement对象,由Connection产生,执行sql语句
4.如果要接收返回值,创建ResultSet对象,保存Statement执行后所查到的结果
// 获取连接
String url = "jdbc:mysql://localhost:3306/usejdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String user = "root";
String password = "123456";
解释:
localhost :IP地址(本地)
3306:端口号
usejdbc 数据库名
useUnicode=true&characterEncoding=UTF-8 防止中文乱码
&useSSL=false 高版本mysql要添加(5.0以上)
String user = “root”; 数据库登录账号(默认root)
String password = “123456”;(数据库设置的密码)
5.数据库的增删改查
首先数据库的增删改查代码都大体相同,不同的仅仅是sql语句和statment执行对象有一些变化。
(1)增,删,改:
int count = statement.executeUpdate(sql);
(2)查:
ResultSet resultSet = statement.executeQuery(sql);
有人会问为啥增删改查不能调用一个方法呢。那是因为增删改会对数据产生影响·,查不会改变数据,因此用到两个不同方法。以后遇到增删改就用方法(1),查询就用方法(2)。
(3)我们首先从增删改开始(代码如下):
package cn.web.jdbc;
import java.sql.*;
public class executeUpdate {
public static void main(String[] args) {
// 加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
String url = "jdbc:mysql://localhost:3306/usejdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String user = "root";
String password = "123456";
try {
// 连接对象输入三个参数
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println(connection);
//定义sql语句
// 增
String sql1 = "insert into student(username,password) values ('诸葛亮','111111')";
// 删
String sql2 = "delete from student where username ='诸葛亮'";
// 改
String sql3 = "update student set username='老八' where id = 1 ";
Statement statement = connection.createStatement();
// 修改这里的sql即可
int count = statement.executeUpdate(sql1);
System.out.println(count);
// ----------------------------------------------------------------
// 释放资源
statement.close();
connection.close();
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
我们只需要替换上述代码第28行的.executeUpdate( )括号内部的sql语句就可完成数据库的增删改。
sql1:完成数据的插入;
sql2:完成数据的删除;
sql3:完成数据的修改;
(sql1,sql2,sql3)三步依次完成后数据表的结果是(用的是Navicat查看student表数据):
(4) 最后的查询就模拟用户登录来结束(代码如下):
package cn.web.jdbc;
import java.sql.*;
public class UserLogin {
public static void main(String[] args) {
// 加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
String url = "jdbc:mysql://localhost:3306/usejdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String user = "root";
String mysqlPassword = "123456";
//模拟前台传入的用户名和密码
String InputUsername = "老八";
String InputPassword = "123456";
try {
// 连接对象输入三个参数
Connection connection = DriverManager.getConnection(url, user, mysqlPassword);
System.out.println(connection);
//定义sql语句
// 查询
String sql1 = "select * from student where username='" + InputUsername + "' and password='" + InputPassword + "'";
System.out.println(sql1);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql1);
System.out.println(resultSet);
if (resultSet.next()) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
// 释放资源
statement.close();
connection.close();
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
控制台输出结果:
6.最后来说说sql的注入问题
如果将上述登录代码的15行,16行修改为下图所示的样子:
会发现无论红线内的文字我们写什么,运行java代码都会显示查询成功。
修改后的java代码入下:
package cn.web.jdbc;
import java.sql.*;
public class UserLogin {
public static void main(String[] args) {
// 加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
String url = "jdbc:mysql://localhost:3306/usejdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String user = "root";
String mysqlPassword = "123456";
// String InputUsername = "老八";
// String InputPassword = "123456";
String InputUsername = "我不是用户";
String InputPassword = "8888' or '1' ='1";
try {
// 连接对象输入三个参数
Connection connection = DriverManager.getConnection(url, user, mysqlPassword);
System.out.println(connection);
//定义sql语句
// 查询
String sql1 = "select * from student where username='" + InputUsername + "' and password='" + InputPassword + "'";
System.out.println(sql1);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql1);
System.out.println(resultSet);
if (resultSet.next()) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
// 释放资源
statement.close();
connection.close();
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
我们会发现原始的JDBC有两个缺点:
(1)复杂的sql字符串拼接;
在上面select 的sql语句:
仅仅两个参数就比较复杂,而且还要注意单引号,这会让我们很容易写错sql语句(如下图)
(2)sql注入问题;
利用某些系统没有对用户输入的信息充分检测,在用户的数据中注入非法的SQL语句,从而利用系统的SQL引擎完成恶意的行为做法。说白了就是通过mysql语句本身的漏洞。在控制台输出sql语句发现无论前面你写什么,后面的 or ‘1’ =‘1’ 一定成立。这也是字符串不当的拼接导致的。
如何解决上述两个困扰:可以使用Statement 的一个子类PreparedStatement,提供SQL占位符功能。
代码如下:
package cn.web.jdbc;
import java.sql.*;
public class EscJdbc {
public static void main(String[] args) {
// 加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
String url = "jdbc:mysql://localhost:3306/usejdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String user = "root";
String mysqlPassword = "123456";
String InputUsername = "张三";
String InputPassword = "8888' or '1' ='1";
try {
// 连接对象输入三个参数
Connection connection = DriverManager.getConnection(url, user, mysqlPassword);
System.out.println(connection);
//定义sql语句
// 查询
String sql = "select * from student where username=? and password=?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,InputUsername);
preparedStatement.setString(2,InputPassword);
ResultSet resultSet = preparedStatement.executeQuery();
System.out.println(resultSet);
if (resultSet.next()) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
// 释放资源
preparedStatement.close();
connection.close();
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
解释(仅仅修改了4行代码):
① 把用户名和密码用问号代替,这就避免了字符串的拼接;
② 执行sql对象
③ 第一个问号填补字符串 : “张三”
④ 第二个问号填补字符串 : “8888’ or ‘1’ ='1”
有几个问号就添加几个数据,保持sql语句完整,同时也防止了sql的注入问题。那是因为该方法会把密码为:“8888’ or ‘1’ ='1” 和后台数据库密码那一栏的数据进行一一比对,如下图的 密码 123456 会和密码 “8888’ or ‘1’ ='1” 进行比对明显二者是不一致。
运行程序,控制台会输出登录失败
最后,我会把这个小模块的源代码以及涉及的数据库连接jar包,数据库管理工具Navicat(破解)放在百度网盘大家可根据需求自行下载
点击:点击获取
提取码:4sn9