Java数据库小项目00---基础知识
目录
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---基础知识的更多相关文章
- Java数据库小项目02--管家婆项目
目录 项目要求 开发环境搭建 工具类JDBCUtils 创建管家婆数据表 项目分层 MainApp层 MainView层 ZhangWuController层 ZhangWuService层 Zhan ...
- Java数据库小项目01--实现用户登录注册
先实现数据库和数据表,检测正常后再做其他的 CREATE TABLE users( username ) NOT NULL, PASSWORD ) NOT NULL); INSERT INTO use ...
- 总结了零基础学习Java编程语言的几个基础知识要点
很多Java编程初学者在刚接触Java语言程序的时候,不知道该学习掌握哪些必要的基础知识.本文总结了零基础学习Java编程语言的几个基础知识要点. 1先了解什么是Java的四个方面 初学者先弄清这 ...
- java Reflection(反射)基础知识讲解
原文链接:小ben马的java Reflection(反射)基础知识讲解 1.获取Class对象的方式 1.1)使用 "Class#forName" public static C ...
- Java中实现异常处理的基础知识
Java中实现异常处理的基础知识 异常 (Exception):发生于程序执行期间,表明出现了一个非法的运行状况.许多JDK中的方法在检测到非法情况时,都会抛出一个异常对象. 例如:数组越界和被0除. ...
- JAVA面试题集之基础知识
JAVA面试题集之基础知识 基础知识: 1.C 或Java中的异常处理机制的简单原理和应用. 当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就 ...
- 【Java面试】1、基础知识篇
[Java面试]基础知识篇 Java基础知识总结,主要包括数据类型,string类,集合,线程,时间,正则,流,jdk5--8各个版本的新特性,等等.不足的地方,欢迎大家补充. 源码分享:https: ...
- Java IO(1)基础知识——字节与字符
正所谓怕什么来什么,这是知名的“墨菲定律”.Java基础涵盖各个方面,敢说Java基础扎实的人不是刚毕业的学生,就是工作N年的程序员.工作N年的程序员甚至也不敢人人都说Java基础扎实,甚至精通,往往 ...
- Java 面试知识点解析(一)——基础知识篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
随机推荐
- SpringBoot以WAR包部署遇到的坑---集合贴
⒈忽略tomcat的context-path 方式一: 停止tomcat服务,删除tomcat安装目录的webapps目录下的ROOT目录,将打成的WAR包重命名为ROOT.war,重启tomcat服 ...
- 剑指offer21:第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。(注意:这两个序列的长度是相等的)
1 题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是 ...
- php中的访问类型(public,private,protected)
类型的访问修饰符允许开发人员对类成员的访问进行限制,这是PHP5的新特性.但却是oop语言的一个好的特性.而且大多数的oop语言都已支持此特性.PHP5支持三种访问修饰符: public(公有的,默认 ...
- 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 ...
- c++11 原生字符串字面值
c++11 原生字符串字面值 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #in ...
- Pycharm+Selenium webdriverPython自动化测试
这是关于软件测试的一个作业! 1.Pycharm下载,这里可以自己去官网下载即可:https://www.jetbrains.com/pycharm/download/#section=windows ...
- oracle中查询表中的触发器,关闭启用操作
1.查询指定表中有哪些触发器 select * from all_triggers WHERE table_name='表名' 2.禁用指定表中所有的触发器 alter table table_nam ...
- Zookeeper 入门详解
zookeeper zookeeper是什么 Apache ZooKeeper是Apache软件基金会的一个软件项目,他为大型分布式计算提供开源的分布式配置服务.同步服务和命名注册.ZooKeeper ...
- react hooks学习
接触React项目快两个月了,还在研究摸索各种知识点的过程中,充实且幸福. 在项目中学习新知识,还是很有效率的,一边写项目,一边实验新的知识点,比如react hooks!嘻嘻嘻~~~ 写了好一段时间 ...
- mycat sql timeout 问题解决
发现程序中有个批量update语句需要update 16000多条数据导致超时 2019-11-06 10:35:28.312 pool-9-thread-24 ERROR com.hp.nova.c ...