引入依赖,及数据库驱动包,我的是mysql和sqlserver
<!-- hutool工具类,几乎包含所以通用方法 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2.4</version>
</dependency>
然后在根路径创建db.setting文件,这个是hutool工具栏提供的数据库配置文件,详情请看官网
https://www.hutool.cn/docs/#/db/%E6%A6%82%E8%BF%B0
配置文件内容:
#------------------------------------------------------------------------------------------
## 可选配置
# 是否在日志中显示执行的SQL
showSql = true
# 是否格式化显示的SQL
formatSql = false
# 是否显示SQL参数
showParams = true
# 打印SQL的日志等级,默认debug
sqlLevel = debug
# 分组,若有多个数据源,使用此分组
[new_mysql_YingYew]
## 基本配置信息
# JDBC URL,根据不同的数据库,使用相应的JDBC连接字符串 &serverTimezone=UTC
url = jdbc:mysql://127.0.0.1:3306/数据库名?useUnicode=true&useSSL=false&characterEncoding=utf8
# 用户名,此处也可以使用 user 代替
username = 数据库用户名
# 密码,此处也可以使用 pass 代替
password = 数据库密码
# JDBC驱动名,可选(Hutool会自动识别)
driver = com.mysql.cj.jdbc.Driver
## 连接池配置项,这是HikariCP连接池配置,其它连接池请看官网配置
## https://www.hutool.cn/docs/#/db/%E6%95%B0%E6%8D%AE%E6%BA%90%E9%85%8D%E7%BD%AEdb.setting%E6%A0%B7%E4%BE%8B?id=%e5%9f%ba%e6%9c%ac%e9%85%8d%e7%bd%ae%e6%a0%b7%e4%be%8b
# 自动提交
autoCommit = true
# 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒
connectionTimeout = 30000
# 一个连接idle状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟
idleTimeout = 600000
# 一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒,参考MySQL wait_timeout参数(show variables like '%timeout%';)
maxLifetime = 1800000
# 获取连接前的测试SQL
connectionTestQuery = SELECT 1
# 最小闲置连接数
minimumIdle = 10
# 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
maximumPoolSize = 10
# 连接只读数据库时配置为true, 保证安全
readOnly = false
# 分组,若有多个数据源,使用此分组
[sqlserver__YingYew]
## 基本配置信息
# JDBC URL,根据不同的数据库,使用相应的JDBC连接字符串
url = jdbc:jtds:sqlserver://sqlserver的ip地址:1437;database=数据库名
# 用户名,此处也可以使用 user 代替
username = 数据库用户名
# 密码,此处也可以使用 pass 代替
password = 数据库密码
# JDBC驱动名,可选(Hutool会自动识别)
driver = net.sourceforge.jtds.jdbc.Driver
## 连接池配置项
# 自动提交
autoCommit = true
# 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒
connectionTimeout = 30000
# 一个连接idle状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟
idleTimeout = 600000
# 一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒,参考MySQL wait_timeout参数(show variables like '%timeout%';)
maxLifetime = 1800000
# 获取连接前的测试SQL
connectionTestQuery = SELECT 1
# 最小闲置连接数
minimumIdle = 10
# 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
maximumPoolSize = 10
# 连接只读数据库时配置为true, 保证安全
readOnly = false
# 分组,若有多个数据源,使用此分组
[old_mysql_YingYew]
## 基本配置信息
# JDBC URL,根据不同的数据库,使用相应的JDBC连接字符串
url = jdbc:mysql://数据库的ip:3306/数据库名?useUnicode=true&characterEncoding=utf8
# 用户名,此处也可以使用 user 代替
username = 数据库用户名
# 密码,此处也可以使用 pass 代替
password = 数据库密码
# JDBC驱动名,可选(Hutool会自动识别)
driver = com.mysql.cj.jdbc.Driver
## 连接池配置项
# 自动提交
autoCommit = true
# 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒
connectionTimeout = 30000
# 一个连接idle状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟
idleTimeout = 600000
# 一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒,参考MySQL wait_timeout参数(show variables like '%timeout%';)
maxLifetime = 1800000
# 获取连接前的测试SQL
connectionTestQuery = SELECT 1
# 最小闲置连接数
minimumIdle = 10
# 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
maximumPoolSize = 10
# 连接只读数据库时配置为true, 保证安全
readOnly = false
然后就是封装的代码工具类
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.ds.DSFactory;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author 影耀子YingYew
* @Description: 封装的执行灵活sql的工具类
* @ClassName: NimbleSql
* @date 2022/7/13 14:02
*/
@Slf4j
public class HutoolDbUtil {
public static String NEW_MYSQL_YINGYEW = "new_mysql_YingYew"; // 数据源分组名,新的mysql8
public static String SQLSERVER_YINGYEW = "sqlserver_YingYew"; // 数据源分组名,sqlserver
public static String OLD_MYSQL_YINGYEW = "old_mysql_YingYew"; // 数据源分组名,旧的mysql数据库
/**
* 查询并封装实体
* @param group
* @param beanClass
* @param sql
* @param parameter 可以为null
* @param <T>
* @return
*/
public static <T> List<T> queryGroup(String group, Class<T> beanClass, String sql, Object... parameter){
try {
return Db.use(group).query(sql,beanClass, parameter);
} catch (SQLException e) {
log.info(e.getMessage());
e.printStackTrace();
}
return null;
}
/**
* 查询并封装实体
* @param beanClass
* @param sql
* @param parameter 可以为null
* @param <T>
* @return
*/
public static <T> List<T> query(Class<T> beanClass, String sql, Object... parameter){
return queryGroup(NEW_MYSQL_YINGYEW,beanClass,sql,parameter);
}
/**
* 查询
* @param group 分组名
* @param sql 查询的sql,如select * from user where age < ?
* @param parameter 参数值
*/
public static List<Entity> queryGroup(String group,String sql,Object... parameter){
List<Entity> query = null;
try {
query = Db.use(group).query(sql, parameter);
} catch (SQLException e) {
log.info(e.getMessage());
e.printStackTrace();
}
return query;
}
/**
* 查询分组为new_mysql_YingYew 的数据库
* @param sql 查询的sql,如select * from user where age < ?
* @param parameter 参数值
*/
public static List<Entity> query(String sql,Object... parameter){
return queryGroup(NEW_MYSQL_YINGYEW,sql,parameter);
}
public static Entity queryOne(String sql,Object... params){
return queryOneGroup(NEW_MYSQL_YINGYEW,sql,params);
}
public static Entity queryOneGroup(String group,String sql,Object... params){
try {
return Db.use(group).queryOne(sql,params);
} catch (SQLException e) {
log.info(e.getMessage());
e.printStackTrace();
}
return null;
}
public static <T> T queryOneGroup(Class<T> beanClass, String group, String sql, Object... params){
Entity entity = queryOneGroup(group,sql,params);
return BeanUtil.toBean(entity, beanClass);
}
public static <T> T queryOne(Class<T> beanClass, String sql, Object... params){
return queryOneGroup(beanClass,NEW_MYSQL_YINGYEW,sql,params);
}
/**
* 增删改调用此方法
* @param sql
* @param parameter
*/
public static int executeGroup(String group,String sql,Object... parameter){
int execute = 0;
try {
execute = Db.use(group).execute(sql, parameter);
} catch (SQLException e) {
log.info(e.getMessage());
e.printStackTrace();
}
return execute;
}
/**
* 增删改调用此方法,不指定分组名默认操作分组为new_mysql_YingYew的数据
* @param sql
* @param parameter
*/
public static int execute(String sql,Object... parameter){
return executeGroup(NEW_MYSQL_YINGYEW,sql,parameter);
}
/**
* obj 转 Entity
* @param obj
* @param tableName
* @return
*/
public static Entity objToEntity(Object obj,String tableName){
Entity entity = Entity.create(tableName);
try {
Class<?> claszz = obj.getClass();
// 遍历javaBean中所有属性
for (Field field: claszz.getDeclaredFields()) {
field.setAccessible(true);
String fieldName = field.getName();
Object value = field.get(obj);
if (value != null){
entity.set(fieldName,value);
}
}
} catch (Exception e) {
log.info(e.getMessage());
e.printStackTrace();
return null;
}
return entity;
}
/**
* Entity转列表
* Entity转实体调用 BeanUtil.toBean(entity, clazz);
* 满足数据库列名和实体名除了下划线无区别映射
* @param clazz
* @param entityList
* @param <T>
* @return
*/
public static <T> List<T> entityToObj(Class<T> clazz, List<Entity> entityList){
/*List<T> list = new ArrayList<>();
for (Entity entity : entityList) {
// Entity转实体
T t = BeanUtil.toBean(entity, clazz);
list.add(t);
}
return list;*/
return JSONUtil.toList(JSONUtil.toJsonStr(entityList), clazz);
}
}
该准备的都准备好了,接下来就是使用了,因为方法都是静态的,所以在静态方法中也可以使用,以下只是其中一个方法的使用,具体根据业务需求选择使用哪个方法即可:
// 查询第一页权限下的所有子权限
List<Entity> query = HutoolDbUtil.query(
"with recursive td as " +
"(select id,site_type,type,name,pid,code,api_method,api_url,weight from admin_permission where FIND_IN_SET(id,?)" +
"union all select c.id,c.site_type,c.type,c.name,c.pid,c.code,c.api_method,c.api_url,c.weight from " +
"admin_permission c,td where c.pid=td.id)" +
"select * from td ", ids.toString());