读配置文件
配置文件名为jdbc.properties
-
创建dataSource和ThreadLock【】
private static DataSource dataSource; private static final ThreadLocal<Connection> ts = new ThreadLocal<>();
-
读取配置文件【】
InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
-
加载配置没见【】
Properties ps = new Properties(); ps.load(is);
-
联接datasource【】
dataSource = DruidDataSourceFactory.createDataSource(ps);
书写工具方法jdbcutil
interface jdbcutil{
public static Connection getConnection();//获取数据库连接
public static PreparedStatement createPreparedStatement(String sql, Object... params) ;//由于PreparedStatement 既有预加载的性能可以提高速度,但是由于加载sql语句是insertinto tb_user values(?,?,?,...);的形式,故需要将params里面的值一一赋值;
public static ResultSet executeQuery(String sql, Object... params);//获取数据库数据的方法,返回结果集 (ResultSet);
public static int executeUpdate(String sql, Object... params);//数据库增删改的操作,返回值是一个影响数据库行数的值;
public static void releaseConnection();//关闭连接,实际是将数据库连接归还数据池
}
实体类
public class JdbcUtil implement jdbcutil{
private JdbcUtil() {
}
private static DataSource dataSource;
private static final ThreadLocal<Connection> ts = new ThreadLocal<>();
static {
try {
InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties ps = new Properties();
ps.load(is);
dataSource = DruidDataSourceFactory.createDataSource(ps);
} catch (Exception e) {
e.printStackTrace();
}
}
//数据库增删改的操作,返回值是一个影响数据库行数的值;
public static int executeUpdate(String sql, Object... params) {
try {
return createPreparedStatement(sql, params).executeUpdate();
} catch (
Exception e) {
throw new RuntimeException(e.getMessage());
}
}
//获取数据库数据的方法,返回结果集
public static ResultSet executeQuery(String sql, Object... params) {
try {
return createPreparedStatement(sql, params).executeQuery();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
//由于PreparedStatement 既有预加载的性能可以提高速度,但是由于加载sql语句是insertinto tb_user values(?,?,?,...);的形式,故需要将params里面的值一一赋值;
public static PreparedStatement createPreparedStatement(String sql, Object... params) {
try {
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
if (params != null && params.length > 0)
for (int i = 0; i < params.length; i++)
ps.setObject(i + 1, params[i]);
return ps;
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
// 获取连接的方法
public static Connection getConnection() {
Connection res = ts.get();
if (res == null) {
try {
res = dataSource.getConnection();
ts.set(res);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
return res;
}
// 释放连接的方法
public static void releaseConnection() {
Connection conn = ts.get();
if (conn != null) {
try {
conn.close();
ts.remove();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}
}
DAO模式
-
basedao接口dao类//定义数据库基本功能的接口【】
public interface IBaseDao<T extends Serializable> { public int save(T t); public int delete(T t); public int update(T t); public List<T> findByExample(T t); 【 //第一步获取调用new对象的Class反射类队形,以便于寻找数据库里面对应的表,进行数据操作 private Class<T> clazz; public BaseDaoImpl() { Class<? extends IBaseDao> clz = this.getClass(); Type type = clz.getGenericSuperclass(); // ParameterizedType参数化类型,即泛型 ParameterizedType p = (ParameterizedType) type; // getActualTypeArguments获取参数化类型的数组,泛型可能有多个 clazz = (Class) p.getActualTypeArguments()[0]; System.out.println(clazz); } //第二步建立list集合来记录T类型里面的值,主要作用是为了给sql语句里面的参数(?)进行替换赋值 List<Object> params = new ArrayList<>(); //第三步利用反射获取实体类里面的属性, Field[] fs = clazz.getDeclaredFields(); //第四步建立需要的sql语句,并根据第三获取属性里面的值; StringBuilder sb = new StringBuilder("select * from tb_"); sb.append(clazz.getSimpleName().toLowerCase()).append(" where 1=1 "); for (int i = 1; i < fs.length; i++) { Field f = fs[i]; f.setAccessible(true); Object val = f.get(obj); if (val != null) { sb.append(" and ").append(f.getName()).append("=? "); params.add(val); } } ResultSet rs = JdbcUtil.executeQuery(sb.toString(), params.toArray()); //第五步根据结果集返回数据库里面的数据,利用反射,进行赋值返回到list while (rs.next()) { ResultSetMetaData rsmd = rs.getMetaData(); T t = clazz.newInstance(); for (int i = 1; i <= rsmd.getColumnCount(); i++) { String fieldName = rsmd.getColumnLabel(i); Field f = clazz.getDeclaredField(fieldName); f.setAccessible(true); f.set(t, rs.getObject(i)); } res.add(t); } rs.close(); 】 }
-
basedaolmp实现basedao的dao类//实现定义数据库基本功能的类
public abstract class BaseDaoImpl<T extends Serializable> implements IBaseDao<T> { }
-
userdao实体dao类//实现basedao接口功能并且含有自己独有的功能的具体接口
public interface IUserDao extends IBaseDao<User>{ //如果有userDao中需要添加的特殊方法,声明在这里 }
-
userdaoImp实现实体类的dao类//实现具体类的功能的实现类
public class UserDaoImpl extends BaseDaoImpl<User> implements IUserDao { // 如果有特殊方法,则在这里实现,实际上通用的CRUD方法已经从BaseDao中继承 }
-
(User)具体类//注意要和数据库表的类名要一样
public class User implements Serializable { private static final long serialVersionUID = 4118906006740949960L; private Long id; private String username; private String password; }
-
factorydao工厂类//在一个类的时候就可以不要这个,但是当有多个实体dao类的时候就需要这个工厂类
public class DaoFactory {
public static UserDaoImpl getUserDao1(String clzz) {
String key = clzz;
switch (key) {
case "user":
return new UserDaoImpl();
case "book":
return new bookDaoImpl();
default:
return null;
}
}
}
7.测试类
IUserDao iuse = DaoFactory.getUserDao1("user");
User user = new User();
iuse.save(user);
iuse.delete(user);
iuse.update(user);
List list = iuse.findByExample(user);
System.out.println(list);