使用数据库连接池技术
自己手写连接池
使用三方库
DBCP (有Bug)
C3P0 (速度太慢)
Druid (阿里巴巴)
BoneCP
HikariCP
Druid连接池
商品数据库面向接口编程设计
.properties属性文件
1.专门用于软件中编写配置参数的
2.格式是 属性名=属性值
建立一个Druid连接池工具类
package com.iweb.shop.dao;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class ConnectionUtil {
private static DataSource dataSource;//接口类型没有写死
static {// 类加载的时候自动执行静态代码块,调用init方法
init();//会初始化连接池
}
private static void init(){
// //database.properties
//# .properties 属性文件
//#1.专门用于软件中编写配置参数的
//#2.格式是 属性名=属性值 不用加双引号
Properties properties = new Properties(); //用于读properties 文件的对象
try {
// properties.load() 加载属性文件,参数是属性文件的输入流
properties.load(ConnectionUtil.class.getClassLoader().getResourceAsStream("database.properties"));
// DruidDataSourceFactory.createDataSource() 使用三方库创建连接池对象,参数是properties
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 连接池dataSource 被 private 私有化,连接池初始化的过程对外不可见
* 暴露一个公有的方法给外部获取连接对象
* 外界 ConnectionUtil.getConnection()
*/
public static Connection getConnection(){
try {
return dataSource.getConnection(); //取连接池错误的话就为空
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
}
建立个测试类测试连接
建立Dao 父类,封装增删改查操作
package com.iweb.shop.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
/**
* Dao 父类,封装增删改查操作
*/
public class BaseDao {
protected Connection conn;//有参构造方法
public BaseDao (Connection conn){
this.conn = conn ;
}
/**
* 封装增删改操作,该方法可以被子类直接调用,返回受影响行数
*/
protected int update(String sql, List <Object> params){
try {
//预编译SQL语句
PreparedStatement ps = conn.prepareStatement(sql);
//为SQL中的 ? 填入参数
if (params != null && params.size()>0){
for (int i = 0; i < params.size(); i++) {
ps.setObject((i+1),params.get(i));
}
}
int rows = ps.executeUpdate();
return rows;
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
}
建立一个UserDao接口,暴露给上层工厂调用
package com.iweb.shop.dao;
import com.iweb.shop.dao.impl.UserDaoImpl;
import com.iweb.shop.entity.User;
import java.sql.Connection;
public interface UserDao {
/**
*暴露给你上层调用插入一个用户到数据库的方法
* 参数是一个User对象
* 返回值int代表受影响的行数
*/
int insert(User user);
/**
*静态工厂方法,提供给上层的
*/
static UserDao getInstance(Connection conn){
return new UserDaoImpl(conn);
}
}
建立一个UserDaoIml实现类,完成操作的实现
是UserDao的具体实现不暴露给上层,而是将UserDao接口暴露给上层调用。
package com.iweb.shop.dao.impl;
import com.iweb.shop.dao.BaseDao;
import com.iweb.shop.dao.UserDao;
import com.iweb.shop.entity.User;
import org.apache.commons.codec.digest.DigestUtils;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class UserDaoImpl extends BaseDao implements UserDao {
public UserDaoImpl(Connection conn) {//此时子类没有构造方法,调用父类的无参构造方法,父类只有有参构造方法 ,只能super(conn)
super(conn);
}
@Override
public int insert(User user) {//用user 来替换????? 形式参数
String sql = "insert into user(username,password,sex,mobile,id_code) values(?,?,?,?,?) ";
List<Object> params = new ArrayList<>();
// //第一种
// params.add(user.getUsername());
// params.add(user.getPassword());
// params.add(user.getSex());
// params.add(user.getMobile());
// params.add(user.getIdCode());
// super.update(sql,params);
//第二种
return super.update(sql, Arrays.asList(new Object[]{user.getUsername(), DigestUtils.md5Hex(user.getPassword())
,user.getSex(),user.getMobile(),user.getIdCode()}));
}
}
测试
建立一个BaseEntity
package com.iweb.shop.entity;
//实体类 -- 和数据库一一映射
public class BaseEntity {
private Integer id;
private Integer isDelete;
private String createDate;
private String modifyDate;
@Override
public String toString() {
return "BaseEntity{" +
"id=" + id +
", isDelete=" + isDelete +
", createDate='" + createDate + '\'' +
", modifyDate='" + modifyDate + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getIsDelete() {
return isDelete;
}
public void setIsDelete(Integer isDelete) {
this.isDelete = isDelete;
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate;
}
public String getModifyDate() {
return modifyDate;
}
public void setModifyDate(String modifyDate) {
this.modifyDate = modifyDate;
}
}
定义一个具体实体类,要与具体数据库一一映射
package com.iweb.shop.entity;
public class User extends BaseEntity{
private String username;
private String password;
private String avatar;
private String sex;
private String mobile;
private String idCode;
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", avatar='" + avatar + '\'' +
", sex='" + sex + '\'' +
", mobile='" + mobile + '\'' +
", idCode='" + idCode + '\'' +
'}';
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getIdCode() {
return idCode;
}
public void setIdCode(String idCode) {
this.idCode = idCode;
}
}
测试
package com.iweb.shop.test;
import com.iweb.shop.dao.ConnectionUtil;
import com.iweb.shop.dao.UserDao;
import com.iweb.shop.entity.User;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.Test;
import java.sql.Connection;
public class UserDaoTest {
@Test
public void test01(){
Connection conn = ConnectionUtil.getConnection();//1.‘向连接池要一个连接对象
UserDao userDao = UserDao.getInstance(conn);//2.调用接口的静态工厂方法拿到UserDao对象
User user = new User();//3.准备测试数据
user.setUsername("测试用户aa");
user.setPassword("测试密码");
user.setSex("男");
user.setMobile("15915915959");
user.setIdCode("320123199912124545");
int rows = userDao.insert(user);
System.out.println(rows != -1 ? "插入成功!" : "插入失败");
}
}