003 Dao模式、sql安全问题、简单的事务处理

=================

Dao模式

一种规范的模式
1 创建一个包,专门存放接口的,如果是用户类,就是用户的接口,如果是商品,就是商品的接口,接口里是增删查改
2 再创建一个包,里面是接口的实现类
3 然后直接调用这个类的方法即可

在它的实现类里,最后面的释放资源的,只是随便写写,后面不会这样释放资源

public class ProductDaoImp implements ProductDao
{
	static Connection conn1 = null;
	static Statement state1 = null;
	static ResultSet resultSet1 = null;

	// 注册驱动,使用静态代码块,只注册一次
	static
	{
		try
		{
			// 创建连接
			conn1 = JDBCUtil.getConnection();

		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	// 找出所有数据
	public void findAll()
	{
		try
		{
			// 创建声明
			state1 = conn1.createStatement();

			String sql = "select * from product";
			resultSet1 = state1.executeQuery(sql);

			// 遍历结果
			while (resultSet1.next())
			{
				System.out.println("pid==" + resultSet1.getInt(1) + "      " + "pname" + resultSet1.getString("pname"));
			}

		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	// 垃圾回收器,相当于析构函数
	public void finalize() throws Throwable
	{
		JDBCUtil.release(resultSet1, state1, conn1);
		super.finalize();
	}

}

在调用的地方直接调用即可

SQL安全

但是这种语句有安全的问题

由下面可以看出,or这种只要一个条件成立,整个表达式即成立的关键词,我们手动加上去

那么就达到了sql注入的效果,那就gg了

我们用帐号密码登录为例,首先应该创建一个user表,下面的类名就不用在意了,因为麻烦所以没有改,安装规范,正确的应该改为UserDao

表里面有帐号密码2个列

在ProductDao里添加这2个接口

在它的实现类里添加下面2个方法

	// 传统登录方式,有sql安全问题
	public void login(String user, String pass)
	{
		try
		{
			state1 = conn1.createStatement();
			String sql = "select * from user where username='" + user + "' and password='" + pass + " ' ";
			resultSet1 = state1.executeQuery(sql);
			if (resultSet1.next())
			{
				System.out.println("登录成功");
			} else
			{
				System.out.println("登录失败");
			}

		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	//解决sql安全问题
	public void login2(String user, String pass)
	{
		try
		{
			// 把需要的参数都用?来替换
			String sql = "select * from user where username=? and password=?";

			// 预处理声明,先处理sql语句,再去执行
			// 把?都看成一个字符串 像or这种关键字也看作成字符串,那么sql安全问题就避免了
			PreparedStatement state1 = conn1.prepareStatement(sql);

			// 索引从1开始,如果是字符串数据,就setString,如果是整数型数据,比如id,就用setInt
			state1.setString(1, user);
			state1.setString(2, pass);

			resultSet1 = state1.executeQuery();

			// 遍历结果
			if (resultSet1.next())
			{
				System.out.println("登录成功");
			} else
			{
				System.out.println("登录失败");
			}

		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

在调用的地方

简单的事务处理

事务在前面001 mysql的时候有讲,jdbc是提交事务的,如果要手动提交,就必须先关闭自动提交事务

		public static void main(String [] xxx)
		{
			testTransaction();
		}

		//事务的简单使用
		public static void testTransaction()
		{
			Connection conn1 = null;
			PreparedStatement state1 = null;
			ResultSet resultSet1 = null;
			
			try
			{
				conn1 = JDBCUtil.getConnection();
				
				//关闭事务自动提交
				conn1.setAutoCommit(false);
				
				String sql="update bank set money=money-? where id=?";
					
				state1 = conn1.prepareStatement(sql);
				
				//加100块钱
				state1.setInt(1,100);
				state1.setInt(2,1);
				state1.executeUpdate();
				
				//这里异常了,那么就不会执行下面加钱的语句,我们就少了100块钱了
				int a=10/0;
				
				//加200块钱
				state1.setInt(1,-200);
				state1.setInt(2,1);
				state1.executeUpdate();
				
				//但是如果我们关闭了自动提交,到这里才提交,那么不管怎么异常,数据都不会更新到数据库
				//必须要执行到这里数据才能更新到数据库
				conn1.commit();

			} catch (Exception e)
			{
				try
				{
					//如果异常了,那么就回滚事务
					conn1.rollback();
				} catch (SQLException e1)
				{
					e1.printStackTrace();
				}
				e.printStackTrace();
			}finally {
				JDBCUtil.release(resultSet1, state1, conn1);
			}
		}

猜你喜欢

转载自blog.csdn.net/yzj17025693/article/details/82822419
003