diff --git a/src/org/redkale/source/DistributeTable.java b/src/org/redkale/source/DistributeTable.java index 939adb385..c4345a256 100644 --- a/src/org/redkale/source/DistributeTable.java +++ b/src/org/redkale/source/DistributeTable.java @@ -10,6 +10,8 @@ import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** + * Entity分库分表的注解,需要结合DistributeTableStrategy使用
+ * 标记为 @DistributeTable的Entity类视为需要进行分库分表操作
* *

* 详情见: https://redkale.org diff --git a/src/org/redkale/source/DistributeTableStrategy.java b/src/org/redkale/source/DistributeTableStrategy.java index 9fdd58ae0..5bce05353 100644 --- a/src/org/redkale/source/DistributeTableStrategy.java +++ b/src/org/redkale/source/DistributeTableStrategy.java @@ -8,9 +8,9 @@ package org.redkale.source; import java.io.Serializable; /** - * 分表分库策略,结合@DistributeTable使用 - * 不能与@Cacheable同时使用 - * 使用分表分库功能重点是主键的生成策略,不同场景生成策略不一样 + * 分表分库策略,结合@DistributeTable使用
+ * 不能与@Cacheable同时使用
+ * 使用分表分库功能重点是主键的生成策略,不同场景生成策略不一样
* *

* 详情见: https://redkale.org @@ -21,8 +21,8 @@ import java.io.Serializable; public interface DistributeTableStrategy { /** - * 获取对象的表名 - * 查询单个对象(DataSource.find)时调用本方法获取表名 + * 获取对象的表名
+ * 查询单个对象(DataSource.find)时调用本方法获取表名
* * @param table 模板表的表名 * @param primary 记录主键 @@ -32,9 +32,20 @@ public interface DistributeTableStrategy { public String getTable(String table, Serializable primary); /** - * 获取对象的表名 - * 查询、修改、删除对象(DataSource.find、DataSource.query、DataSource.delete、DataSource.update)时调用本方法获取表名 - * 注意: 需保证FilterNode过滤的结果集合必须在一个数据库表中 + * 获取对象的表名
+ * 新增对象或更新单个对象(DataSource.insert、DataSource.update)时调用本方法获取表名
+ * + * @param table 模板表的表名 + * @param bean 实体对象 + * + * @return 带库名的全表名 + */ + public String getTable(String table, T bean); + + /** + * 获取对象的表名
+ * 查询、修改、删除对象(DataSource.find、DataSource.query、DataSource.delete、DataSource.update)时调用本方法获取表名
+ * 注意: 需保证FilterNode过滤的结果集合必须在一个数据库表中
* * @param table 模板表的表名 * @param node 过滤条件 @@ -43,14 +54,4 @@ public interface DistributeTableStrategy { */ public String getTable(String table, FilterNode node); - /** - * 获取对象的表名 - * 新增对象或更新单个对象(DataSource.insert、DataSource.update)时调用本方法获取表名 - * - * @param table 模板表的表名 - * @param bean 实体对象 - * - * @return 带库名的全表名 - */ - public String getTable(String table, T bean); } diff --git a/src/org/redkale/source/EntityInfo.java b/src/org/redkale/source/EntityInfo.java index 9e93c826d..3bce9decd 100644 --- a/src/org/redkale/source/EntityInfo.java +++ b/src/org/redkale/source/EntityInfo.java @@ -53,6 +53,7 @@ public final class EntityInfo { //存放所有与数据库对应的字段, 包括主键 private final HashMap> attributeMap = new HashMap<>(); + //存放所有与数据库对应的字段, 包括主键 final Attribute[] attributes; //key是field的name, value是Column的别名,即数据库表的字段名 @@ -120,6 +121,15 @@ public final class EntityInfo { final BiFunction fullloader; //------------------------------------------------------------ + /** + * 加载EntityInfo + * + * @param type Entity类 + * @param cacheForbidden 是否禁用EntityCache + * @param conf 配置信息, persistence.xml中的property节点值 + * @param source DataSource,可为null + * @param fullloader 全量加载器,可为null + */ static EntityInfo load(Class clazz, final boolean cacheForbidden, final Properties conf, DataSource source, BiFunction fullloader) { EntityInfo rs = entityInfos.get(clazz); @@ -138,10 +148,27 @@ public final class EntityInfo { } } + /** + * 获取Entity类对应的EntityInfo对象 + * + * @param 泛型 + * @param clazz Entity类 + * + * @return EntityInfo + */ static EntityInfo get(Class clazz) { return entityInfos.get(clazz); } + /** + * 构造函数 + * + * @param type Entity类 + * @param cacheForbidden 是否禁用EntityCache + * @param conf 配置信息, persistence.xml中的property节点值 + * @param source DataSource,可为null + * @param fullloader 全量加载器,可为null + */ private EntityInfo(Class type, final boolean cacheForbidden, Properties conf, DataSource source, BiFunction fullloader) { this.type = type; @@ -284,92 +311,196 @@ public final class EntityInfo { this.tablecopySQL = conf.getProperty(JDBCPoolSource.JDBC_TABLECOPY_SQLTEMPLATE, "CREATE TABLE ${newtable} LIKE ${oldtable}"); } + /** + * 创建主键值,目前只支持UUID赋值 + * + * @param src Entity对象 + */ public void createPrimaryValue(T src) { if (autouuid) getPrimary().set(src, Utility.uuid()); } + /** + * 获取Entity缓存器 + * + * @return EntityCache + */ public EntityCache getCache() { return cache; } + /** + * 判断缓存器是否已经全量加载过 + * + * @return boolean + */ public boolean isCacheFullLoaded() { return cache != null && cache.isFullLoaded(); } + /** + * 获取Entity构建器 + * + * @return Creator + */ public Creator getCreator() { return creator; } + /** + * 获取Entity类名 + * + * @return Class + */ public Class getType() { return type; } /** - * 是否虚拟类 + * 判断Entity是否为虚拟类 * - * @return 是否虚拟类 + * @return boolean */ public boolean isVirtualEntity() { return table == null; } + /** + * 获取Entity的INSERT SQL + * + * @param bean Entity对象 + * + * @return String + */ public String getInsertSQL(T bean) { if (this.tableStrategy == null) return insertSQL; return insertSQL.replace("${newtable}", getTable(bean)); } + /** + * 获取Entity的UPDATE SQL + * + * @param bean Entity对象 + * + * @return String + */ public String getUpdateSQL(T bean) { if (this.tableStrategy == null) return updateSQL; return updateSQL.replace("${newtable}", getTable(bean)); } + /** + * 获取Entity的DELETE SQL + * + * @param bean Entity对象 + * + * @return String + */ public String getDeleteSQL(T bean) { if (this.tableStrategy == null) return deleteSQL; return deleteSQL.replace("${newtable}", getTable(bean)); } + /** + * 根据主键值获取Entity的表名 + * + * @param primary Entity主键值 + * + * @return String + */ public String getTable(Serializable primary) { if (tableStrategy == null) return table; String t = tableStrategy.getTable(table, primary); return t == null || t.isEmpty() ? table : t; } + /** + * 根据过滤条件获取Entity的表名 + * + * @param node 过滤条件 + * + * @return String + */ public String getTable(FilterNode node) { if (tableStrategy == null) return table; String t = tableStrategy.getTable(table, node); return t == null || t.isEmpty() ? table : t; } + /** + * 根据Entity对象获取Entity的表名 + * + * @param bean Entity对象 + * + * @return String + */ public String getTable(T bean) { if (tableStrategy == null) return table; String t = tableStrategy.getTable(table, bean); return t == null || t.isEmpty() ? table : t; } + /** + * 获取主键字段的Attribute + * + * @return Attribute + */ public Attribute getPrimary() { return this.primary; } + /** + * 遍历数据库表对应的所有字段, 不包含@Transient字段 + * + * @param action BiConsumer + */ public void forEachAttribute(BiConsumer> action) { this.attributeMap.forEach(action); } + /** + * 根据Entity字段名获取字段的Attribute + * + * @param fieldname Class字段名 + * + * @return Attribute + */ public Attribute getAttribute(String fieldname) { if (fieldname == null) return null; return this.attributeMap.get(fieldname); } + /** + * 根据Entity字段名获取可更新字段的Attribute + * + * @param fieldname Class字段名 + * + * @return Attribute + */ public Attribute getUpdateAttribute(String fieldname) { return this.updateAttributeMap.get(fieldname); } + /** + * 判断Entity类的字段名与表字段名s是否存在不一致的值 + * + * @return boolean + */ public boolean isNoAlias() { return this.aliasmap == null; } + /** + * 根据Flipper获取ORDER BY的SQL语句,不存在Flipper或sort字段返回空字符串 + * + * @param flipper 翻页对象 + * + * @return String + */ protected String createSQLOrderby(Flipper flipper) { - if (flipper == null || flipper.getSort() == null || flipper.getSort().isEmpty() || flipper.getSort().indexOf(';') >= 0 || flipper.getSort().indexOf('\n') >= 0) return ""; + if (flipper == null || flipper.getSort() == null) return ""; final String sort = flipper.getSort(); + if (sort.isEmpty() || sort.indexOf(';') >= 0 || sort.indexOf('\n') >= 0) return ""; String sql = this.sortOrderbySqls.get(sort); if (sql != null) return sql; final StringBuilder sb = new StringBuilder(); @@ -395,21 +526,47 @@ public final class EntityInfo { return sql; } - //根据field字段名获取数据库对应的字段名 + /** + * 根据field字段名获取数据库对应的字段名 + * + * @param tabalis 表别名 + * @param fieldname 字段名 + * + * @return String + */ public String getSQLColumn(String tabalis, String fieldname) { return this.aliasmap == null ? (tabalis == null ? fieldname : (tabalis + '.' + fieldname)) : (tabalis == null ? aliasmap.getOrDefault(fieldname, fieldname) : (tabalis + '.' + aliasmap.getOrDefault(fieldname, fieldname))); } + /** + * 获取主键字段的表字段名 + * + * @return String + */ public String getPrimarySQLColumn() { return getSQLColumn(null, this.primary.field()); } - //数据库字段名 + /** + * 获取主键字段的带有表别名的表字段名 + * + * @param tabalis 表别名 + * + * @return String + */ public String getPrimarySQLColumn(String tabalis) { return getSQLColumn(tabalis, this.primary.field()); } + /** + * 拼接UPDATE给字段赋值的SQL片段 + * + * @param col 表字段名 + * @param cv ColumnValue + * + * @return CharSequence + */ protected CharSequence formatSQLValue(String col, final ColumnValue cv) { if (cv == null) return null; switch (cv.getExpress()) { @@ -427,14 +584,33 @@ public final class EntityInfo { return formatToString(cv.getValue()); } + /** + * 获取所有数据表字段的Attribute, 不包含@Transient字段 + * + * @return Map + */ protected Map> getAttributes() { return attributeMap; } + /** + * 判断日志级别 + * + * @param l Level + * + * @return boolean + */ public boolean isLoggable(Level l) { return l.intValue() >= this.logLevel; } + /** + * 将字段值序列化为可SQL的字符串 + * + * @param value 字段值 + * + * @return String + */ protected String formatToString(Object value) { if (value == null) return null; if (value instanceof CharSequence) { @@ -443,6 +619,15 @@ public final class EntityInfo { return String.valueOf(value); } + /** + * 将一行的ResultSet组装成一个Entity对象 + * + * @param sels 指定字段 + * @param set ResultSet + * + * @return Entity对象 + * @throws SQLException SQLException + */ protected T getValue(final SelectColumn sels, final ResultSet set) throws SQLException { T obj = creator.create(); for (Attribute attr : queryAttributes) { diff --git a/src/org/redkale/source/FilterBean.java b/src/org/redkale/source/FilterBean.java index 0148bae6c..2bb0f32f4 100644 --- a/src/org/redkale/source/FilterBean.java +++ b/src/org/redkale/source/FilterBean.java @@ -3,16 +3,18 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ - package org.redkale.source; /** - * - * 不被标记为@javax.persistence.Transient 的字段均视为过滤条件 + * FilterBean用于过滤条件, 所有的FilterBean都必须可以转换成FilterNode
+ * + * 不被标记为@javax.persistence.Transient 的字段均视为过滤条件
+ * + *

+ * 详情见: https://redkale.org * - *

详情见: https://redkale.org * @author zhangjx */ public interface FilterBean { - + } diff --git a/src/org/redkale/source/FilterJoinColumn.java b/src/org/redkale/source/FilterJoinColumn.java index 828f3975d..0e1db647b 100644 --- a/src/org/redkale/source/FilterJoinColumn.java +++ b/src/org/redkale/source/FilterJoinColumn.java @@ -10,6 +10,8 @@ import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** + * 关联表过滤条件
+ * 关联关系表必须含主表, 不能是主表A关联表B,表B再关联表C,只能是主表A关联表B,主表A关联表C
* *

* 详情见: https://redkale.org diff --git a/src/org/redkale/source/FilterJoinNode.java b/src/org/redkale/source/FilterJoinNode.java index c8bfee478..140f7d162 100644 --- a/src/org/redkale/source/FilterJoinNode.java +++ b/src/org/redkale/source/FilterJoinNode.java @@ -13,6 +13,7 @@ import static org.redkale.source.FilterExpress.EQUAL; import org.redkale.util.*; /** + * @FilterJoinColumn对应的FilterNode对象 * *

* 详情见: https://redkale.org diff --git a/src/org/redkale/source/Flipper.java b/src/org/redkale/source/Flipper.java index 3b542fbec..e40c3c000 100644 --- a/src/org/redkale/source/Flipper.java +++ b/src/org/redkale/source/Flipper.java @@ -8,7 +8,7 @@ package org.redkale.source; import java.io.Serializable; /** - * 翻页对象, offset从0开始 + * 翻页对象, offset从0开始, limit必须大于0 * *

* 详情见: https://redkale.org diff --git a/src/org/redkale/source/Range.java b/src/org/redkale/source/Range.java index f74b27f4b..9d22a79c9 100644 --- a/src/org/redkale/source/Range.java +++ b/src/org/redkale/source/Range.java @@ -9,7 +9,7 @@ import java.util.function.*; /** * - * 包含两边的值 + * 取值范围,包含两边的值 * *

* 详情见: https://redkale.org diff --git a/src/org/redkale/source/VirtualEntity.java b/src/org/redkale/source/VirtualEntity.java index 9d7c2fef2..f293bf54b 100644 --- a/src/org/redkale/source/VirtualEntity.java +++ b/src/org/redkale/source/VirtualEntity.java @@ -12,7 +12,7 @@ import java.util.*; import java.util.function.*; /** - * VirtualEntity表示虚拟的数据实体类, 通常Entity都会映射到数据库中的某个表,而标记为VirtualEntity的Entity类只存在EntityCache中 + * VirtualEntity表示虚拟的数据实体类, 通常Entity都会映射到数据库中的某个表,而标记为@VirtualEntity的Entity类只存在EntityCache中 * *

* 详情见: https://redkale.org