一、连接数据库,获取连接
package org.lanqiao.util;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class DataUtil {
//设置数据库连接池
public static final ComboPooledDataSource cpds = new ComboPooledDataSource();
//初始化
static{
try {
//读取连接数据库的信息
InputStream is = new FileInputStream("jdbcinfo.config");
Properties pp = new Properties();
pp.load(is);
is.close();
//获取连接数据库的信息
String user = pp.getProperty("user");
String pwd = pp.getProperty("pwd");
String url = pp.getProperty("url");
String driver = pp.getProperty("driver");
//设置连接数据库的信息
cpds.setUser(user);
cpds.setPassword(pwd);
cpds.setJdbcUrl(url);
cpds.setDriverClass(driver);
cpds.setMaxPoolSize(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接池里面的连接
* @return
*/
public static Connection getConnection() {
try {
return cpds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
二、创建实体类Dog
package org.lanqiao.entity;
import java.time.LocalDate;
public class Dog {
private int id;
private String name;
private int age;
private LocalDate brith;
private String city;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public LocalDate getBrith() {
return brith;
}
public void setBrith(LocalDate brith) {
this.brith = brith;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Dog(int id, String name, int age, LocalDate brith, String city) {
super();
this.id = id;
this.name = name;
this.age = age;
this.brith = brith;
this.city = city;
}
public Dog() {
super();
}
@Override
public String toString() {
return "Dog [id=" + id + ", name=" + name + ", age=" + age + ", brith=" + brith + ", city=" + city + "]";
}
}
三、通用版的增删改查(单表)
package org.lanqiao.dao;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.lanqiao.util.DataUtil;
public abstract class BaseDao<T> {
/**
* 查询
*
* @throws SQLException
*/
protected List<T> getAll(String sql, Object... args) throws SQLException {
List<T> ts = new ArrayList<>();
// 连接 一样
Connection conn = DataUtil.getConnection();
// sql 不用
// prepareStatement 一样
PreparedStatement ps = conn.prepareStatement(sql);
// 填充占位符 相似
for (int i = 0; i < args.length; i++) {
ps.setObject((i + 1), args[i]);
}
// 执行sql 一样
ResultSet rs = ps.executeQuery();
// 获取元数据
ResultSetMetaData rsmd = rs.getMetaData();
// 通过元数据获取列的数量
int columnCount = rsmd.getColumnCount();
// 处理结果集 相似
while (rs.next()) {
// 创建对象
T t = null;
// 获取带泛型的父类
Type genericSuperclass = this.getClass().getGenericSuperclass();
// 强转为带泛型的父类类型
ParameterizedType pt = (ParameterizedType) genericSuperclass;
// 取出泛型
Type[] actualTypeArguments = pt.getActualTypeArguments();
// 取出第0个泛型
Type type = actualTypeArguments[0];
// 泛型的类型
Class c = (Class) type;
// 创建对象
try {
t = (T) c.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
// 取出所有的字段
Field[] fields = c.getDeclaredFields();
// 遍历列
for (int i = 1; i <= columnCount; i++) {
// 取出列的值
Object value = rs.getObject(i);
// 取出表中当前列的字段名
String columnName = rsmd.getColumnLabel(i);
// set属性值
Field f = null;
// 取出相应的字段
for (Field field : fields) {
// 类中字段名
String fieldName = field.getName();
// 找到列名和类中相同的字段
if (columnName.equalsIgnoreCase(fieldName)) {
f = field;
}
}
// 设置为可以修改字段
if (f != null) {
f.setAccessible(true);
try {
// 单独处理日期
if (value instanceof Date) {
f.set(t, ((Date) value).toLocalDate());
} else {
// 设置值
f.set(t, value);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
ts.add(t);
}
// 关闭连接 一样
ps.close();
rs.close();
conn.close();
return ts;
}
/**
* 增删改
*
* @param sql
* @param args
* @throws SQLException
*/
protected void update(String sql, Object... args) throws SQLException {
// 准备连接 一样的
Connection conn = DataUtil.getConnection();
// 准别sql 不一样(传进来的)
// 创建prepareStatement 一样的
PreparedStatement ps = conn.prepareStatement(sql);
// 填充占位符 相似的
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
// 执行sql 一样的
ps.executeUpdate();
// 关闭连接 一样的
conn.close();
}
}
四、调用方法,传入sql语句和需要设置的值
package org.lanqiao.dao;
import java.sql.SQLException;
import java.util.List;
import org.lanqiao.entity.Dog;
public class DogDao extends BaseDao<Dog>{
//查找多个
public List<Dog> getAll() throws SQLException{
String sql = "select id,name,age,dogBrith as brith,city from dogs";
return getAll(sql);
}
//查找一个
public Dog get(int id) throws SQLException {
String sql = "select id,name,age,dogBrith as brith,city from dogs where id = ?";
return getAll(sql, id).get(0);
}
//删除
public void delete(int id) throws SQLException {
String sql = "delete from dogs where id=?";
update(sql, id);
}
//修改
public void update(Dog d) throws SQLException {
String sql = "update dogs set name=?,age=?,dogBrith=?,city=? where id=?";
update(sql, d.getName(),d.getAge(),d.getBrith(),d.getCity(),d.getId());
}
//增加
public void insert(Dog d) throws SQLException {
String sql = "insert into dogs(name,age,dogBrith,city) values(?,?,?,?)";
update(sql, d.getName(),d.getAge(),d.getBrith(),d.getCity());
}
}