目录
什么是连接池
为什么要使用连接池
c3p0连接池
c3p0官网和api下载
列:使用线程解决:多个线程访问共享变量不互相影响
列:使用连接池
mysql的实现
tb_user表
tb_address表(地址表)
导包新建c3p0-config.xml文件
新建JDBC Util工具类Dbutils.java
JDBC连接实现
用户接口UserDao.java
用户实现类UserDaoImpl.java
测试类:测试用户名和密码是否查询成功
加深内容:测试QueryRunner.java中的方法
封装地址数据Address.java
封装User.java
多表查询工具类CommonsTools.java
方法测试TestTxQueryRunner.java
结果:
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。
连接池技术尽可能多地重用了消耗内存地资源,大大节省了内存,提高了服务器地服务效率,能够支持更多的客户服务。通过使用连接池,将大大提高程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。
http://mvnrepository.com/
下载
使用包junit-4.8.2.jar
public class TestThreadLocal {
//fun1相当于主线程
@Test
public void fun1(){
ThreadLocal tl=new ThreadLocal();
tl.set("aaa");//
String temp=tl.get();
//匿名类 开启一个线程
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
tl.set("bbb");
System.out.println(Thread.currentThread().getName()+"===="+tl.get());
}
}.start();
System.out.println(Thread.currentThread().getName()+"****"+temp);
}
}
结果:
导包
命名必须为c3p0-config.xml,
必须放在src目录下,c3p0包会默认加载src目录下的c3p0-config.xml文件。
jdbc:mysql://localhost:3306/shopping
com.mysql.jdbc.Driver
root
root
3
10
2
10
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class Dbutils {
private static DataSource ds=new ComboPooledDataSource();//拿到数据源
//解决线程同步
private static ThreadLocal tl=new ThreadLocal();
//获取连接池
public static DataSource getDataSource(){
return ds;
}
/**
* 获取连接
* 如果有事务,返回当前事务的connection
* 如果没有事务,通过连接池中获取connection对象
* @return 返回当前的事务的连接
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
Connection conn=tl.get(); //获取当前线程程序的事务连接;
if(conn!=null) return conn;//当连接不能空是获取连接
return ds.getConnection(); //否则从池里获取
}
/**
* 开启事务
* @throws SQLException
*/
public static void beginTransaction() throws SQLException{
Connection conn=tl.get();//获取当前线程程序的事务连接
if(conn!=null) throw new SQLException("事务巳开启,不能再开启事务");
conn=ds.getConnection(); //开启了事务
conn.setAutoCommit(false); //设置手动提交
tl.set(conn); //当前事务放在tl线程副本变量中
}
/**
* 事务提交
* @throws SQLException
*/
public static void commitTransaction() throws SQLException{
Connection conn=tl.get(); //获取当前线程的事务连接;
if(conn==null) throw new SQLException("没有事务不能提交");
conn.commit(); //不能为空,提交事务
conn.close();//关闭连接
conn=null; //表示事务结束,虚拟机垃圾回收;
tl.remove();//移出当前事务
}
/**
* 回滚事务
* @throws SQLException
*/
public static void rollbackTransaction() throws SQLException{
Connection conn=tl.get(); //获取当前事务的连接;
if(conn==null) throw new SQLException("没有事务不能提交");
conn.rollback(); //回退事务
conn.close();//关闭连接
conn=null; //事务结束,虚拟机垃圾回收
tl.remove();
}
//关闭连接
public static void closeConnection(Connection connection) throws SQLException{
Connection conn=tl.get(); //获取当前线程的事务连接;
if(connection!=conn){ //传进来的connection与当前事务的conn不相同,可以关闭;
if(connection!=null&&connection.isClosed()){
connection.close();
}
}
}
}
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
public class TxQueryRunner extends QueryRunner {
//批处理
@Override
public int[] batch(String sql, Object[][] params)
throws SQLException {
// TODO Auto-generated method stub
Connection conn=Dbutils.getConnection();//获取数据库连接
int []result=super.batch(conn, sql, params);//批处理
Dbutils.closeConnection(conn);//关闭连接
return result; //返回处理结果
}
@Override
public T query(String sql, ResultSetHandler rsh,
Object... params) throws SQLException {
// TODO Auto-generated method stub
Connection conn=Dbutils.getConnection();
//super 调用父类的方法
T result= super.query(conn, sql, rsh, params);
Dbutils.closeConnection(conn);
return result;
}
@Override
public T query(String sql, ResultSetHandler rsh)
throws SQLException {
// TODO Auto-generated method stub
Connection conn=Dbutils.getConnection();
T result=super.query(conn, sql, rsh);
Dbutils.closeConnection(conn);
return result;
}
@Override
public int update(String sql, Object... params)
throws SQLException {
// TODO Auto-generated method stub
Connection conn=Dbutils.getConnection();
int count= super.update(conn, sql, params);
Dbutils.closeConnection(conn);
return count;
}
@Override
public int update(String sql, Object param)
throws SQLException {
// TODO Auto-generated method stub
Connection conn=Dbutils.getConnection();
int count=super.update(conn, sql, param);
Dbutils.closeConnection(conn);
return count;
}
@Override
public int update(String sql) throws SQLException {
// TODO Auto-generated method stub
Connection conn=Dbutils.getConnection();
int count=super.update(sql);
Dbutils.closeConnection(conn);
return count;
}
}
public interface UserDao {
//查询用户名和密码
public User queryByUserAndPassword(String userName,String password);
//添加一条数据
public int addUser(User user);
}
import com.iotek.commons.jdbc.TxQueryRunner;
import com.iotek.po.User;
public class UserDaoImpl extends TxQueryRunner implements UserDao {
/**
*查询数据库中是否存在用户名和密码
*/
@Override
public User queryByUserAndPassword(String userName, String password) {
// TODO Auto-generated method stub
try {
String sql="select id,username,password,confirmpassword,email,phone from tb_user where username=? and password=?";
//查询数据
return query(sql, new BeanHandler(User.class),userName,password);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;//没找到返回空
}
@Override
public int addUser(User user) {
// TODO Auto-generated method stub
return 0;
}
}
查询用户名和密码在数据库中是否存在
TestUserDaoImpl.java
import org.junit.Test;
import com.iotek.po.User;
import com.iotek.user.dao.UserDao;
import com.iotek.user.dao.UserDaoImpl;
public class TestUserDaoImpl {
@Test
public void testQueryByUsernameAndPassword(){
UserDao userDao=new UserDaoImpl();
//查询用户名和密码
User user=userDao.queryByUserAndPassword("css", "css");
System.out.println("user="+user);
}
}
测试结果:
public class Address implements java.io.Serializable {
private Integer aid;
private String addr;
private String remark;
public Address() {
// TODO Auto-generated constructor stub
}
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return "Address [aid=" + aid + ", addr=" + addr + ", remark=" + remark
+ "]";
}
}
public class User implements java.io.Serializable {
private Integer id;
private String username;
private String psw;
private String confirmpassword;
private String email;
private String phone;
private Address address; //设置对象的关联关系(组合关系) (两个表之间的关联关系)
public User() {
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPsw() {
return psw;
}
public void setPsw(String psw) {
this.psw = psw;
}
public String getConfirmpassword() {
return confirmpassword;
}
public void setConfirmpassword(String confirmpassword) {
this.confirmpassword = confirmpassword;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", psw=" + psw
+ ", confirmpassword=" + confirmpassword + ", email=" + email
+ ", phone=" + phone + ", address=" + address + "]";
}
}
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import com.iotek.po.Address;
import com.iotek.po.User;
/**
* 工具类
* @author Administrator
*
*/
public class CommonsTools {
/**
* Map集合转换成对象
*/
public static T toBean(Map map,Class clazz){
try {
T bean=clazz.newInstance();//实例化
BeanUtils.populate(bean,map); //将集合转化为对象
return bean;//返回对象
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/*
*测试toBean()
*/
public static void main(String[] args) {
Map map=new HashMap();
map.put("id", "1");
map.put("username", "ccc");
map.put("password", "fendou");
map.put("confirmpassword", "fendou");
map.put("email", "[email protected]");
map.put("phone", "1233333333");
map.put("aid", "1");
map.put("userid", "1");
map.put("addr", "sh");
map.put("remark", "mmmmmm");
User user=toBean(map,User.class);//将map集合转换成User对象
System.out.println("user=="+user);
Address address=toBean(map,Address.class);//将map集合转化成Address对象
System.out.println("address="+address);
user.setAddress(address);//关联两个表
System.out.println("user=="+user);
}
}
结果:
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.junit.Test;
import com.iotek.commons.jdbc.Dbutils;
import com.iotek.commons.jdbc.TxQueryRunner;
import com.iotek.commons.tools.CommonsTools;
import com.iotek.po.Address;
import com.iotek.po.User;
public class TestTxQueryRunner {
/**
*添加数据
*/
@Test
public void addUser() throws SQLException{
String sql="insert into tb_user(username,password,confirmpassword,email,phone) values(?,?,?,?,?)";
Object params[]={"kk","fendou","fendou","kk@qq","133333"};
QueryRunner qr=new TxQueryRunner();
int count=qr.update(sql,params);
System.out.println("count=="+count);
}
/*
* 使用事务实现添加数据
*/
@Test
public void addUser2() throws SQLException {
try {
Dbutils.beginTransaction(); //开启事务
//数据库插入数据语句
String sql="insert into tb_user(username,password,confirmpassword,email,phone) values(?,?,?,?,?)";
Object params[]={"uuu","fendou","fendou","uu@qq","14444"};
QueryRunner qr=new TxQueryRunner();
int count=qr.update(sql,params);//添加数据到数据库
System.out.println("count=="+count);//提交成功输出count==1
//当数据没有添加成功,抛出异常
if(count<0){
throw new Exception();
}
Dbutils.commitTransaction(); //提交事务
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
Dbutils.rollbackTransaction();
}
}
/**
*根据id查询数据
*/
@Test
public void testQuery1() throws SQLException{
String sql="select * from tb_user where id=?";
QueryRunner qr=new TxQueryRunner();
User user=qr.query(sql, new BeanHandler(User.class),1);
System.out.println("user=="+user);
}
/**
*查询所有数据
*/
@Test
public void testQuery2() throws SQLException{
String sql="select * from tb_user";
QueryRunner qr=new TxQueryRunner();
List users=qr.query(sql, new BeanListHandler(User.class));
System.out.println("users=="+users);
}
/**
*查询到的数据转成map对象
* @throws SQLException
*/
@Test
public void testQuery3() throws SQLException{
String sql="select * from tb_user where id=?";
QueryRunner qr=new TxQueryRunner();
Map map=qr.query(sql, new MapHandler(),1);
System.out.println("map=="+map);
}
/**
* 将查询到map对象放到list集合当中
* @throws SQLException
*/
@Test
public void testQuery4() throws SQLException{
String sql="select * from tb_user";
QueryRunner qr=new TxQueryRunner();
List
addUser()结果
testQuery3()结果
testQuery6()结果:多表查询