BaseDao的作用:减少代码的冗余,详细如下图:
一:maven项目中导入jar依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- 数据库连接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<!-- 数据库连接池 -->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.2</version>
</dependency>
<!--导入lombok-->
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.14</version>
<scope>provided</scope>
</dependency>
<!-- 日志相关jar -->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
二:导入数据库池,druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/数据库名?useUnicode=true&characterEncoding=utf8
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
三:封装数据库类
package com.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/*
1. 声明静态数据源成员变量
2. 创建连接池对象
3. 定义公有的得到数据源的方法
4. 定义得到连接对象的方法
5. 定义关闭资源的方法
*/
public class JdbcUtils {
// 1. 声明静态数据源成员变量
private static DataSource dataSource;
// 2. 创建连接池对象
static{
//获取配置文件数据
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
Properties properties = new Properties();
properties.load(in);
// 创建连接池,使用配置文件中的参数
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接
* @return 数据库连接对象
* @throws SQLException
*/
// 4. 定义得到连接对象的方法
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
/**
* 获取数据库连接池
* @return
*/
// 3. 定义公有的得到数据源的方法
public static DataSource getDataSource(){
return dataSource;
}
/**
* 释放资源
* @param statement 语句执行者
* @param conn 数据库连接对象
*/
// 6.重载关闭方法
public static void close(Statement statement,Connection conn){
try {
statement.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 5.定义关闭资源的方法
public static void close(Statement statement, Connection conn, ResultSet resultSet){
try {
if(statement != null){
statement.close();
}
if(conn != null){
conn.close();
}
if(resultSet != null){
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
四:封装BaseDao类
package com.dao;
import com.utils.JdbcUtils;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Slf4j
public class BaseDao<T> {
private Connection connection = null;
private PreparedStatement ps = null;
private ResultSet rs = null;
/**
* 更新数据
* Object... 可变参数,本质上是一个数组
* @param sql 修改的SQL语句
* @param objects 表达式 ? 的实例(参数)
* @return 更新的结果(正确返回1,错误返回 -1)
*/
public int update(String sql,Object... objects){
try {
connection = JdbcUtils.getConnection();
ps = connection.prepareStatement(sql);
if (objects != null){
for (int i = 0; i < objects.length; i++) {
ps.setObject(i+1,objects[i]);
}
}
return ps.executeUpdate();
} catch (SQLException e) {
log.error("BaseDao update sql:{},params:{},exception:{}",sql,objects,e);
e.printStackTrace();
}finally {
JdbcUtils.close(ps,connection);
}
// 错误时,返回 -1
return -1;
}
/**
* 查找全部
* @param sql 查找的SQL语句
* @param tClass 类对象
* @param objects 表达式 ? 的实例(参数)
* @return 查找结果(正确返回 list,错误返回 null)
*/
public List<T> queryList(String sql,Class<T> tClass,Object... objects){
ArrayList<T> list = new ArrayList<>();
try {
connection = JdbcUtils.getConnection();
ps = connection.prepareStatement(sql);
// 获取 ?表达式的完整值
if (objects != null){
for (int i = 0; i < objects.length; i++) {
ps.setObject(i+1,objects[i]);
}
}
// 执行 SQL,返回结果集
rs = ps.executeQuery();
// ResultSetMetaData类完成查询结果信息和查询结果中的各种列信息
ResultSetMetaData metaData = ps.getMetaData();
// 获取总条数(方便循环取值)
int columnCount = metaData.getColumnCount();
T t = null;
// 获取每一行的信息
while (rs.next()){
// 将类对象转换成 Object 对象
t = tClass.getConstructor().newInstance(); // 每次都应该拿一个新对象,在把新对象添加到集合里面
// 获取每条数据的信息
for (int i = 0; i < columnCount; i++) {
// 获得列名
String columnName = metaData.getColumnName(i + 1);
// 通过列名反射拿到 Filed 对象
Field field = tClass.getDeclaredField(columnName);
// 暴力获取(不用考虑修饰符)
field.setAccessible(true);
// 注意:不同的属性,具有不同的类型,那么在跟不同的类型赋值的时候,需要进行判断
// 给属性赋值
// i,rs ----> rs.getString(),i 作为里面的下标,rs 获得值然后赋给 filed
setFiledValue(field,t,i,rs);
}
if (list != null){
list.add(t);
}
}
// 判断返回的类型
if(list != null){
//查询集合
return list;
}else{
//单个对象
return (List<T>) t;
}
} catch (Exception e) {
log.error("BaseDao update sql:{},params:{},exception:{}",sql,objects,e);
e.printStackTrace();
} finally {
JdbcUtils.close(ps,connection);
}
return null;
}
/**
* 判断赋值的类型
* @param field 字段对象
* @param t 对象
* @param i 列下标
* @param rs 结果集
*/
private void setFiledValue(Field field, T t, int i, ResultSet rs) {
try {
String typeName = field.getType().getName();
if (typeName.equals(int.class.getName()) || typeName.equals(Integer.class.getName())){
field.set(t,Integer.valueOf(rs.getObject(i + 1).toString()));
}else if (typeName.equals(String.class.getName())){
field.set(t,rs.getObject(i + 1).toString());
}else if (typeName.equals(Date.class.getName())){
field.set(t,new Date(rs.getObject(i + 1).toString()));
}else if (typeName.equals(double.class.getName()) || typeName.equals(Double.class.getName())){
field.set(t,Double.valueOf(rs.getObject(i + 1).toString()));
}else {
field.set(t,rs.getObject(i + 1));
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 统计个数
* @param sql 查找的SQL语句
* @param objects 表达式 ? 的实例(参数)
* @return
*/
public Long queryCount(String sql,Object... objects){
try {
connection = JdbcUtils.getConnection();
ps = connection.prepareStatement(sql);
if (objects != null){
for (int i = 0; i < objects.length; i++) {
ps.setObject(i+1,objects[i]);
}
}
rs = ps.executeQuery();
while (rs.next()){
return rs.getLong(1);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.close(ps,connection);
}
return -1L;
}