JDBC事物机制和代码优化

事务机制管理

Transaction事务机制管理
默认情况下,是执行一条SQL语句就保存一次,那么比如我需要 有三条数据同时成功同时失败,这个时候就需要开启事务机制了
如果开启事务机制,执行中发生问题,会回滚到没有操作之前,相当于什么也没有发生过
1.1 没有事务处理的操作

	Connection conn = null;
	PreparedStatement prst = null;
	Statement stmt = null;
	try {
		conn = DBUtil.getConnection();
		String sql = "insert into test_jdbc (id,name,money) values(?,?,?)";
		prst = conn.prepareStatement(sql);
		prst.setInt(1, 31);
		prst.setString(2, "事务测试1");
		prst.setDouble(3, 11.1);
		prst.addBatch();
		prst.setInt(1, 32);
		// 这里故意写成1,让报错
		prst.setString(1, "事务测试2");
		prst.setDouble(3, 21.1);
		prst.addBatch();
		prst.setInt(1, 33);
		prst.setString(2, "事务测试3");
		prst.setDouble(3, 31.1);
		prst.addBatch();
		prst.executeBatch();
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		DBUtil.close(stmt);
		DBUtil.close(prst);
		DBUtil.close(conn);
	}

插入三条数据,但是第二天添加失败,但是1和3都能添加成功,因为默认是一条SQL就提交一次

有事务处理的操作

	Connection conn = null;
	PreparedStatement prst = null;
	Statement stmt = null;
	try {
		conn = DBUtil.getConnection();
		// 取消自动提交
		conn.setAutoCommit(false);
		String sql = "insert into test_jdbc (id,name,money) values(?,?,?)";
		prst = conn.prepareStatement(sql);
		prst.setInt(1, 31);
		prst.setString(2, "事务测试1");
		prst.setDouble(3, 11.1);
		prst.addBatch();
		prst.setInt(1, 32);
		// 这里故意写成1,让报错
		prst.setString(1, "事务测试2");
		prst.setDouble(3, 21.1);
		prst.addBatch();
		prst.setInt(1, 33);
		prst.setString(2, "事务测试3");
		prst.setDouble(3, 31.1);
		prst.addBatch();
		prst.executeBatch();
		// 提交
		conn.commit();
		conn.setAutoCommit(true);
	} catch (Exception e) {
		e.printStackTrace();
		try {
			// 事务回滚
			conn.rollback();
			conn.setAutoCommit(true);
		} catch (SQLException e1) {
			e1.printStackTrace();
		}
	
	} finally {
		DBUtil.close(stmt);
		DBUtil.close(prst);
		DBUtil.close(conn);
	}

第二条出错,三天数据都不插入

SQL注入

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据 库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。

Properties优化硬代码

实例

如上,我们项目开发完成测试通过后,通常是要打包发布给别人使用的,如果我们把一些配置信息写死到代码中(这种行为叫硬编码,hardcode),别人就无法修改了
比如别人使用的MySQL服务器对应的IP是10.0.0.1,端口号是9300,用户名是mysqluser、密码是123456。
那么我们只能改代码再重新打包发布,如果有多个用户,他们对应的配置信息都不同,那么我们要针对不同的用户打包发布多次。
以上显然是没必要的,因为我们开发的是程序,只要业务需求/逻辑不变,我们就无需多次打包发布。对此我们的解决方案是,尽量避免硬编码, 将数据与程序分离解耦,将配置信息存储到配置文件中,程序运行时读取配置文件,不同用户只需按自己的实际情况修改配置文件即可。
3.1 创建jdbc.properties配置文件
这种方式 账号密码什么的如果发生改动,我只需要更改配置文件就可以
在src目录下创建jdbc.properties文件,内容如下
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/06
username=root
password=root
3.2 更改DBUtil工具类
public static Connection getConnection() throws ClassNotFoundException,
SQLException, IOException {

	Properties properties = new Properties();
	// getClassLoader : 获取类加载器
	// getResourceAsStream : 把资源转换为流
	// 这里 定位到src.所以可以直接写文件名,而流是定位到项目
	properties.load(DBUtil.class.getClassLoader().getResourceAsStream(
			"jdbc.properties"));
	// properties 本质就是一个map,可以通过key获取value
	// username=root 读取到之后,以 = 分隔为数组,把username作为key,root作为value保存
	// 所以我们就可以通过username 来获取root
	String driver = properties.getProperty("driver");
	String username = properties.getProperty("username");
	String password = properties.getProperty("password");
	String url = properties.getProperty("url");

	Class.forName(driver);
	Connection connection = DriverManager.getConnection(url, username,
			password);

	return connection;
}

3.3 测试test
还是以刚才的SQL注入程序为例,只更改了DBUtil和添加了jdbc.properties

在这里插入图片描述
在这里插入图片描述

3.4 优化工具类

在这里插入图片描述

以上工具类中,我们没有必要每次获取链接对象都创建一个Properties对象,每次都去加载资源吧?
所以对加载资源这些再做一个优化
3.4.1创建PropertiesUtil
对Properties解析对象 进行单例创建
public class PropertiesUtil {
private static Properties jdbcProperties = null;

private PropertiesUtil() {
}

public static Properties getProperties() {
	try {
		if (jdbcProperties == null) {
			jdbcProperties = new Properties();
			jdbcProperties.load(PropertiesUtil.class.getClassLoader()
					.getResourceAsStream("jdbc.properties"));
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
	return jdbcProperties;
}

}
3.4.2 更改DBUtil工具类
public static Connection getConnection() throws ClassNotFoundException,
SQLException, IOException {

	Properties properties = PropertiesUtil.getProperties();

	String driver = properties.getProperty("driver");
	String username = properties.getProperty("username");
	String password = properties.getProperty("password");
	String url = properties.getProperty("url");

	Class.forName(driver);
	Connection connection = DriverManager.getConnection(url, username,
			password);

	return connection;
}

测试同上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值