MySQL从入门到入魔之数据库连接池(04)丨【绽放吧!数据库】

举报
海拥 发表于 2021/08/06 17:15:30 2021/08/06
【摘要】 数据库连接池为什么使用数据库连接池?如果不使用连接池每一次客户端发出的业务请求都需要对应一次数据库连接,如果有一万次请求就有一万次数据库连接的建立和断开,频繁的开关连接会影响程序的执行效率,通过数据库连接池可以将数据库连接进行复用,从而提高执行效率.如何使用? //创建连接池对象 DruidDataSource ds = new DruidDataSource(); //设置数据库连...

数据库连接池

  • 为什么使用数据库连接池?
    如果不使用连接池每一次客户端发出的业务请求都需要对应一次数据库连接,如果有一万次请求就有一万次数据库连接的建立和断开,频繁的开关连接会影响程序的执行效率,通过数据库连接池可以将数据库连接进行复用,从而提高执行效率.

  • 如何使用?

      //创建连接池对象
      DruidDataSource ds = new DruidDataSource();
      //设置数据库连接信息
      ds.setDriverClassName(driver);
      ds.setUrl(url);
      ds.setUsername(username);
      ds.setPassword(password);
      //设置初始连接数量
      ds.setInitialSize(Integer.parseInt(initSize));
      //设置最大连接数量
      ds.setMaxActive(Integer.parseInt(maxSize));
      //从连接池对象中获取连接  异常抛出
      Connection conn = ds.getConnection();
    

jdbc.properties

db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/newdb3?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
db.username=root
db.password=123456
db.maxActive=10
db.initialSize=2

读取*.properties配置文件

	//创建读取配置文件的属性对象
	Properties p = new Properties();
	//得到文件输入流 这种写法会自动去src/main/resources目录下找文件
	InputStream ips = Demo03.class.getClassLoader()
			.getResourceAsStream("my.properties");
	//把文件输入流交给属性对象
	p.load(ips);
	//读取数据
	String name = p.getProperty("name");
	//getProperty方法只能读取字符串
	String age = p.getProperty("age");
	System.out.println(name+":"+age);

读取 jdbc.properties配置文件

public class DBUtils {
	private static DruidDataSource ds;
	//因为读取配置文件只需要读取一次,连接池对象也只需要创建一次 
	static {
		//读取配置文件里面的数据
		Properties p = new Properties();
		InputStream ips = DBUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
		try {
			p.load(ips);
		} catch (IOException e) {

			e.printStackTrace();
		}
		String driver = p.getProperty("db.driver");
		String url = p.getProperty("db.url");
		String username = p.getProperty("db.username");
		String password = p.getProperty("db.password");
		String maxActive = p.getProperty("db.maxActive");
		String initialSize = p.getProperty("db.initialSize");
		ds = new DruidDataSource();
		ds.setDriverClassName(driver);
		ds.setUrl(url);
		ds.setUsername(username);
		ds.setPassword(password);
		// 设置初始连接数量
		ds.setInitialSize(Integer.parseInt(initialSize));
		// 设置最大连接数量
		ds.setMaxActive(Integer.parseInt(maxActive));
	}
	public static Connection getConn() throws SQLException {
		// 注册驱动
		// 从连接池对象中获取连接 异常抛出
		Connection conn = ds.getConnection();
		System.out.println(conn);
		return conn;
	}
}
  • 创建用户表
    use newdb3;
    create table user(id int primary key auto_increment,username varchar(20),password varchar(20))charset=utf8;

注册功能

import java.sql.Connection;
import java.sql.Statement;
import java.util.Scanner;
/**
 * 注册功能
 * @author 海拥😋
 * @date 2020年5月7日 下午2:04:42
 */
public class Demo04 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入用户名");
		String username = sc.nextLine();
		System.out.println("请输入密码");
		String password = sc.nextLine();
		sc.close();
		// 获取连接
		try (Connection conn = DBUtils.getConn();) {
			Statement s = conn.createStatement();
			String sql = "insert into user values(null,'"+username+"','"+password+"')";
			s.executeUpdate(sql);
			System.out.println("注册成功");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

登录功能

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
/** 
 * 登录功能
 * @author 海拥😋
 * @date 2020年5月7日 下午2:11:29
 */
public class Demo05 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入用户名");
		String username = sc.nextLine();
		System.out.println("请输入密码");
		String password = sc.nextLine();
		
		//获取连接
		try (Connection conn = DBUtils.getConn();) {
			Statement s = conn.createStatement();
//			String sql =
//					"select count(*) from user where username='"
//					+username+"'and password='"+password+"'";
//			ResultSet rs = s.executeQuery(sql);
			
			//通过PrepredStatement解决SQL注入问题
			String sql = "select count(*) from user where username=? and password=?";
			//在编译时已经将SQL语句的业务逻辑锁死 用户写的内容不会再影响逻辑
			PreparedStatement ps = conn.prepareStatement(sql);
			//替换sql中的?
			ps.setString(1, username);
			ps.setString(2, password);
			//执行SQL
			ResultSet rs = ps.executeQuery();
			//查询回来的是符合条件的数量 只有一条数据所以可以用if 如果查询回来的是
			//多条数据必须用while
			if(rs.next()) {
				//取出查询回来的符合条件的数量
				int count =rs.getInt(1);
				if(count>0) {
					System.out.println("登录成功");
				}else {
					System.out.println("登录失败");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Statement和PreparedStatement

  • 如果执行的SQL语句中存在变量,为了避免SQL注入所以使用PreparedStatement
  • 如果SQL语句中没有变量则使用Statement

批量操作

  • 批量操作就是将多条SQL语句执行时的多次网络数据传输合并成一次传输,从而提高执行效率
  • 代码参考Demo06.java
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
/**
 * 批量操作
 * @author 海拥😋
 * @date 2020年5月7日 下午3:27:24
 */
public class Demo06 {
	public static void main(String[] args) {
		//获取连接
		try (Connection conn = DBUtils.getConn();) {
			String sql1="insert into user values(null,'刘备','123')";
			String sql2="insert into user values(null,'关羽','123')";
			String sql3="insert into user values(null,'张飞','123')";
			Statement s = conn.createStatement();
//			s.executeUpdate(sql1);
//			s.executeUpdate(sql2);
//			s.executeUpdate(sql3);
			//通过批量操作将多次数据传输合并成一次
//			s.addBatch(sql1);
//			s.addBatch(sql2);
//			s.addBatch(sql3);
//			//执行批量操作
//			s.executeBatch();
//			System.out.println("执行完成");
			//preparedStatement批量操作
			String sql = "insert into user values(null,?,?)";
			PreparedStatement ps = conn.prepareStatement(sql);
			for (int i = 0;i<100;i++) {
				ps.setString(1, "name"+i);
				ps.setString(2, "pw"+i);
				//添加到批量操作
				ps.addBatch();
				//每隔20次执行一次 避免内存溢出
				if(i%20==0) {
					ps.executeBatch();
				}	
			}
			//执行批量操作
			ps.executeBatch();
			System.out.println("执行完成");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

分页查询

  • 代码参考Demo07.java
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;
/** 
 * 分页查询
 * @author 海拥😋
 * @date 2020年5月7日 下午4:22:49
 */
public class Demo07 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入查询的页数");
		int page = sc.nextInt() ;
		System.out.println("请输入查询的条数");
		int count = sc.nextInt();
		if(page<1) {
			System.out.println("输入错误");
		}
		//获取连接
		try (Connection conn = DBUtils.getConn();) {
			String sql ="select username,password from user limit ?,?";
			PreparedStatement ps =conn.prepareStatement(sql);
			//第一个?代表跳过的条数=(请求页数-1)*条数
			ps.setInt(1, (page-1)*count);
			//第二个?代表请求条数(每页条数)
			ps.setInt(2,count);
			//执行查询
			ResultSet rs = ps.executeQuery();
			while(rs .next()) {
			String username = rs.getString(1);
			String password = rs.getString(2);
			System.out.println( username+":"+password) ;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

获取自增主键值

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
/**
 * 获取自增主键值
 * @author 海拥😋
 * @date 2020年5月7日 下午4:40:33
 */
public class Demo08 {
	public static void main(String[] args) {
		//获取连接
		try (Connection conn = DBUtils.getConn();) {
			String sql =
					"insert into user values(null,'james','123456')";
			Statement s = conn.createStatement();
			//编译SQL语句时,需要设置返回自增主键值
			s.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);
			//通过结果集 获取自增的主键值
			ResultSet rs  = s.getGeneratedKeys();
			if(rs.next()) {
				int id =rs.getInt(1);
				System.out.println("id="+id);
			}
			System.out.println("插入完成");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
  • 创建球队表
    create table team(id int primary key auto_increment,name varchar(10))charset=utf8;
  • 创建球员表
    create table player(id int primary key auto_increment,name varchar(10),teamId int)charset=utf8;

球队球员小练习

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
/**
 * @author 海拥😋
 * @date 2020年5月7日 下午5:17:59
 */
public class Demo09 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入球队名字");
		String teamName = sc.nextLine();
		System.out.println("请输入球员名字");
		String playerName = sc.nextLine();
		// 获取连接
		try (Connection conn = DBUtils.getConn();) {
			String sql = "insert into team values(null,?)";
			PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
			// 替换?
			ps.setString(1, teamName);
			// 执行
			ps.executeUpdate();
			// 获取自增主键值
			ResultSet rs = ps.getGeneratedKeys();
			if (rs.next()) {
				int teamId = rs.getInt(1);
				System.out.println("球队id:"+teamId);
				String psql = "insert into player values(null,?,?)";
				PreparedStatement pps = conn.prepareStatement(psql);
				pps.setString(1, playerName);
				pps.setInt(2, teamId);
				pps.executeUpdate();
				System.out.println("保存完成!");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

代码介绍

  1. Demo04 注册功能
  2. Demo05 登录功能 接触了预编译的Sql执行对象 讲解了SQL注入(给用户写值的位置,用户写进去了SQL语句 导致原有逻辑发生改变)
  3. Demo06 批量操作
  4. Demo07 分页查询
  5. Demo08 获取自增主键值
  6. Demo09 球队球员小练习

【绽放吧!数据库】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/285617

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。