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 知识点进行复习和学习一番,大 ...
随机推荐
- HDU-6170 Two strings
http://acm.hdu.edu.cn/showproblem.php?pid=6170 . 匹配任意字符,x* 匹配任意长度的 x (x 为任意字符,长度可以为 0 ) 正则表达式 #inclu ...
- Python 解leetcode:3. Longest Substring Without Repeating Characters
题目描述:求一个字符串的不含重复字符的最长连续子串的长度: 思路: 使用一个哈希表保存字符出现的位置: 使用left和right分别表示子串的最左和最右字符的下标: 遍历字符串,如果当前字符在哈希表中 ...
- Idea中Smart Tomcat插件启动报NullPointerException问题
如果你跟我一样用的是Idea Community社区版的话,也一定会遇到用Smart Tomcat插件启动报错的问题: 这个问题网上搜了一圈,大家好像也都遇到过了,不过也都没有找到原因和给出解决方案. ...
- 剪花布条 HDU - 2087(kmp,求不重叠匹配个数)
Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入 ...
- 在windows系统下打包linux平台运行的go程序
在windows系统下打包linux平台运行的go程序 1.先在main.go下打包成.exe可执行程序测试代码是否正确 //cd到main.go目录 go build //打包命令 如果打包成功则表 ...
- SpringBoot使用MongoDB异常问题
一 环境介绍 SpringBoot1.5.13.RELEASE(本地) Spring Data MongoDB Java 8 MongoDB(青云) 二 问题描述 使用Studio3T或者Compas ...
- JS 验证字符串是否能转为json格式
var isJSON=function (str) { if (typeof str == 'string') { try { var obj = JSON.parse(str); if (typeo ...
- BMP RGB888转RGB565 +上下翻转+缩放
典型的BMP图像文件由四部分组成: (1) 位图头文件数据结构,它包含BMP图像文件的类型.文件大小和位图起始位置等信息: typedef struct tagBITMAPFILEHEADER { ...
- JavaScript笔记(5)
1.DOM操作 常用的DOM操作 document.getElementById(id); //返回指定id的元素,通用 document.getElementsByTagName(tagName); ...
- SpringCloud多网卡配置(转)
https://blog.csdn.net/lixiang987654321/article/details/88134324 docker部署过程中遇到如下问题: (1)docker容器创建之后,进 ...