创建项目前的准备工作 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