jdbc进阶-高级工具

我的网站:欢迎欢迎

JDBC进阶

PreparedStatement

预处理语句,这个接口继承了Statement接口

1.解决字符串拼接的问题

2.解决sql注入问题

3.让效率更高一点

实现步骤

前面连接数据库都是一样的步骤

在拿到语句对象的时候就使用SQL

将Statement st = conn.createStatement();

替换成PreparedStatement st = conn.prepareStatement(sql);//预编译sql
在执行的时候不需要传sql;

String sql = "select * from login where username=? and password=?";
			PreparedStatement pStatement = conn.prepareStatement(sql);
			pStatement.setString(1, username);
			pStatement.setString(2, pwd);
			ResultSet set = pStatement.executeQuery();

Demo

使用两种方式来判断登录

package com.ifueen.homework.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.ifueen.classtest.util.JDBCUtil;
import com.ifueen.classtest.util.JDBCUtilDataSource;
import com.ifueen.homework.dao.LoginDao;
import com.sun.javafx.binding.Logging;

public class LoginDaoImpl implements LoginDao{

	/**
	 * 第一种判断登录的方式
	 */
	@Override
	public void login(String username, String pwd) {
		// TODO Auto-generated method stub
		Connection conn = JDBCUtilDataSource.getinstance().getconn();
		try {
			Statement statement = conn.createStatement();
			String sql = "select * from login";
			ResultSet rs = statement.executeQuery(sql);
			if (rs.next()) {
				if (!rs.getString("username").equals(username)) {
					System.out.println("你有这个账户吗?嗯?弟弟");
				}else{
					if (rs.getString("username").equals(username) && rs.getString("password").equals(pwd)) {
						System.out.println("登录成功");
					}else{
						System.out.println("密码都记不住吗弟弟?");
					}
				}
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

    /**
	 * 第二种
	 * 使用prepareStatement来进行加载,避免了sql注入问题
	 */
	@Override
	public void login2(String username, String pwd) {
		// TODO Auto-generated method stub
		Connection conn = JDBCUtilDataSource.getinstance().getconn();
		try {
			String sql = "select * from login where username=? and password=?";
			PreparedStatement pStatement = conn.prepareStatement(sql);
			pStatement.setString(1, username);
			pStatement.setString(2, pwd);
			ResultSet set = pStatement.executeQuery();
			if (set.next()) {
				if (set.getString("username").equals(username) && set.getString("password").equals(pwd)) 
					System.out.println("登录成功");
			}else{
				System.out.println("密码都记不住吗弟弟?");
			}
			
			JDBCUtil.getinstance().getclose(pStatement, conn);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

?事务

什么是事务

事务: 程序里面的一组操作,要不都成功,要不都失败;

事务示例:
银行转帐功能: bank / money
小冯和小红:
小冯 : 10000块钱 小红 : 0块钱

转账:小冯要给小红转1000块钱
分析:转钱需要提供两条sql,但是程序员也会出错,比较代码写错了.

如果在扣款时出错,那么小冯的余额扣除了但是小红却没有收到,所以不合理

这个时候就需要用到事务操作了

事务的操作:先定义开始一个事务,然后对数据作修改操作,这时如果提交(commit),这些修改就永久地保存下来,如果回退(rollback),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态。

事物的四大特性(面试题)

事物四大特性:ACID

原子性:一组操作不可分割

一致性:操作前后需要一直

隔离性:并发编程的时候,多个线程之间的操作不会相会影响

持久性:将内存中的数据持久化到磁盘

Demo

利用事务实现的转账功能

package com.ifueen.homework.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.ifueen.classtest.util.JDBCUtilDataSource;
import com.ifueen.homework.dao.Transfer;
import com.sun.org.apache.bcel.internal.generic.Select;

public class TransferDaoImpl implements Transfer{

	/**
	 * 查询账户余额
	 */
	@Override
	public double select(String name) {
		Double b = null;
		// TODO Auto-generated method stub
		Connection conn = JDBCUtilDataSource.getinstance().getconn();
		String sql = "select balance from transfer where name = ?";
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setString(1, name);
			ResultSet rs = ps.executeQuery();
			while(rs.next()){
				b = rs.getDouble("balance");
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return b;
	}
	
	
	/**
	 * 转账功能
	 */
	@Override
	public void transfer(String name, String name2, double money) {
		// TODO Auto-generated method stub
		Connection conn = JDBCUtilDataSource.getinstance().getconn();
		try {
			//设置事务的自动提交为false,即不自动提交
			conn.setAutoCommit(false);
			String sql = "update transfer set balance= ? where name = ?";
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setDouble(1, select(name)-money);
			ps.setString(2, name);
			ps.executeUpdate();
			//测试意外情况
			//System.out.println(1/0);
			//另一个账户增加
			String sql1 = "update transfer set balance= ? where name = ?";
			PreparedStatement ps1 = conn.prepareStatement(sql1);
			ps1.setDouble(1, select(name2)+money);
			ps1.setString(2, name2);
			ps1.executeUpdate();
			
			//完成操作提交事务
			conn.commit();
			JDBCUtilDataSource.getinstance().getclose(ps,conn);
			JDBCUtilDataSource.getinstance().getclose(ps1,conn);
			System.out.println("转账成功啦");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			try {
				//设置事务的自动回滚
				conn.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
	}
}

注意!MySQL中,InnoDB支持外键.支持事务,MyISAM不支持外键,不支持事务

使用JDBC拿到主键

为什么需要拿到Id?

现在我们插入的一条数据,但是并不知道该数据的id是多少, 而我们有时候操作,需要这个id.

比如我们向product表插入一条数据,它的数量为200,但是product表里面并没有表示数量的字段,而product_store表里面含有storeNum,所有我们应该在插入数据之后,同时需要插入一条数据到product_store表里面; – 这时候我们就需要拿到product表里新插入的id;

拿到主键的方法:

Connection conn = JDBCUtilDataSource.getinstance().getconn();
			String sql = "insert into student (name,age) value (?,?)";
			PreparedStatement ps = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
			ps.setString(1, name);
			ps.setInt(2, age);
			ps.execute();
			//拿到主键的集合
			ResultSet rs = ps.getGeneratedKeys();
			while (rs.next()) {
				System.out.println(rs.getLong(1));
			}

连接池

为什么要连接池?

每次请求都会创建一个connection,因此会浪费资源(内存),当同时1000人访问的时候,那就会占用很多资源,因此很浪费时间和容器操作系统崩溃

认识连接池

节约内存资源 维护连接对象的生命周期
最开始的时候就创建一些连接对象放到连接池中 请求来了可以直接在连接池中获取连接 操作数据库

操作完成以后 释放连接 回到连接池 等待下一次被请求使用
初始的时候 创建了一些连接 最小连接数 请求并发的时候 创建更多的连接 最大连接

常见的连接池

dbcp(spring集成)

c3p0

druid(常用)

使用dbcp连接池

注意:在使用连接池之前需要导入相应的包

Properties prop =new Properties();
    prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"))
    DataSource ds = BasicDataSourceFactory.createDataSource(prop);
    Connection conn=ds.getConnection();
发布了87 篇原创文章 · 获赞 7 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/f2315895270/article/details/99643814
今日推荐