目录

JDBC的简单使用

向JDBC注入攻击

防止注入攻击

自建JDBC工具类

自建工具类优化--使用配置文件

使用数据库连接池优化工具类

JDBC的简单使用

 package Test;

 import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; /*JDBCsun公司提供的一套标准数据库操作规范
* JDBC使用步骤
* 1 注册驱动--告诉JVM使用的是哪一个数据库
* 2 获得连接--使用JDBC中的类完成对MySQL数据库的连接
* 3 获得语句执行平台--通过连接对象获取SQL语句1的执行者对象
* 4 执行sql语句--使用执行者对象向数据库执行SQL语句,并获取执行后的结果
* 5 处理结果
* 6 释放资源
* ----------在使用之前一定要先导入jar包
*/ public class Main{
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1 注册驱动,但查看源码发现这样会注册两次
//DriverManager.registerDriver(new Driver());
//使用反射技术注册,在这里类名可能找不到因此抛出类名查不到的异常
Class.forName("com.mysql.jdbc.Driver"); //2连接数据库 url:数据库 jdbc:jdbc:mysql://连接主机IP:端口号//数据库名
String url ="jdbc:mysql://localhost:3306/mybase";
String username="root";//用户名
String password="123";//密码
//连接,可能连接不到抛出SQL异常
Connection con =DriverManager.getConnection(url, username,password); //3 获得语句执行平台,通过数据库连接对象获得SQL语句的执行者对象,注意导包为sql的包
Statement stat=con.createStatement();
//查询语句
String sql ="Select * from titles"; //4 调用执行者对象方法,执行SQL语句获取结果集
ResultSet rs=stat.executeQuery(sql);
//5 处理结果集
while(rs.next()){
System.out.println(rs.getString("emp_no")+" "+rs.getString("title"));
} //6 释放资源
rs.close();
stat.close();
con.close();
}
}

向JDBC注入攻击

创建数据表

 CREATE TABLE users(
username VARCHAR(20),
PASSWORD VARCHAR(10)
); INSERT INTO users VALUES('a',''),('b','');

待注入攻击的代码:

 package Test;

 import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner; /*MySQL注入攻击
* 用户登录案例
*/ public class Main{
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver"); //2连接数据库 url:数据库 jdbc:jdbc:mysql://连接主机IP:端口号//数据库名
String url ="jdbc:mysql://localhost:3306/mybase";
String username="root";//用户名
String password="123";//密码
Connection con =DriverManager.getConnection(url, username,password);
Statement stat=con.createStatement();
//查询语句
Scanner sc=new Scanner(System.in);
String user=sc.next();
String pass=sc.next();
String sql ="Select * from users where username= '"+user+"' and password= '"+pass+"'"; //4 调用执行者对象方法,执行SQL语句获取结果集
ResultSet rs=stat.executeQuery(sql);
System.out.println(sql);
//5 处理结果集
while(rs.next()){
System.out.println(rs.getString("username")+" "+rs.getString("password"));
} //6 释放资源
rs.close();
stat.close();
con.close();
}
}

 代码运行结果:

攻击的原理:

利用SQL语句:Select * from users where username= 'a' and password= '1'or'1=1',这样由于最后一个是或运算那么就会显示出来所有的数据,因此在输入时只要想办法凑成这样的形式就可以了。

输入:aa 12'or'1=1  这样便可以完成攻击,即使输入的用户名不对也可以正常登陆。

防止注入攻击

 package Test;

 import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner; /*MySQL防止注入攻击--采用statement的子类preparedstatement
* 还可以用占位符实现增删改查等操作
*/ public class Main{
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver"); //2连接数据库 url:数据库 jdbc:jdbc:mysql://连接主机IP:端口号//数据库名
String url ="jdbc:mysql://localhost:3306/mybase";
String username="root";//用户名
String password="123";//密码
Connection con =DriverManager.getConnection(url, username,password); //查询语句
Scanner sc=new Scanner(System.in);
String user=sc.next();
String pass=sc.next();
//用?占位符代替参数
String sql ="Select * from users where username=? and password= ?";
PreparedStatement pds=con.prepareStatement(sql);
pds.setObject(1, user);
pds.setObject(2, pass);
//4 调用执行者对象方法,执行SQL语句获取结果集
ResultSet rs=pds.executeQuery();
System.out.println(sql);
//5 处理结果集
while(rs.next()){
System.out.println(rs.getString("username")+" "+rs.getString("password"));
} //6 释放资源
rs.close();
pds.close();
con.close();
}
}

自建JDBC工具类

JDBCUtils.class文件

 package Test;

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; public class JDBCUtils {
private JDBCUtils(){}
private static Connection con; static{
try {
Class.forName("com.mysql.jdbc.Driver");
//2连接数据库 url:数据库 jdbc:jdbc:mysql://连接主机IP:端口号//数据库名
String url ="jdbc:mysql://localhost:3306/mybase";
String username="root";//用户名
String password="123";//密码
con =DriverManager.getConnection(url, username,password);
} catch (Exception e) {
throw new RuntimeException(e+"数据库连接失败!");
}
}
//定义静态方法,返回数据库的连接对象
public static Connection getConnection(){
return con;
} //释放资源
public static void close(Connection con,Statement stat){
if(stat!=null){
try {
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//重载,关闭结果集
public static void close(Connection con,Statement stat,ResultSet rs){
//注意释放的顺序
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if(stat!=null){
try {
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

测试代码:

 package Test;

 import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import Test.JDBCUtils; public class JDBCTset {
public static void main(String[] args) throws SQLException {
Connection con =JDBCUtils.getConnection();
PreparedStatement pst=con.prepareStatement("SELECT * FROM titles");
ResultSet rs =pst.executeQuery();
while(rs.next()){
System.out.println(rs.getString("title"));
}
//释放资源
JDBCUtils.close(con, pst);
}
}

自建工具类优化--使用配置文件

优化代码

 package Test;

 import java.io.IOException;
import java.io.InputStream; /*在前面的代码中由于数据库用户名,密码直接在静态代码块中,相当于写死了代码,不容易修改
* 因此采用properties配置文件,方便后期维护。配置文件建议放在src下,方便自动拷贝bin目录下
*
*/ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties; public class JDBCUtils {
private JDBCUtils(){}
private static Connection con;
private static String driverClass;
private static String url;
private static String username;
private static String password;
//放到静态代码块中保证读取配置文件,获取连接只执行一次
static{
try{
readConfig();
//反射
Class.forName(driverClass);
con=DriverManager.getConnection(url,username,password);
}catch(Exception e){
throw new RuntimeException("数据库连接失败!");
} } private static void readConfig() throws IOException{
//通过字节流,使用类加载器读取配置文件的内容
InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("database.properties");
Properties pro = new Properties();
pro.load(in);
driverClass=pro.getProperty("driverClass");
url = pro.getProperty("url");
username=pro.getProperty("username");
password=pro.getProperty("password");
} //定义静态方法,返回数据库的连接对象
public static Connection getConnection(){
return con;
} //释放资源
public static void close(Connection con,Statement stat){
if(stat!=null){
try {
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//重载,关闭结果集
public static void close(Connection con,Statement stat,ResultSet rs){
//注意释放的顺序
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if(stat!=null){
try {
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

测试代码

 package Test;

 import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import Test.JDBCUtils; public class JDBCTset {
public static void main(String[] args) throws SQLException {
Connection con =JDBCUtils.getConnection();
//当能输出数据库连接时边说用工具类正常了
System.out.println(con);
//由于是简单的测试,因此不用释放资源
//JDBCUtils.close(con, pst);
}
}

使用数据库连接池优化工具类

优化代码:

 package Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties; import javax.sql.DataSource; /*
* JDBC连接池工具类,使用连接池专门负责数据库的连接
* JDBC连接池简化了sql语句中的增删改查操作,方便代码编写
*/
import org.apache.commons.dbcp.BasicDataSource; public class JDBCUtils {
private JDBCUtils(){}
private static String driverClass;
private static String url;
private static String username;
private static String password;
private static BasicDataSource datasource =new BasicDataSource();
//放到静态代码块中保证读取配置文件,获取连接只执行一次
static{
try {
readConfig();
//数据库连接配置
datasource.setDriverClassName(driverClass);
datasource.setUrl(url);
datasource.setUsername(username);
datasource.setPassword(password);
//对象连接池中的数量配置,这些配置可以不用配置的
datasource.setInitialSize(10);//初始化的连接数
datasource.setMaxActive(8);//最大连接数
datasource.setMaxIdle(5);//最大空闲数
datasource.setMinIdle(1);//最小空闲数
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} private static void readConfig() throws IOException{
//通过字节流,使用类加载器读取配置文件的内容
InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("database.properties");
Properties pro = new Properties();
pro.load(in);
driverClass=pro.getProperty("driverClass");
url = pro.getProperty("url");
username=pro.getProperty("username");
password=pro.getProperty("password");
} //定义静态方法,返回数据库的连接对象
public static DataSource getDataSource(){
return datasource;
}
}

测试代码:

 package Test;

 import java.sql.SQLException;
import java.util.List; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler; public class JDBCTset {
private static QueryRunner qr=new QueryRunner(JDBCUtils.getDataSource()); public static void main(String[] args) throws SQLException {
String sql="select * from titles";
//ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。这是dbutils所特有的
List<Object[]> list =qr.query(sql, new ArrayListHandler());
for(Object[] objs:list){
for(Object obj:objs)
System.out.print(obj+"\t\t");
System.out.println();
}
} }

0

Java数据库小项目00---基础知识的更多相关文章

  1. Java数据库小项目02--管家婆项目

    目录 项目要求 开发环境搭建 工具类JDBCUtils 创建管家婆数据表 项目分层 MainApp层 MainView层 ZhangWuController层 ZhangWuService层 Zhan ...

  2. Java数据库小项目01--实现用户登录注册

    先实现数据库和数据表,检测正常后再做其他的 CREATE TABLE users( username ) NOT NULL, PASSWORD ) NOT NULL); INSERT INTO use ...

  3. 总结了零基础学习Java编程语言的几个基础知识要点

    很多Java编程初学者在刚接触Java语言程序的时候,不知道该学习掌握哪些必要的基础知识.本文总结了零基础学习Java编程语言的几个基础知识要点. 1先了解什么是Java的四个方面   初学者先弄清这 ...

  4. java Reflection(反射)基础知识讲解

    原文链接:小ben马的java Reflection(反射)基础知识讲解 1.获取Class对象的方式 1.1)使用 "Class#forName" public static C ...

  5. Java中实现异常处理的基础知识

    Java中实现异常处理的基础知识 异常 (Exception):发生于程序执行期间,表明出现了一个非法的运行状况.许多JDK中的方法在检测到非法情况时,都会抛出一个异常对象. 例如:数组越界和被0除. ...

  6. JAVA面试题集之基础知识

                           JAVA面试题集之基础知识 基础知识:  1.C 或Java中的异常处理机制的简单原理和应用. 当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就 ...

  7. 【Java面试】1、基础知识篇

    [Java面试]基础知识篇 Java基础知识总结,主要包括数据类型,string类,集合,线程,时间,正则,流,jdk5--8各个版本的新特性,等等.不足的地方,欢迎大家补充. 源码分享:https: ...

  8. Java IO(1)基础知识——字节与字符

    正所谓怕什么来什么,这是知名的“墨菲定律”.Java基础涵盖各个方面,敢说Java基础扎实的人不是刚毕业的学生,就是工作N年的程序员.工作N年的程序员甚至也不敢人人都说Java基础扎实,甚至精通,往往 ...

  9. Java 面试知识点解析(一)——基础知识篇

    前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...

随机推荐

  1. SpringBoot以WAR包部署遇到的坑---集合贴

    ⒈忽略tomcat的context-path 方式一: 停止tomcat服务,删除tomcat安装目录的webapps目录下的ROOT目录,将打成的WAR包重命名为ROOT.war,重启tomcat服 ...

  2. 剑指offer21:第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。(注意:这两个序列的长度是相等的)

    1 题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是 ...

  3. php中的访问类型(public,private,protected)

    类型的访问修饰符允许开发人员对类成员的访问进行限制,这是PHP5的新特性.但却是oop语言的一个好的特性.而且大多数的oop语言都已支持此特性.PHP5支持三种访问修饰符: public(公有的,默认 ...

  4. Viola–Jones object detection framework--Rapid Object Detection using a Boosted Cascade of Simple Features中文翻译 及 matlab实现(见文末链接)

    ACCEPTED CONFERENCE ON COMPUTER VISION AND PATTERN RECOGNITION 2001 Rapid Object Detection using a B ...

  5. c++11 原生字符串字面值

    c++11 原生字符串字面值 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #in ...

  6. Pycharm+Selenium webdriverPython自动化测试

    这是关于软件测试的一个作业! 1.Pycharm下载,这里可以自己去官网下载即可:https://www.jetbrains.com/pycharm/download/#section=windows ...

  7. oracle中查询表中的触发器,关闭启用操作

    1.查询指定表中有哪些触发器 select * from all_triggers WHERE table_name='表名' 2.禁用指定表中所有的触发器 alter table table_nam ...

  8. Zookeeper 入门详解

    zookeeper zookeeper是什么 Apache ZooKeeper是Apache软件基金会的一个软件项目,他为大型分布式计算提供开源的分布式配置服务.同步服务和命名注册.ZooKeeper ...

  9. react hooks学习

    接触React项目快两个月了,还在研究摸索各种知识点的过程中,充实且幸福. 在项目中学习新知识,还是很有效率的,一边写项目,一边实验新的知识点,比如react hooks!嘻嘻嘻~~~ 写了好一段时间 ...

  10. mycat sql timeout 问题解决

    发现程序中有个批量update语句需要update 16000多条数据导致超时 2019-11-06 10:35:28.312 pool-9-thread-24 ERROR com.hp.nova.c ...