mysql之jdbc连接数据库和sql注入的问题


一,概述


可能是自己的记忆力太差了,经常忘记一些很重要的知识点,记得个大概,等要用的时候就去找,结果还找不到。干脆,记博客里,怎么都找的到。这篇博客主要就是关于Jdbc(java database connectivity)和MySql的,记录如何连接数据库及插入数据等等。

二,工具及准备工作


MyEclipse10,mysql驱动jar包(我用的是这个版本mysql-connector-java-5.0.8-bin.jar,大家可以选择用其他版本)

三,导入驱动,连接数据库


在MyEclipse中新建一个Web Project命名为bighuan_login,将准备好的驱动jar包拷贝到bighuan_login/WebRoot/WEB_INF/lib目录下,将驱动jar包拷入到lib目录后就可以了。

接下来就去封装一下连接数据库的代码,这样就不用每次操作数据库都写一大堆代码了。JdbcUtils.java代码如下:
package com.bighuan.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;

import org.junit.Test;

/**
 * Jdbc工具类
 * 
 * @author bighuan
 * 
 */
public class JdbcUtils {

	private static String driverClass = null;
	private static String url = null;
	private static String username = null;
	private static String password = null;

	/**
	 * 获得连接
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		// 注意:导sql包下的Connection
		try {
			loadDriver();

			ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
			url = bundle.getString("url");
			username = bundle.getString("username");
			password = bundle.getString("password");

			return DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 注册驱动
	 */
	private static void loadDriver() {

		try {
			// ResourceBundle专门用于读取properties文件,注意不要后缀名
			ResourceBundle bundle = ResourceBundle.getBundle("jdbc");

			driverClass = bundle.getString("driverClass");
			// 注册驱动
			Class.forName(driverClass);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 释放资源
	 * 
	 * @param rs
	 * @param stmt
	 * @param conn
	 */
	public static void release(ResultSet rs, Statement stmt, Connection conn) {

		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rs = null;
		}

		if (stmt != null) {
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			stmt = null;
		}

		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			conn = null;
		}

	}

	@Test
	public void test() {
		Connection conn = getConnection();

		Statement stmt = null;
		ResultSet rs = null;
		try {
			stmt = conn.createStatement();

			rs = stmt.executeQuery("select * from user");

			while (rs.next()) {

				String name = rs.getString("name");
				String psd = rs.getString("psd");
				System.out.println("name:" + name + ",psd:" + psd);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			release(rs, stmt, conn);
		}
	}
}
为了加强程序的扩展性,一些必要的配置信息写在jdbc.properties文件中,以key-value形式,这个文件建在src目录下,代码如下:
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bighuan
username=root
password=abc

接下来就对工具类和这个配置文件进行解释。driverClass对应的值主要用来注册驱动,url username password主要就是在建立连接的时候需要用到。url中的bighuan是数据库名,如果需要修改,直接在配置文件中修改即可,这也是配置文件的好处之一吧。url中的3306是你mysql数据库的端口号,默认就是3306,可自行查看。localhost就代表本地机器咯。前面那一串jdbc:mysql:是固定的。username代表当前那个用户,password代表对应的密码。安装mysql时最后几个步骤包含设置密码这个步骤。说完这些,那配置文件中我们需要的配置信息我们要怎样拿出来呢?将目光转移到工具类中,在注册驱动的loadDriver()方法中,


// ResourceBundle专门用于读取properties文件,注意不要后缀名
			ResourceBundle bundle = ResourceBundle.getBundle("jdbc");

			driverClass = bundle.getString("driverClass");
			// 注册驱动
			Class.forName(driverClass);

我们只要通过ResourceBundle对象就可以拿到配置文件中的信息,注意,ResourceBundle.getBundle("jdbc")拿ResourceBundle对象时不要文件的后缀名。然后通过getXXX方法就可以取到值了。代码中都有注释,不做过多解释,对释放资源的方法做一个强调。我们连接数据库都是先注册驱动,建立连接,获得结果集(查询对象时),所以我们在释放资源时最好按相反顺序来释放资源,这也是mysql官网所推荐的方式哦。工具类中有一个test()方法,可以直接测试是否连接数据库成功,当然了,你要先向数据库中插入数据。

四,sql注入的问题

在传递sql语句的参数的时候,传递一些sql语句的关键字进来,更改了原有sql语句的语义,达成一些非法的目的,从而发生了sql注入的问题。如:

select * from user where name='zs' or '1'='1'and password='123';

上面这行代码or后面的约束相当于没用了,只要知道用户名就可以非法登录某个系统了。如何解决呢?

只要使用PreparedStatement代替Statement对象就可以了。

Connection conn = JdbcUtils.getConnection();
//			Statement stmt = conn.createStatement();
//			ResultSet rs = stmt.executeQuery("select * from user where name='"+username+"' and psd='"+password+"'");
			
			PreparedStatement pstmt = conn.prepareStatement("select * from user where name = ? and psd = ? ");
			
			pstmt.setString(1, username);
			pstmt.setString(2,password);
			
			ResultSet rs = pstmt.executeQuery();
			//判断数据库中是否有这个用户
			if(rs.next()){
				//存在这个用户
				System.out.println("登录成功...");
			}else{
				System.out.println("登录失败...");
			}

PreparedStatement可以预编译sql语句,当你传参数进来的时候,其实sql语句已经确定了关键字,从而可以防止sql注入的问题发生了。

五,总结


好了,就这样吧!如果那里有问题,欢迎大家留言指出,我也会及时更改的!拜拜!
  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

bighuan

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值