说说数据库连接池工作原理和实现方案?
说说数据库连接池工作原理和实现方案?
工作原理:
- JAVA EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。
实现方案:连接池使用集合来进行装载,返回的Connection是原始Connection的代理,代理Connection的close方法,当调用close方法时,不是真正关连接,而是把它代理的Connection对象放回到连接池中,等待下一次重复利用。
具体代码:
@Override
publicConnectiongetConnection()throwsSQLException{
if(list.size()>0){
finalConnectionconnection=list.removeFirst();
//看看池的大小
System.out.println(list.size());
//返回一个动态代理对象
return(Connection)Proxy.newProxyInstance(Demo1.class.getClassLoader(),connection.getClass().getInterfaces(),newInvocationHandler(){
@Override
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
//如果不是调用close方法,就按照正常的来调用
if(!method.getName().equals("close")){
method.invoke(connection,args);
}else{
//进到这里来,说明调用的是close方法
list.add(connection);
//再看看池的大小
System.out.println(list.size());
}
returnnull;
}
});
}
returnnull;
}
Java中如何进行事务的处理?
Java中如何进行事务的处理?
- 事务是作为单个逻辑工作单元执行的一系列操作。
- 一个逻辑工作单元必须有四个属性,称为原子性、一致性、隔离性和持久性 (ACID) 属性,只有这样才能成为一个事务
Connection类中提供了4个事务处理方法:
- setAutoCommit(Boolean autoCommit):设置是否自动提交事务,默认为自动提交,即为true,通过设置false禁止自动提交事务;
- commit():提交事务;
- rollback():回滚事务.
- savepoint:保存点
- 注意:savepoint不会结束当前事务,普通提交和回滚都会结束当前事务的
修改JDBC代码质量
下述程序是一段简单的基于JDBC的数据库访问代码,实现了以下功能:从数据库中查询product表中的所有记录,然后打印输出到控制台.该代码质量较低,如没有正确处理异常,连接字符串以”魔数”的形式直接存在于代码中等,请用你的思路重新编写程序,完成相同的功能,提高代码质量.
原来的代码:
publicvoidprintProducts(){
Connectionc=null;
Statementss=null;
ResultSetr=null;
try{
c=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:sid","username","password");
s=c.createStatement();
r=s.executeQuery("select id, name, price from product");
System.out.println("Id\tName\tPrice");
while(r.next()){
intx=r.getInt("id");
Stringy=r.getString("name");
floatz=r.getFloat("price");
System.out.println(x+"\t"+y+"\t"+z);
}
}catch(Exceptione){
}
}
修改后的代码:
classConstant{
publicstaticfinalStringURL="jdbc:oracle:thin:@127.0.0.1:1521:sid";
publicstaticfinalStringUSERNAME="username";
publicstaticfinalStringPASSWORD="password";
}
classDAOExceptionextendsException{
publicDAOException(){
super();
}
publicDAOException(Stringmsg){
super(msg);
}
}
publicclassTest{
publicvoidprintProducts()throwsDAOException{
Connectionc=null;
Statements=null;
ResultSetr=null;
try{
c=DriverManager.getConnection(Constant.URL,Constant.USERNAME,Constant.PASSWORD);
s=c.createStatement();
r=s.executeQuery("select id,name,price from product");
System.out.println("Id\tName\tPrice");
while(r.next()){
intx=r.getInt("id");
Stringy=r.getString("name");
floatz=r.getFloat("price");
System.out.println(x+"\t"+y+"\t"+z);
}
}catch(SQLExceptione){
thrownewDAOException("数据库异常");
}finally{
try{
r.close();
s.close();
c.close();
}catch(SQLExceptione){
e.printStackTrace();
}
}
}
}
修改点:
- url、password等信息不应该直接使用字符串“写死”,可以使用常量代替
- catch中应该回滚事务,抛出RuntimeException也是回滚事务的一种方法
- 关闭资源
写出一段JDBC连接本机MySQL数据库的代码
写出一段JDBC连接本机MySQL数据库的代码
Class.forName("com.mysql.jdbc.Driver");
Stringurl="jdbc:mysql://localhost/test";
Stirnguser='root';
Stringpassword='root';
Connectionconn=DriverManager.getConnection(url,user,passwo