标签:布尔值 except vax getc manage dex try 官方 避免
目录
JDBC:Java数据库连接。官方定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
? 导入mysql-connector-java-5.1.7-bin.jar包到该项目的lib目录下,并Add As Library
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection ("jdbc:mysql://localhost:3306/jdbctest","root","123456");
String sql="select * from user";
Statement stmt = conn.createStatement();
ResultSet resultSet = stmt.executeQuery(sql);
while(resultSet.next()){
int uid = resultSet.getInt("uid");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String name = resultSet.getString("name");
System.out.println(uid+" "+username+" "+password+" "+name);
}
resultSet.close();
stmt.close();
conn.close();
代码实现:
JDBCDemo1.java
import org.junit.Test;
import java.sql.*;
public class JDBCDemo1 {
@Test
public void demo1() {
try {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获得连接
Connection conn =
DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123456");
//定义SQL并创建用于向数据库发送SQL的Statement对象
String sql = "select * from user";
Statement stmt = conn.createStatement();
//执行SQL
ResultSet resultSet = stmt.executeQuery(sql);
//遍历查询到的结果
while (resultSet.next()) {
int uid = resultSet.getInt("uid");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String name = resultSet.getString("name");
System.out.println(uid + " " + username + " " + password + " " + name);
}
//释放资源
resultSet.close();
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
作用:
①注册驱动
? 在com.mysql.jdbc.Driver类中存在静态代码块
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
编写代码: Class.forName("com.mysql.jdbc.Driver");
注册加载驱动
②获取数据库连接
方法:static Connection getConnection(String url, String user, String password)
作用:
①创建执行SQL语句的对象
②进行事务管理
作用:
①执行SQL语句
②执行批处理操作
作用:
select语句查询结果的封装,next()方法指向下一行,getObject()获取数据。
为了简化JDBC的开发,对一些重复代码进行提取,并且添加配置文件("xxx.properties"),便于之后的维护更新
代码实现:
jdbc.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql:///jdbctest?characterEncoding=utf-8
username=root
password=123456
JDBCUtils.java
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
private static final String driverClass;
private static final String url;
private static final String username;
private static final String passsword;
//配置文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
static {
//创建Properties集合类
Properties properties = new Properties();
//使用字节码文件获取当前类的类加载器以获取资源输入流
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
try {
//加载配置文件
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//获取配置文件中的数据
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
username = properties.getProperty("username");
passsword = properties.getProperty("password");
}
//注册加载驱动
public static void loadDriver() throws ClassNotFoundException {
Class.forName(driverClass);
}
//获取数据库连接
public static Connection getConnection() throws Exception {
loadDriver();
Connection conn = DriverManager.getConnection(url, username, passsword);
return conn;
}
//断开数据库连接,资源释放
public static void release(Connection conn, Statement stmt) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
}
//断开数据库连接,资源释放
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
}
}
JDBCDemo2.java
import Utils.JDBCUtils;
import org.junit.Test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCDemo2 {
@Test
/**
* 测试SQL注入漏洞的方法
*/
public void demo1() {
boolean flag = JDBCDemo2.login("aaa' or '1=1", "dsacqwed1");
if (flag == true) {
System.out.println("登录成功!");
} else {
System.out.println("登录失败!");
}
}
public static boolean login(String username, String password) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
boolean flag = false;
try {
conn = JDBCUtils.getConnection();
// 创建执行SQL语句的对象:
stmt = conn.createStatement();
// 编写SQL:
String sql = "select * from user where username = '" + username + "' and password = '" + password + "'";
// 执行SQL:
rs = stmt.executeQuery(sql);
// 判断结果集中是否有数据。
if (rs.next()) {
flag = true;
} else {
flag = false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(conn, stmt, rs);
}
return flag;
}
}
我们要执行的SQL语句为select * from user where username = ‘" + username + "‘ and password = ‘" + password + "‘
当我们输入用户名username为aaa‘ or ‘1=1
时,无论密码输入什么都能登录成功
产生原因:当我们输入用户名与SQL语句进行字符串拼接,输入的内容也作为了SQL语句的一部分,生成的SQL语句为select * from user where username = ‘ aaa‘ or ‘ 1=1 ‘ and password = ‘dsacqwed1‘
存在关键字or
select * from user where username = ' aaa' 执行
' 1=1 ' and password = 'dsacqwed1' 假
方法:使用PreparedStatement接口
Statement对象每执行一条SQL语句都会先将SQL语句发送给数据库,数据库先编译SQL,再执行。效率低,且可能造成数据库缓存区的溢出。
PreparedStatement会先将SQL语句发送给数据库预编译,PreparedStatement会引用着预编译后的结果,可以多次传入不同的参数来给PreparedStatement对象并执行。
解决注入漏洞问题:
编写SQL语句时,参数使用?占位 "select * from user where username = ? and password = ?";
再利用PreparedStatement对象的setXxx(占位符位置(从1开始),实际值)方法设置参数
/**
* 避免SQL注入漏洞的方法
*/
public static boolean login(String username,String password){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
boolean flag = false;
try{
conn = JDBCUtils.getConnection();
String sql = "select * from user where username = ? and password = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
rs = pstmt.executeQuery();
if(rs.next()){
flag = true;
}else{
flag = false;
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(conn, pstmt, rs);
}
return flag;
}
JDBCDemo3.java
import Utils.JDBCUtils;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCDemo3 {
@Test
public void select() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
String sql = "select * from user where username=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "aaa");
rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("uid") + " " + rs.getString("username") + " " + rs.getString("password") + " " + rs.getString("name"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(conn, pstmt, rs);
}
}
@Test
public void delete() {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
String sql = "delete from user where username=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "xxx");
int i = pstmt.executeUpdate();
if (i > 0) {
System.out.println("删除成功!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(conn, pstmt);
}
}
@Test
public void update() {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
String sql = "update user set username=? where name=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "aaa");
pstmt.setString(2, "Marry");
int i = pstmt.executeUpdate();
if (i > 0) {
System.out.println("更改成功!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(conn, pstmt);
}
}
@Test
public void insert() {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
String sql = "insert into user values(null,?,?,?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "xxx");
pstmt.setString(2, "666");
pstmt.setString(3, "小八");
int i = pstmt.executeUpdate();
if (i > 0) {
System.out.println("添加成功!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(conn, pstmt);
}
}
}
数据库连接池:数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;相当于一个容器,存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
实现步骤:
导入相应jar包
c3p0-0.9.5.2.jar
mchange-commons-java-0.2.12.jar
PS:不要忘记导入mysql-connector-java-5.1.7-bin 驱动包
定义配置文件
? 文件名只能为: c3p0.properties或者 c3p0-config.xml
3.创建数据库连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
?
c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///jdbctest?characterEncoding=utf-8</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
</c3p0-config>
定义c3p0工具类 JDBCUtils2.java
package Utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtils2 {
//创建数据库连接池对象
private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
//获取连接对象
public static Connection getConnection() throws SQLException {
Connection conn = dataSource.getConnection();
return conn;
}
public static void release(Connection conn, Statement stmt) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
}
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
}
}
JDBCDemo4.java
package JDBCDemo;
import Utils.JDBCUtils2;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCDemo7 {
@Test
public void demo1() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = JDBCUtils2.getConnection();
String sql = "select * from user where uid=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 1);
rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt("uid") + " " + rs.getString("username"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils2.release(conn, pstmt, rs);
}
}
}
实现步骤
导入jar包 druid-1.0.9.jar
定义配置文件xxx.properties
加载配置文件
获取数据库连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
获取连接
? Connection conn=dataSource.getConnection();
定义Druid工具类 JDBCUtils3.java (提供静态代码块加载配置文件,初始化连接池对象)
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class JDBCUtils3 {
private static DataSource dataSource;
static {
Properties properties = new Properties();
InputStream is = JDBCUtils3.class.getClassLoader().getResourceAsStream("druid.properties");
try {
properties.load(is);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
Connection conn = dataSource.getConnection();
return conn;
}
public static void release(Connection conn, PreparedStatement pstmt) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
pstmt = null;
}
}
public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
pstmt = null;
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
}
}
配置文件druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncoding=utf-8
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
标签:布尔值 except vax getc manage dex try 官方 避免
原文地址:https://www.cnblogs.com/jascen/p/11354642.html