DBCP讲义

今日内容介绍
1、连接池

###01连接池介绍
* A: 连接池介绍
* a: 连接池介绍
* 实际上就是存放连接的池子(容器)
* 在开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程
* 为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection。
* 这样我们就不需要每次都创建连接、释放连接了,这些操作都交给了连接池

###02连接池概念规范和DataSource接口
* A: 连接池概念规范和DataSource接口
* a: 连接池概念规范
* 用池来管理Connection,这样可以重复使用Connection。
* 不用自己来创建Connection,而是通过池来获取Connection对象
* 使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池
* 连接池技术可以完成Connection对象的再次利用
* b: DataSource接口
* Java为数据库连接池提供了公共的接口:javax.sql.DataSource
* 各个厂商需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池
* 常见的连接池:DBCP、C3P0
###03DBCP连接池介绍
* A: DBCP连接池介绍
* a: DBCP连接池介绍
* DBCP也是一个开源的连接池,是Apache Common成员之一,在企业开发中也比较常见,tomcat内置的连接池
* tomcat服务器简单介绍

###04导入jar包
* A: 导入jar包
* a: jar包介绍
* mysql-connector-java-5.1.37-bin.jar:数据库驱动
* commons-dbutils-1.6.jar:提供QueryRunner类方便进行增删改查操作
* commons-dbcp-1.4.jar:
* commons-pool-1.5.6.jar:提供高效的数据库连接池技术
* b: 导入jar包
* 在项目根路径下建立文件夹lib
* 拷贝以上jar包,选定拷贝的jar包/右键/Build Path/Add to Build Path

###05BasicDataSource类的使用
* A: BasicDataSource类的使用
* a: 案例代码
/*
* 连接池jar包中,定义好一个类 BasicDataSource
* 实现类数据源的规范接口 javax.sql.DataSource
*/
public class DataSoruceDemo {
public static void main(String[] args) {
//创建DataSource接口的实现类对象
//实现类, org.apache.commons.dbcp
BasicDataSource dataSource = new BasicDataSource();
//连接数据库的4个最基本信息,通过对象方法setXXX设置进来
dataSource.setDriverClassName(“com.mysql.jdbc.Driver”);
dataSource.setUrl(“jdbc:mysql://localhost:3306/mybase”);
dataSource.setUsername(“root”);
dataSource.setPassword(“123”);

				try{
				//调用对象方法getConnection获取数据库的连接
					Connection con = dataSource.getConnection();
					System.out.println(con);
				}catch(SQLException ex){
		//			System.out.println(ex);
					ex.printStackTrace();
					throw new RuntimeException("数据库连接失败");
				}
			}
		}

###06BasicDataSource类的常见配置
* A: BasicDataSource类的常见配置
* a: 常见配置
分类 属性 描述
必须项
driverClassName 数据库驱动名称
url 数据库的地址
username 用户名
password 密码
基本项(扩展)
maxActive 最大连接数量
minIdle 最小空闲连接
maxIdle 最大空闲连接
initialSize 初始化连接

###07实现数据库连接池工具类
* A: 实现数据库连接池工具类
* a: 案例代码
/*
* 使用DBCP实现数据库的连接池
* 连接池配置,自定义类,
* 最基本四项完整
* 对于数据库连接池其他配置,自定义
*/

		import javax.sql.DataSource;

		import org.apache.commons.dbcp.BasicDataSource;
		public class JDBCUtils{
			//创建出BasicDataSource类对象
			private static BasicDataSource datasource = new BasicDataSource();
			
			//静态代码块,对象BasicDataSource对象中的配置,自定义
			static{
				//数据库连接信息,必须的
				datasource.setDriverClassName("com.mysql.jdbc.Driver");
				datasource.setUrl("jdbc:mysql://localhost:3306/day33_user");
				datasource.setUsername("root");
				datasource.setPassword("123");
				//对象连接池中的连接数量配置,可选的
				datasource.setInitialSize(10);//初始化的连接数
				datasource.setMaxActive(8);//最大连接数量
				datasource.setMaxIdle(5);//最大空闲数
				datasource.setMinIdle(1);//最小空闲
			}
			
			
			//定义静态方法,返回BasicDataSource类的对象
			public static DataSource getDataSource(){
				return datasource;
			}
		}

###08工具类的测试
* A: 工具类的测试
* a: 案例代码
/*
* 测试写好的工具类,
* 提供的是一个DataSource接口的数据源
* QueryRunner类构造方法,接收DataSource接口的实现类
* 后面,调用方法update,query,无需传递他们Connection连接对象
*/

		import java.sql.SQLException;
		import java.util.List;

		import org.apache.commons.dbutils.QueryRunner;
		import org.apache.commons.dbutils.handlers.ArrayListHandler;

		import cn.itcast.jdbcutils.JDBCUtils;
		public class QueryRunnerDemo{
			public static void main(String[] args) {
				select();
			}
			//定义2个方法,实现数据表的添加,数据表查询
			//QueryRunner类对象,写在类成员位置
			private static QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource()); 
			
			//数据表查询
			public static void select(){
				String sql = "SELECT * FROM sort";
				try{
				List<Object[]> list = qr.query(sql, new ArrayListHandler());
				for(Object[] objs : list){
					for(Object obj : objs){
						System.out.print(obj+"\t");
					}
					System.out.println();
				}
				}catch(SQLException ex){
					throw new RuntimeException("数据查询失败");
				}
			}
			
			//数据表添加数据
			public static void insert(){
				String sql = "INSERT INTO sort (sname,sprice,sdesc)VALUES(?,?,?)";
				Object[] params = {"水果",100.12,"刚刚上市的核桃"};
				try{
					int row = qr.update(sql, params);
					System.out.println(row);
				}catch(SQLException ex){
					throw new RuntimeException("数据添加失败");
				}
			}
			
		}

###09登录注册案例分析
* A: 登录注册案例分析(详见day33_source/用户登录注册案例.JPG)
* a: 登录
* 接收键盘输入的用户名和密码
* 调用另一个类的方法,传递用户名和密码
* 导数据表中查询是否有用户
* 如果有,告诉用户登录成功
* b: 注册
* 接收键盘输入的用户名和密码
* 调用另一个类的方法,传递用户名和密码
* 查询用户名是否存在,存在就告诉用户注册失败,不存在执行数据库的insert操作

###10创建数据库和数据表
* A:创建数据库和数据表
* a: 创建数据库
/*
创建用户的数据库
名字: day33_user
/
CREATE DATABASE day33_user;
USE day33_user;
* b: 创建数据库表
/

创建用户的数据表
名字: users
三个列: 主键,用户名,密码
*/
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
PASSWORD VARCHAR(50) NOT NULL
);
– 写入表中测试数据
INSERT INTO users (username,PASSWORD) VALUES
(‘a’,‘1’),(‘b’,‘2’);

		SELECT * FROM users

###11案例编程过程分析
* A: 案例编程过程分析

###12登录注册案例建包建类
* A: 登录注册案例建包建类
* a: 建包
* 建立:cn.itcast.dao包
* 建立:cn.itcast.ui包
* b: 建类
* cn.itcast.dao包中建立UsersDao类
* cn.itcast.ui包中建立UserOperator类

###13登录注册案例登录功能实现
* A: 登录注册案例登录功能实现
* a: 案例代码
public class UsersDao{
//创建QueryRunner类的对象,构造方法中,传递工具类中获取的数据源
private QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

		/*
		 *  创建登录功能,接收用户的输入的用户名和密码
		 *  返回登录的结果 true 登录成功  false 登录失败 
		 *  实现思想:
		 *    用户名和密码,作为数据表users的查询条件,查询表结果集
		 *    有结果集,返回true
		 *    没有结果集,返回false
		 */
		public boolean login(String username,String password){
			try{
				//拼写查询数据表的SQL
				String sql  = "SELECT * FROM users WHERE username=? and password=?";
				Object[] params = {username,password};
				//调用qr方法query查询数据表
				Object[] result = qr.query(sql, new ArrayHandler(),params);
				//对数组进行判断,没有结果集
				if(result.length==0)
					return false;
				//if判断为假,有结果集
				return true;
			}catch(SQLException ex){
				System.out.println(ex);
				throw new RuntimeException("登录查询失败");
			}
		}
	}

###14登录注册案例注册功能实现
* A: 登录注册案例注册功能实现
* a: 案例代码
public class UsersDao{
//创建QueryRunner类的对象,构造方法中,传递工具类中获取的数据源
private QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

			/*
			 *  创建注册功能,接收用户的输入用户名和密码
			 *  返回注册结果  true 注册成功  false注册失败,用户名被占
			 *  实现思想:
			 *    检查用户名是否被占
			 *      将用户输入的用户名,作为users表查询条件
			 *      如果有结果集,说明用户名已经有了, 返回false
			 *      
			 *      如果没有结果集,用户名可以使用
			 *      用户名和密码insert 写入到数据表,返回true
			 */
			
			public boolean register(String username,String password){
				try{
					//拼写SQL语句,检查用户是否被占,用户名作为条件查询
					String sql = "SELECT username FROM users WHERE username=?";
					//调用qr对象方法query查询结果集,ScalarHandler 一个结果集
					String user = qr.query(sql, new ScalarHandler<String>(), username);
					//如果用户名存在,user变量,表示一个用户名,用户名不存在,user变量结果null
					if(user != null)
						return false;
					//用户名可以使用
					//拼写添加用户名密码的SQL语句
					sql = "INSERT INTO users (username,PASSWORD) VALUES (?,?)";
					//创建对象数组,保存?占位符的实际参数
					Object[] params = {username,password};
					//调用qr对象方法update写入数据
					qr.update(sql, params);
					return true;
				}catch(SQLException ex){
					System.out.println(ex);
					throw new RuntimeException("注册失败");
				}
			}
		}

###15登录注册案例登录功能调用测试
* A: 登录注册案例登录功能调用测试
* a: 案例代码
public class UserOperator {

			private static Scanner sc = new Scanner(System.in);
			
			public static void main(String[] args) {
				UsersDao dao = new UsersDao();
				String number = chooser();
				//对选择序号判断
				switch(number){
				   case "1":
					   //接收键盘输入,调用登录功能
					   System.out.println("选择的是登录,请输入用户名");
					   String username = sc.next();
					   System.out.println("输入密码");
					   String password = sc.next();
					   //调用Dao包中的UserDao类中的方法login传递用户名密码
					   
					   boolean b  = dao.login(username, password);
					   if(b)
						   System.out.println("登录成功");
					   else
						   System.out.println("登录失败,检查你的用户名和密码");
				   break;
				   
				   case "2":
						
				   break;
				   
				   case "3":
					   System.exit(0);
				   default:
					   System.out.println("没有此功能");
				   break;
				}
			
			}
			/*
			 * 定义方法,选择功能菜单的
			 * 返回选择内容
			 */
			public static String chooser(){
				System.out.println("欢迎光临");
				System.out.println("请选择功能菜单");
				System.out.println("1 登录  2 注册  3 退出");
				return sc.next();
			}
		}

###16登录注册案例注册功能调用测试
* A: 登录注册案例注册功能调用测试
* a: 案例代码
/*
* 实现和用户的交互部分
* 提供菜单,让用户选择菜单,根据菜单,调用不同的功能
*/
public class UserOperator {

			private static Scanner sc = new Scanner(System.in);

			public static void main(String[] args) {
				UsersDao dao = new UsersDao();
				// 调用选择方法,获取用户的选择内容
				while (true) {
					String number = chooser();
					// 对选择序号判断
					switch (number) {
					case "1":
						// 接收键盘输入,调用登录功能
						System.out.println("选择的是登录,请输入用户名");
						String username = sc.next();
						System.out.println("输入密码");
						String password = sc.next();
						// 调用Dao包中的UserDao类中的方法login传递用户名密码

						boolean b = dao.login(username, password);
						if (b)
							System.out.println("登录成功");
						else
							System.out.println("登录失败,检查你的用户名和密码");
						break;

					case "2":
						// 接收键盘输入,调用注册功能
						System.out.println("选择的是注册,请输入用户名");
						username = sc.next();
						System.out.println("请输入密码");
						password = sc.next();
						// 调用Dao包中的UserDao类中的方法register传递用户名密码
						b = dao.register(username, password);
						if (b)
							System.out.println("注册成功");
						else
							System.out.println("注册失败,用户名被占用,请尝试 " + username + "_123");
						break;

					case "3":
						System.exit(0);
					default:
						System.out.println("没有此功能");
						break;
					}
				}
			}

			/*
			 * 定义方法,选择功能菜单的 返回选择内容
			 */
			public static String chooser() {
				System.out.println("欢迎光临");
				System.out.println("请选择功能菜单");
				System.out.println("1 登录  2 注册  3 退出");
				return sc.next();
			}
		}

###17总结
* 把今天的知识点总结一遍。

猜你喜欢

转载自blog.csdn.net/ITzhongzi/article/details/85114985