All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.dromara.hutool.db.DaoTemplate Maven / Gradle / Ivy
/*
* Copyright (c) 2013-2024 Hutool Team and hutool.cn
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.hutool.db;
import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.db.ds.DSUtil;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.List;
/**
* 数据访问层模板
* 此模板用于简化对指定表的操作,简化的操作如下:
*
* 1、在初始化时指定了表名,CRUD操作时便不需要表名
* 2、在初始化时指定了主键,某些需要主键的操作便不需要指定主键类型
*
*
* @author Looly
*/
public class DaoTemplate {
/**
* 表名
*/
protected String tableName;
/**
* 本表的主键字段,请在子类中覆盖或构造方法中指定,默认为id
*/
protected String primaryKeyField = "id";
/**
* SQL运行器
*/
protected Db db;
// region ----- Constructor
/**
* 构造,此构造需要自定义SqlRunner,主键默认为id
*
* @param tableName 数据库表名
*/
public DaoTemplate(final String tableName) {
this(tableName, (String) null);
}
/**
* 构造,使用默认的池化连接池,读取默认配置文件的空分组,适用于只有一个数据库的情况
*
* @param tableName 数据库表名
* @param primaryKeyField 主键字段名
*/
public DaoTemplate(final String tableName, final String primaryKeyField) {
this(tableName, primaryKeyField, DSUtil.getDS());
}
/**
* 构造
*
* @param tableName 表
* @param ds 数据源
*/
public DaoTemplate(final String tableName, final DataSource ds) {
this(tableName, null, ds);
}
/**
* 构造
*
* @param tableName 表名
* @param primaryKeyField 主键字段名
* @param ds 数据源
*/
public DaoTemplate(final String tableName, final String primaryKeyField, final DataSource ds) {
this(tableName, primaryKeyField, Db.of(ds));
}
/**
* 构造
*
* @param tableName 表名
* @param primaryKeyField 主键字段名
* @param db Db对象
*/
public DaoTemplate(final String tableName, final String primaryKeyField, final Db db) {
this.tableName = tableName;
if (StrUtil.isNotBlank(primaryKeyField)) {
this.primaryKeyField = primaryKeyField;
}
this.db = db;
}
// endregion
// region ----- Add
/**
* 添加
*
* @param entity 实体对象
* @return 插入行数
* @throws DbException SQL执行异常
*/
public int add(final Entity entity) throws DbException {
return db.insert(fixEntity(entity));
}
/**
* 添加
*
* @param entity 实体对象
* @return 主键列表
* @throws DbException SQL执行异常
*/
public List addForGeneratedKeys(final Entity entity) throws DbException {
return db.insertForGeneratedKeys(fixEntity(entity));
}
/**
* 添加
*
* @param entity 实体对象
* @return 自增主键
* @throws DbException SQL执行异常
*/
public Long addForGeneratedKey(final Entity entity) throws DbException {
return db.insertForGeneratedKey(fixEntity(entity));
}
// endregion
// region ----- Delete
/**
* 删除
*
* @param 主键类型
* @param pk 主键
* @return 删除行数
* @throws DbException SQL执行异常
*/
public int del(final T pk) throws DbException {
if (pk == null) {
return 0;
}
return this.del(Entity.of(tableName).set(primaryKeyField, pk));
}
/**
* 删除
*
* @param 主键类型
* @param field 字段名
* @param value 字段值
* @return 删除行数
* @throws DbException SQL执行异常
*/
public int del(final String field, final T value) throws DbException {
if (StrUtil.isBlank(field)) {
return 0;
}
return this.del(Entity.of(tableName).set(field, value));
}
/**
* 删除
*
* @param where 删除条件,当条件为空时,返回0(防止误删全表)
* @return 删除行数
* @throws DbException SQL执行异常
*/
public int del(final Entity where) throws DbException {
if (MapUtil.isEmpty(where)) {
return 0;
}
return db.del(fixEntity(where));
}
// endregion
// region ----- Update
/**
* 按照条件更新
*
* @param record 更新的内容
* @param where 条件
* @return 更新条目数
* @throws DbException SQL执行异常
*/
public int update(final Entity record, final Entity where) throws DbException {
if (MapUtil.isEmpty(record)) {
return 0;
}
return db.update(fixEntity(record), where);
}
/**
* 更新
*
* @param entity 实体对象,必须包含主键
* @return 更新行数
* @throws DbException SQL执行异常
*/
public int update(Entity entity) throws DbException {
if (MapUtil.isEmpty(entity)) {
return 0;
}
entity = fixEntity(entity);
final Object pk = entity.get(primaryKeyField);
if (null == pk) {
throw new DbException(StrUtil.format("Please determine `{}` for update", primaryKeyField));
}
final Entity where = Entity.of(tableName).set(primaryKeyField, pk);
final Entity record = entity.clone();
record.remove(primaryKeyField);
return db.update(record, where);
}
/**
* 增加或者更新实体
*
* @param entity 实体,当包含主键时更新,否则新增
* @return 新增或更新条数
* @throws DbException SQL执行异常
*/
public int addOrUpdate(final Entity entity) throws DbException {
return null == entity.get(primaryKeyField) ? add(entity) : update(entity);
}
// endregion
//region ----- Get
/**
* 根据主键获取单个记录
*
* @param 主键类型
* @param pk 主键值
* @return 记录
* @throws DbException SQL执行异常
*/
public Entity get(final T pk) throws DbException {
return this.get(primaryKeyField, pk);
}
/**
* 根据某个字段(最好是唯一字段)查询单个记录
* 当有多条返回时,只显示查询到的第一条
*
* @param 字段值类型
* @param field 字段名
* @param value 字段值
* @return 记录
* @throws DbException SQL执行异常
*/
public Entity get(final String field, final T value) throws DbException {
return this.get(Entity.of(tableName).set(field, value));
}
/**
* 根据条件实体查询单个记录,当有多条返回时,只显示查询到的第一条
*
* @param where 条件
* @return 记录
* @throws DbException SQL执行异常
*/
public Entity get(final Entity where) throws DbException {
return db.get(fixEntity(where));
}
// endregion
// region ----- Find and page
/**
* 根据某个字段值查询结果
*
* @param 字段值类型
* @param field 字段名
* @param value 字段值
* @return 记录
* @throws DbException SQL执行异常
*/
public List find(final String field, final T value) throws DbException {
return this.find(Entity.of(tableName).set(field, value));
}
/**
* 查询当前表的所有记录
*
* @return 记录
* @throws DbException SQL执行异常
*/
public List findAll() throws DbException {
return this.find(Entity.of(tableName));
}
/**
* 根据某个字段值查询结果
*
* @param where 查询条件
* @return 记录
* @throws DbException SQL执行异常
*/
public List find(final Entity where) throws DbException {
return db.find(null, fixEntity(where));
}
/**
* 根据SQL语句查询结果
* SQL语句可以是非完整SQL语句,可以只提供查询的条件部分(例如WHERE部分)
* 此方法会自动补全SELECT * FROM [tableName] 部分,这样就无需关心表名,直接提供条件即可
*
* @param sql SQL语句
* @param params SQL占位符中对应的参数
* @return 记录
* @throws DbException SQL执行异常
*/
public List findBySql(String sql, final Object... params) throws DbException {
final String selectKeyword = StrUtil.subPre(sql.trim(), 6).toLowerCase();
if (!"select".equals(selectKeyword)) {
sql = "SELECT * FROM " + this.tableName + " " + sql;
}
return db.query(sql, params);
}
/**
* 分页
*
* @param where 条件
* @param page 分页对象
* @param selectFields 查询的字段列表
* @return 分页结果集
* @throws DbException SQL执行异常
*/
public PageResult page(final Entity where, final Page page, final String... selectFields) throws DbException {
return db.page(Arrays.asList(selectFields), fixEntity(where), page);
}
/**
* 分页
*
* @param where 条件
* @param page 分页对象
* @return 分页结果集
* @throws DbException SQL执行异常
*/
public PageResult page(final Entity where, final Page page) throws DbException {
return db.page(fixEntity(where), page);
}
/**
* 满足条件的数据条目数量
*
* @param where 条件
* @return 数量
* @throws DbException SQL执行异常
*/
public long count(final Entity where) throws DbException {
return db.count(fixEntity(where));
}
/**
* 指定条件的数据是否存在
*
* @param where 条件
* @return 是否存在
* @throws DbException SQL执行异常
*/
public boolean exist(final Entity where) throws DbException {
return this.count(where) > 0;
}
// endregion
/**
* 修正Entity对象,避免null和填充表名
*
* @param entity 实体类
* @return 修正后的实体类
*/
private Entity fixEntity(Entity entity) {
if (null == entity) {
entity = Entity.of(tableName);
} else if (StrUtil.isBlank(entity.getTableName())) {
entity.setTableName(tableName);
}
return entity;
}
}