cgb2111-day06
Posted cgblpx皮皮霞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cgb2111-day06相关的知识,希望对你有一定的参考价值。
文章目录
一,JDBC 练习
–1,利用jdbc给user表中,添加一个用户的信息
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.Statement;
//写jdbc的代码,向user表里的添加一条数据
public class Test3
public static void main(String[] args) throws Exception
//1,注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取连接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
//3,获取传输器
Statement s = c.createStatement();
//4,执行SQL(SQL语句中的字符串可以用"" 或者 '')
//executeUpdate()用来执行增删改的SQL,返回对数据库的影响行数
//executeQuery()用来执行查询的SQL,返回一个结果集对象ResultSet
int rows = s.executeUpdate("insert into user values(null,\\"tony\\",'1234')");
//5,处理结果集--增删改的SQL没有结果集,省略....
//6,释放资源
s.close();
c.close();
System.out.println("数据入库成功!");
–2,模拟用户登录
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
//写jdbc的代码,模拟用户登录的过程
//本质上,就是拿到用户在浏览器输入的账号和密码,利用jdbc,去查库
public class Test4
public static void main(String[] args) throws Exception
//1,注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取连接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
//3,获取传输器
Statement s = c.createStatement();
//4,执行SQL
// String sql = "SELECT * FROM USER WHERE NAME='jack' AND pwd='123456'";
//动态的拼接SQL语句
System.out.println("请输入账号: ");
String a = new Scanner(System.in).nextLine();
System.out.println("请输入账密码: ");
String b = new Scanner(System.in).nextLine();
//动态数据,如果在中间,按照 "+???+"
String sql = "SELECT * FROM USER WHERE NAME='"+a+"' AND pwd='"+b+"'";
ResultSet r = s.executeQuery(sql);
//5,处理结果集(根据用户名和密码去查,只会查出来一条记录)
if(r.next())//如果查到了数据,才表示库里有这个用户信息
System.out.println("恭喜您,登录成功~~");
else//如果没查到数据,
System.out.println("请重新输入....");
//6,释放资源
r.close();
s.close();
c.close();
//1,问题:当用户输入特殊值: jack'#时,甚至不需要密码也能登录
//2,产生的原因:#在SQL中表示注释的意思,相当于后面的条件被注释掉了...
//SELECT * FROM USER WHERE NAME='jack'#' AND pwd='123456'
//现象叫SQL攻击/SQL注入,本质上就是因为SQL语句中出现了特殊符号#
//导致了,SQL语义发生改变
//3,哪里出现的问题?Statement传输器不安全,低效
//4,解决方案?使用新的传输器PreparedStatement代码现有的Statement
二,SQL攻击
–1,概述
1,问题:当用户输入特殊值: jack’#时,甚至不需要密码也能登录
2,产生的原因:#在SQL中表示注释的意思,相当于后面的条件被注释掉了…
SELECT * FROM USER WHERE NAME=‘jack’ #’ AND pwd=‘123456’
现象叫SQL攻击/SQL注入,本质上就是因为SQL语句中出现了特殊符号#,导致了,SQL语义发生改变
3,哪里出现的问题?Statement传输器不安全,低效
4,解决方案?使用新的传输器PreparedStatement代码现有的Statement
5,PreparedStatement工具,安全,高效.而且SQL写法简洁.
PreparedStatement把特殊符号#当做普通文本字符在使用,没有注释的意思了
–2,改造用户登录
package cn.tedu.jdbc;
import java.sql.*;
import java.util.Scanner;
//写jdbc的代码,模拟用户登录的过程
//本质上,就是拿到用户在浏览器输入的账号和密码,利用jdbc,去查库
//1,问题:当用户输入特殊值: jack'#时,甚至不需要密码也能登录
//2,产生的原因:#在SQL中表示注释的意思,相当于后面的条件被注释掉了...
//SELECT * FROM USER WHERE NAME='jack'#' AND pwd='123456'
//现象叫SQL攻击/SQL注入,本质上就是因为SQL语句中出现了特殊符号#
//导致了,SQL语义发生改变
//3,哪里出现的问题?Statement传输器不安全,低效
//4,解决方案?使用新的传输器PreparedStatement代码现有的Statement
//5,PreparedStatement工具,安全,高效.而且SQL写法简洁.
//PreparedStatement把特殊符号当做普通文本字符在使用,没有注释的意思了
public class Test4
public static void main(String[] args) throws Exception
//1,注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取连接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
// Statement s = c.createStatement();
// String sql = "SELECT * FROM USER WHERE NAME='"+a+"' AND pwd='"+b+"'";
System.out.println("请输入账号: ");
String a = new Scanner(System.in).nextLine();
System.out.println("请输入账密码: ");
String b = new Scanner(System.in).nextLine();
//新的传输器,执行的SQL有新写法--sql骨架
String sql = "SELECT * FROM USER WHERE NAME=? AND pwd=?";
//3,获取 新的传输器--安全,高效
PreparedStatement s = c.prepareStatement(sql);
//给SQL绑定参数
s.setString(1,a);//给第一个问号,设置a的值
s.setString(2,b);//给第二个问号,设置b的值
//4,执行SQL语句
ResultSet r = s.executeQuery();
//5,处理结果集(根据用户名和密码去查,只会查出来一条记录)
if(r.next())//如果查到了数据,才表示库里有这个用户信息
System.out.println("恭喜您,登录成功~~");
else//如果没查到数据,
System.out.println("请重新输入....");
//6,释放资源
r.close();
s.close();
c.close();
–3,练习: 用新的传输器查询
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
//利用新的传输器,查询部门编号为1的数据
public class Test5
public static void main(String[] args) throws Exception
//1,注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取连接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
//3,获取传输器,并执行SQL骨架
String sql="select * from dept where deptno = ?";
PreparedStatement s = c.prepareStatement(sql);
//设置SQL的参数--是指给第几个问号,设置什么值
s.setObject(1,1);
//4,执行SQL
ResultSet r = s.executeQuery();//执行查询的SQL
//5,解析结果集
while(r.next())
Object deptno = r.getObject(1);//获取第1列的值
Object dname = r.getObject(2);//获取第2列的值
Object loc = r.getObject(3);//获取第3列的值
System.out.println(""+deptno+dname+loc);
//6,释放资源
r.close();
s.close();
c.close();
三,优化: 提供jdbc的工具类
–1,创建工具类
package cn.tedu.jdbc;
import java.sql.*;
//充当了jdbc的工具类,抽取一些共性代码
public class JDBCUtils
/**
* 释放资源
* @param r 结果集
* @param s 传输器
* @param c 连接器
*/
static public void close(ResultSet r, PreparedStatement s,Connection c)
if(r != null)//防止了空指针异常
try
r.close();
catch (SQLException throwables)
throwables.printStackTrace();
finally //就是怕close()执行失败导致发生了异常,进行了catch
r = null;//手动置空,等着GC进行垃圾回收
if(s != null) //防止空指针异常
try
s.close();
catch (SQLException throwables)
throwables.printStackTrace();
finally //就是怕close()执行失败导致发生了异常,进行了catch
s = null;//手动置空,等着GC进行垃圾回收
if(c != null) //防止空指针异常
try
c.close();
catch (SQLException throwables)
throwables.printStackTrace();
finally //就是怕close()执行失败导致发生了异常,进行了catch
c = null;//手动置空,等着GC进行垃圾回收
/**
* 获取数据库的连接
* @return 将给调用者返回一个和数据库连接的对象Connection
* @throws Exception
* static:保证资源在内存中,贮存的时间长.只会加载一次节省内存
* public:工具类可以被所有人使用,最大的访问权限方便调用来调用
*/
static public Connection get() throws Exception
//1,注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取连接
String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");
//把获取到的数据库的连接,返回给调用者
return c;
–2,使用工具类(用新的传输器新增)
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
//利用新的传输器结合着工具类,新增一个用户信息
public class Test6
public static void main(String[] args) throws Exception
//1,利用工具类,来获取数据库的连接
Connection c = JDBCUtils.get();
//2,获取传输器,执行SQL
String sql="insert into user values(null,?,?)";
PreparedStatement p = c.prepareStatement(sql);
//给SQL绑定参数
p.setObject(1,"jerry");
p.setObject(2,"123");
//3,执行SQL
p.executeUpdate();//执行增删改的SQL,返回一个影响行数(通常不处理)
//4,释放资源
p.close();
c.close();
–3,改造上面的练习(修改资源释放的代码)
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
//利用新的传输器结合着工具类,新增一个用户信息
public class Test6
public static void main(String[] args)
//扩大变量的作用范围:为了让try catch finally都能用
Connection c = null;
PreparedStatement p = null;
try
//1,利用工具类,来获取数据库的连接
c = JDBCUtils.get();
//2,获取传输器,执行SQL
String sql="insert into user values(null,?,?)";
p = c.prepareStatement(sql);
//给SQL绑定参数
p.setObject(1,"jerry");
p.setObject(2,"123");
//3,执行SQL
p.executeUpdate();//执行增删改的SQL,返回一个影响行数(通常不处理)
catch (Exception e)
System.out.println("数据插入失败!!");
finally //保证一定会被执行的代码
//利用工具类close完成释放资源(新增业务,没有结果集,传入null就可以了)
JDBCUtils.close(null,p,c);
四,作业
1, 把JDBCUtils工具类,理解着敲两遍
2, 把最后一个性练习敲三遍
以上是关于cgb2111-day06的主要内容,如果未能解决你的问题,请参考以下文章