数据库连接池简介

创建Connection的过程是非常耗时的,为了保证Conection可以重用。应该将Connection进行池管理

没有连接池用工厂类维护一个链接

/**
 * 用静态工厂方法管理一个唯一的可重用的连接
 */
public class ConnUtils {
	private static Connection con;
	//在静态代码块中创建与数据库的连接
	static{
		try{
			Class.forName("com.mysql.jdbc.Driver");
			String url = "jdbc:mysql:///db909?characterEncoding=UTf8";
			con = DriverManager.getConnection(url,"root","1234");
		}catch(Exception e){
			throw new RuntimeException(e.getMessage(),e);
		}
	}
	//使用一个静态方法-静态工厂方法,返回connection实例
	public static Connection getCon(){
		return con;
	}
}


mvc讲述





tomcat管理内存的方式 

为了节省内存空间 每次request虽然立即死亡 但是内存确实重复使用 不销毁再构建
每个Servlet都是单例的 由tomcat维护

模拟一个用户登录的框架 mvc依次来写


表结构

create table users(
  id varchar(32) primary key,
  name varchar(50),
  pwd varchar(32)
);

DAO层

public class RegDao {
	public void reg(User user){
		//声明sql语句,执行insert
		Connection con = null;
		try{
			con = ConnUtils2.getCon();//获取连接
			//声明sql
			String sql = "insert into users(id,name,pwd) values(?,?,?)";
			PreparedStatement pst = con.prepareStatement(sql);
			pst.setString(1,user.getId());
			pst.setString(2,user.getName());
			pst.setString(3, user.getPwd());
			pst.executeUpdate();
		}catch(Exception e){
			throw new RuntimeException(e.getMessage(),e);
		}finally{
			try {
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

Service层

public class RegService {
	//声明dao的实例,注入
	private RegDao dao = new RegDao();
	public void reg(User user){
		//设置id
		user.setId(UUID.randomUUID().toString().replace("-", ""));
		//调用保存的方法
		dao.reg(user);
	}
}


控制层

public class RegServlet extends HttpServlet {
	//声明Service4的实例
	private RegService service = new RegService();
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//设置编码
		request.setCharacterEncoding("UTf-8");
		//接收信息
		String name = request.getParameter("name");
		String pwd = request.getParameter("pwd");
		//封装成User对象
		User u = new User(null,name,pwd);
		//调用service保存
		service.reg(u);
		
	}

}

不能在dopost的方法体内new Service层的实例


但是以上方法不能多线程并发操作



注意事项

数据库表设置id主键时不要使用int 型 因为int有限度 使用varchar(32)

用java.utils.UUID类设置id
user.setId(UUID.randomUUID().toString().replace("-", ""));





String uuid = UUID.randomUUID().toString();
System.err.println(uuid + "," + uuid.length());
输出结果为   95a392c2-cee8-44e1-aadf-be15ae1fc84a,36
不需要-作为分隔符
这样写
		String uuid = UUID.randomUUID().toString().replace("-", "");
		System.err.println(uuid + "," + uuid.length());

输出结果
8a72992bf7ae4d7091399507b6dee014,32



隔离级别

1:读未提交 - 一个Connection读取到了别的连接还没有提交的数据。Read uncommitted.
2:读已提交 - 
3:可重复读 – 一个Connection在自己的事务之内,读取到的永远是自己之前读取到的数据。4,默认值。保证在同一个Connection的事务之内,读取到的数据,具有一侄性。
4:序列化 –Sericable – 在一个Connection操作某个表时,会对这个表执行锁定。其他的connection必须要等待解锁。

连接池的实现

连接池的基本实现
为什么要有连接池
 1:维护多个连接。必须要保证每一个线程获取到的是不同的connection对象。
 2:提供一个方法可以回收连接。

public class ConnUtils2 {
	//声明一个容器,放所有声明的连接Connection
	private static List<Connection> pool = new ArrayList<Connection>();
	static{
		try{
			Class.forName("com.mysql.jdbc.Driver");
			String url = "jdbc:mysql:///db909?characterEncoding=UTf8";
			for(int i=0;i<3;i++){
				//创建三个连接
				Connection con = DriverManager.getConnection(url,"root","1234");
				//将这个三个连接放到pool中去
				pool.add(con);
			}
			System.err.println("连接是:"+pool);
		}catch(Exception e){
			throw new RuntimeException(e.getMessage(),e);
		}
	}
	public static Connection getCon(){
		synchronized (pool) {
			Connection con = pool.remove(0);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.err.println("还有:"+pool.size());
			return con;
		}
	}
	//手工的还连接
	public static void back(Connection con){
		System.err.println("还连接:"+con);
		pool.add(con);
	}
}
过程

声明一个缓存池。

将多个连接对象放到pool池中。

 

同步从池中获取一个连接。且删除已经获取出去的连接。

提供一个方法可以加收连接。

而程序员,总是调用close方法,所以为了回收连接。我们应该重写close方法。对close方法增强。

子类。

包装。

代理。

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值