This commit is contained in:
redkale
2024-01-09 23:22:12 +08:00
parent 4de3d3f505
commit ce630ee253
16 changed files with 963 additions and 95 deletions

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.json.JsonConvert;
* 存放方法的字节信息
*
* @see org.redkale.asm.AsmMethodBoost
*
*
* @since 2.8.0
*/
public class AsmMethodBean {
@@ -65,6 +65,17 @@ public class AsmMethodBean {
}
}
public List<String> fieldNameList() {
if (params == null) {
return new ArrayList<>();
}
List<String> rs = new ArrayList<>(params.size());
for (AsmMethodParam p : params) {
rs.add(p.getName());
}
return rs;
}
public String[] fieldNameArray() {
if (params == null) {
return null;

View File

@@ -0,0 +1,33 @@
/*
*
*/
package org.redkale.persistence;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 原始sql语句
*
*
* <p>
* 详情见: https://redkale.org
*
* @see org.redkale.source.DataSqlMapper
*
* @author zhangjx
*
* @since 2.8.0
*/
@Inherited
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Sql {
String value();
}

View File

@@ -18,6 +18,7 @@ import org.redkale.annotation.*;
import org.redkale.annotation.AutoLoad;
import org.redkale.annotation.ResourceType;
import static org.redkale.boot.Application.*;
import org.redkale.convert.ConvertDisabled;
import org.redkale.inject.ResourceEvent;
import org.redkale.net.AsyncGroup;
import org.redkale.persistence.Table;
@@ -654,6 +655,11 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
return nativeSqlParser.parse(signFunc, dbtype(), nativeSql, params == null ? Collections.emptyMap() : params);
}
@ConvertDisabled
public IntFunction<String> getSignFunc() {
return signFunc;
}
@Override
public void destroy(AnyValue config) {
super.destroy(config);

View File

@@ -22,6 +22,7 @@ import org.redkale.util.Sheet;
* <p>
* 详情见: https://redkale.org
*
* @see org.redkale.persistence.Sql
*
* @author zhangjx
* @param <T> T
@@ -3309,97 +3310,4 @@ public interface DataSqlMapper<T> {
return dataSource().querySheetAsync(entityType(), selects, flipper, node);
}
//----------------------- native ----------------------------
/**
* 执行多条原生无参数的sql
*
* @param sqls 无参数的sql语句
*
* @return 执行条数
*/
default int[] nativeUpdates(String... sqls) {
return dataSource().nativeUpdates(sqls);
}
/**
* 执行多条原生无参数的sql
*
* @param sqls 无参数的sql语句
*
* @return 执行条数
*/
default CompletableFuture<int[]> nativeUpdatesAsync(String... sqls) {
return dataSource().nativeUpdatesAsync(sqls);
}
/**
* 执行原生无参数的sql
*
* @param sql 无参数的sql语句
*
* @return 执行条数
*/
default int nativeUpdate(String sql) {
return dataSource().nativeUpdate(sql);
}
/**
* 执行原生无参数的sql
*
* @param sql 无参数的sql语句
*
* @return 执行条数
*/
default CompletableFuture<Integer> nativeUpdateAsync(String sql) {
return dataSource().nativeUpdateAsync(sql);
}
/**
* 执行原生带参数的sql
*
* @param sql 带参数的sql语句
* @param params 参数值集合
*
* @return 执行条数
*/
default int nativeUpdate(String sql, Map<String, Object> params) {
return dataSource().nativeUpdate(sql, params);
}
/**
* 执行原生带参数的sql
*
* @param sql 带参数的sql语句
* @param params 参数值集合
*
* @return 执行条数
*/
default CompletableFuture<Integer> nativeUpdateAsync(String sql, Map<String, Object> params) {
return dataSource().nativeUpdateAsync(sql, params);
}
/**
* 执行原生带参数的sql
*
* @param sql 带参数的sql语句
* @param bean 参数值集合
*
* @return 执行条数
*/
default int nativeUpdate(String sql, Serializable bean) {
return dataSource().nativeUpdate(sql, bean);
}
/**
* 执行原生带参数的sql
*
* @param sql 带参数的sql语句
* @param bean 参数值集合
*
* @return 执行条数
*/
default CompletableFuture<Integer> nativeUpdateAsync(String sql, Serializable bean) {
return dataSource().nativeUpdateAsync(sql, bean);
}
}

View File

@@ -7,6 +7,7 @@ import java.io.Serializable;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.*;
import org.redkale.asm.AsmDepends;
import static org.redkale.source.DataResultSet.formatColumnValue;
import org.redkale.util.*;
@@ -20,6 +21,7 @@ import org.redkale.util.*;
* @author zhangjx
* @since 2.8.0
*/
@AsmDepends
public interface DataSqlSource extends DataSource {
/**

View File

@@ -3,9 +3,48 @@
*/
package org.redkale.source.spi;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.IntFunction;
import org.redkale.asm.AnnotationVisitor;
import org.redkale.asm.AsmMethodBean;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.asm.ClassWriter;
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
import org.redkale.asm.FieldVisitor;
import org.redkale.asm.Label;
import org.redkale.asm.MethodVisitor;
import static org.redkale.asm.Opcodes.ACC_PRIVATE;
import static org.redkale.asm.Opcodes.ACC_PUBLIC;
import static org.redkale.asm.Opcodes.ACC_SUPER;
import static org.redkale.asm.Opcodes.ALOAD;
import static org.redkale.asm.Opcodes.ARETURN;
import static org.redkale.asm.Opcodes.ASTORE;
import static org.redkale.asm.Opcodes.DUP;
import static org.redkale.asm.Opcodes.GETFIELD;
import static org.redkale.asm.Opcodes.INVOKEINTERFACE;
import static org.redkale.asm.Opcodes.INVOKESPECIAL;
import static org.redkale.asm.Opcodes.INVOKEVIRTUAL;
import static org.redkale.asm.Opcodes.NEW;
import static org.redkale.asm.Opcodes.POP;
import static org.redkale.asm.Opcodes.RETURN;
import static org.redkale.asm.Opcodes.V11;
import org.redkale.asm.Type;
import org.redkale.persistence.Sql;
import org.redkale.source.AbstractDataSqlSource;
import org.redkale.source.DataNativeSqlInfo;
import org.redkale.source.DataNativeSqlParser;
import org.redkale.source.DataSqlMapper;
import org.redkale.source.DataSqlSource;
import org.redkale.source.SourceException;
import org.redkale.util.RedkaleClassLoader;
import org.redkale.util.TypeToken;
import org.redkale.util.Utility;
/**
* DataSqlMapper工厂类
@@ -20,10 +59,215 @@ import org.redkale.source.DataSqlSource;
*/
public final class DataSqlMapperBuilder {
private static Map<String, AsmMethodBean> baseMethodBeans;
private DataSqlMapperBuilder() {
}
public static <T, M extends DataSqlMapper<T>> M createMapper(DataNativeSqlParser nativeSqlParser, DataSqlSource source, Class<M> mapperType) {
return null;
if (!mapperType.isInterface()) {
throw new SourceException(mapperType + " is not interface");
}
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
final Class entityType = entityType(mapperType);
final String supDynName = mapperType.getName().replace('.', '/');
final String newDynName = "org/redkaledyn/source/mapper/_DynDataSqlMapper__" + supDynName.replace('$', '_');
try {
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
M mapper = (M) newClazz.getDeclaredConstructor().newInstance();
{
Field c = newClazz.getDeclaredField("_source");
c.setAccessible(true);
c.set(mapper, source);
}
{
Field c = newClazz.getDeclaredField("_type");
c.setAccessible(true);
c.set(mapper, entityType);
}
return mapper;
} catch (ClassNotFoundException e) {
//do nothing
} catch (Throwable t) {
t.printStackTrace();
}
if (baseMethodBeans == null) {
baseMethodBeans = AsmMethodBoost.getMethodBeans(DataSqlMapper.class);
}
List<Item> items = new ArrayList<>();
Map<String, AsmMethodBean> selfMethodBeans = AsmMethodBoost.getMethodBeans(mapperType);
for (Method method : mapperType.getMethods()) {
if (Modifier.isStatic(method.getModifiers())) {
continue;
}
if ("dataSource".equals(method.getName()) && method.getParameterCount() == 0) {
continue;
}
if ("entityType".equals(method.getName()) && method.getParameterCount() == 0) {
continue;
}
Sql sql = method.getAnnotation(Sql.class);
if (sql == null) {
if (Modifier.isAbstract(method.getModifiers())) {
throw new SourceException(method + " require @" + Sql.class.getSimpleName());
}
continue;
}
if (!Modifier.isAbstract(method.getModifiers())) {
throw new SourceException(method + " is not abstract, but contains @" + Sql.class.getSimpleName());
}
IntFunction<String> signFunc = null;
if (source instanceof AbstractDataSqlSource) {
signFunc = ((AbstractDataSqlSource) source).getSignFunc();
}
DataNativeSqlInfo sqlInfo = nativeSqlParser.parse(signFunc, source.getType(), sql.value());
AsmMethodBean methodBean = selfMethodBeans.get(AsmMethodBoost.getMethodBeanKey(method));
if (!Utility.equalsElement(sqlInfo.getRootParamNames(), methodBean.fieldNameList())) {
throw new SourceException(method + " parameters not match @" + Sql.class.getSimpleName() + "(" + sql.value() + ")");
}
items.add(new Item(method, sqlInfo, methodBean));
}
//------------------------------------------------------------------------------
final String entityDesc = Type.getDescriptor(entityType);
final String sqlSourceDesc = Type.getDescriptor(DataSqlSource.class);
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;
cw.visit(V11, ACC_PUBLIC + ACC_SUPER, newDynName, null, "java/lang/Object", new String[]{supDynName});
{
fv = cw.visitField(ACC_PRIVATE, "_source", sqlSourceDesc, null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE, "_type", "Ljava/lang/Class;", null, null);
fv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "dataSource", "()Lorg/redkale/source/DataSqlSource;", null, null);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "org/redkale/test/source/parser/DynForumInfoMapperImpl", "source", sqlSourceDesc);
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "entityType", "()Ljava/lang/Class;", "()Ljava/lang/Class<" + entityDesc + ">;", null);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "type", "Ljava/lang/Class;");
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
//sql系列方法
for (Item item : items) {
Method method = item.method;
DataNativeSqlInfo sqlInfo = item.sqlInfo;
AsmMethodBean methodBean = item.methodBean;
Sql sql = method.getAnnotation(Sql.class);
mv = cw.visitMethod(ACC_PUBLIC, "queryForumResultAsync", "(Lorg/redkale/test/source/parser/ForumBean;)Ljava/util/concurrent/CompletableFuture;", "(Lorg/redkale/test/source/parser/ForumBean;)Ljava/util/concurrent/CompletableFuture<Ljava/util/List<Lorg/redkale/test/source/parser/ForumResult;>;>;", null);
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLdcInsn(sql.value());
mv.visitVarInsn(ASTORE, 2);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitTypeInsn(NEW, "java/util/HashMap");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false);
mv.visitVarInsn(ASTORE, 3);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitVarInsn(ALOAD, 3);
mv.visitLdcInsn("bean");
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitInsn(POP);
Label l3 = new Label();
mv.visitLabel(l3);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/redkale/test/source/parser/DynForumInfoMapperImpl", "dataSource", "()Lorg/redkale/source/DataSqlSource;", false);
mv.visitLdcInsn(Type.getType("Lorg/redkale/test/source/parser/ForumResult;"));
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn(INVOKEINTERFACE, "org/redkale/source/DataSqlSource", "nativeQueryListAsync", "(Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)Ljava/util/concurrent/CompletableFuture;", true);
mv.visitInsn(ARETURN);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLocalVariable("this", "Lorg/redkale/test/source/parser/DynForumInfoMapperImpl;", null, l0, l4, 0);
mv.visitLocalVariable("bean", "Lorg/redkale/test/source/parser/ForumBean;", null, l0, l4, 1);
mv.visitLocalVariable("sql", "Ljava/lang/String;", null, l1, l4, 2);
mv.visitLocalVariable("params", "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;", l2, l4, 3);
mv.visitMaxs(4, 4);
mv.visitEnd();
}
cw.visitEnd();
byte[] bytes = cw.toByteArray();
Class<?> newClazz = new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}.loadClass(newDynName.replace('/', '.'), bytes);
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz);
RedkaleClassLoader.putReflectionPublicConstructors(newClazz, newDynName.replace('/', '.'));
RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
try {
M mapper = (M) newClazz.getDeclaredConstructor().newInstance();
{
Field c = newClazz.getDeclaredField("_source");
c.setAccessible(true);
c.set(mapper, source);
}
{
Field c = newClazz.getDeclaredField("_type");
c.setAccessible(true);
c.set(mapper, entityType);
}
return mapper;
} catch (Exception ex) {
throw new SourceException(ex);
}
}
private static Class entityType(Class mapperType) {
for (java.lang.reflect.Type t : mapperType.getGenericInterfaces()) {
if (DataSqlMapper.class.isAssignableFrom(TypeToken.typeToClass(t))) {
return TypeToken.typeToClass(((ParameterizedType) t).getActualTypeArguments()[0]);
}
}
throw new SourceException("Not found entity class from " + mapperType.getName());
}
private static class Item {
public Method method;
public DataNativeSqlInfo sqlInfo;
public AsmMethodBean methodBean;
public Item(Method method, DataNativeSqlInfo sqlInfo, AsmMethodBean methodBean) {
this.method = method;
this.sqlInfo = sqlInfo;
this.methodBean = methodBean;
}
}
}

View File

@@ -516,9 +516,14 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager {
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
return null; //远程模式不得注入
}
DataSqlMapper old = resourceFactory.find(resourceName, DataSqlMapper.class);
if (old != null) {
return old;
}
DataSource source = loadDataSource(resourceName, false);
Class mapperType = field.getType();
DataSqlMapper mapper = DataSqlMapperBuilder.createMapper(nativeSqlParser, (DataSqlSource) source, mapperType);
resourceFactory.register(resourceName, DataSqlMapper.class, mapper);
field.set(srcObj, mapper);
return mapper;
} catch (Exception e) {

View File

@@ -0,0 +1,25 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.test.source.parser;
import java.io.*;
import org.redkale.convert.json.*;
import org.redkale.persistence.*;
/**
*
* @author zhangjx
*/
@Entity
public abstract class BaseEntity implements Serializable {
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -0,0 +1,14 @@
/*
*
*/
package org.redkale.test.source.parser;
import org.redkale.source.DataSqlMapper;
/**
*
* @author zhangjx
*/
public interface BaseMapper<V> extends DataSqlMapper<V> {
}

View File

@@ -0,0 +1,39 @@
/*
*
*/
package org.redkale.test.source.parser;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.junit.jupiter.api.Test;
import org.redkale.source.DataSqlMapper;
import org.redkale.source.SourceException;
import org.redkale.util.TypeToken;
/**
*
* @author zhangjx
*/
public class DataSqlMapperTest {
public static void main(String[] args) throws Throwable {
DataSqlMapperTest test = new DataSqlMapperTest();
test.run();
System.out.println(entityType(ForumInfoMapper.class));
}
private static Class entityType(Class mapperType) {
for (Type t : mapperType.getGenericInterfaces()) {
if (DataSqlMapper.class.isAssignableFrom(TypeToken.typeToClass(t))) {
return TypeToken.typeToClass(((ParameterizedType) t).getActualTypeArguments()[0]);
}
}
throw new SourceException("Not found entity class from " + mapperType.getName());
}
@Test
public void run() throws Exception {
}
}

View File

@@ -0,0 +1,62 @@
/*
*
*/
package org.redkale.test.source.parser;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.redkale.source.DataSqlSource;
/**
*
* @author zhangjx
*/
public class DynForumInfoMapperImpl implements ForumInfoMapper {
private DataSqlSource source;
private Class type;
@Override
public ForumResult findForumResult(ForumBean bean) {
String sql = "SELECT f.forum_groupid, s.forum_section_color FROM forum_info f, forum_section s WHERE f.forumid = s.forumid";
Map<String, Object> params = new HashMap<>();
params.put("bean", bean);
return dataSource().nativeQueryOne(ForumResult.class, sql, params);
}
public CompletableFuture<ForumResult> findForumResultAsync(ForumBean bean) {
String sql = "SELECT f.forum_groupid, s.forum_section_color FROM forum_info f, forum_section s WHERE f.forumid = s.forumid";
Map<String, Object> params = new HashMap<>();
params.put("bean", bean);
return dataSource().nativeQueryOneAsync(ForumResult.class, sql, params);
}
@Override
public List<ForumResult> queryForumResult(ForumBean bean) {
String sql = "SELECT f.forum_groupid, s.forum_section_color FROM forum_info f, forum_section s WHERE f.forumid = s.forumid";
Map<String, Object> params = new HashMap<>();
params.put("bean", bean);
return dataSource().nativeQueryList(ForumResult.class, sql, params);
}
public CompletableFuture<List<ForumResult>> queryForumResultAsync(ForumBean bean) {
String sql = "SELECT f.forum_groupid, s.forum_section_color FROM forum_info f, forum_section s WHERE f.forumid = s.forumid";
Map<String, Object> params = new HashMap<>();
params.put("bean", bean);
return dataSource().nativeQueryListAsync(ForumResult.class, sql, params);
}
@Override
public DataSqlSource dataSource() {
return source;
}
@Override
public Class<ForumInfo> entityType() {
return type;
}
}

View File

@@ -0,0 +1,44 @@
/*
*
*/
package org.redkale.test.source.parser;
import java.io.Serializable;
/**
*
* @author zhangjx
*/
public class ForumBean implements Serializable {
private String forumSectionid;
private String forumSectionColor;
private String forumid;
public String getForumSectionid() {
return forumSectionid;
}
public void setForumSectionid(String forumSectionid) {
this.forumSectionid = forumSectionid;
}
public String getForumSectionColor() {
return forumSectionColor;
}
public void setForumSectionColor(String forumSectionColor) {
this.forumSectionColor = forumSectionColor;
}
public String getForumid() {
return forumid;
}
public void setForumid(String forumid) {
this.forumid = forumid;
}
}

View File

@@ -0,0 +1,259 @@
package org.redkale.test.source.parser;
import java.util.*;
import org.redkale.convert.*;
import org.redkale.persistence.*;
import org.redkale.util.Utility;
/**
*
* @author zhangjx
*/
@Table(name = "forum_info", comment = "论坛信息表")
public class ForumInfo extends BaseEntity implements Comparable<ForumInfo> {
@Id
@Column(name = "forum_id", length = 64, comment = "论坛ID")
private String forumid;
@Column(name = "forum_name", length = 128, comment = "论坛的名称")
private String forumName;
@Column(name = "forum_groupid", length = 64, comment = "论坛分类的ID")
private String forumGroupid;
@Column(name = "forum_sections", length = 1024, comment = "论坛小版块的ID集合")
private String[] forumSections;
@Column(name = "forum_managerids", length = 1024, comment = "论坛小版块的ID集合")
private Set<Integer> forumManagerids;
@Column(name = "forum_face_url", length = 255, comment = "论坛的图片url")
private String forumFaceUrl;
@Column(name = "forum_css_img_url", length = 255, comment = "论坛的背景图url")
private String forumCssImgUrl;
@Column(name = "forum_css_url", length = 255, comment = "论坛的样式url")
private String forumCssUrl;
@Column(name = "forum_css_content", length = 10240, comment = "论坛的css内容")
private String forumCssContent;
@Column(name = "forum_bar_html", length = 1024, comment = "版块的提示栏")
private String forumBarHtml;
@Column(name = "forum_desc", length = 255, comment = "论坛说明")
private String forumDesc;
@Column(name = "forum_notice", length = 1024, comment = "论坛公告")
private String forumNotice;
@Column(comment = "被关注的用户数")
private long followers;
@Column(name = "post_count", comment = "帖子数")
private long postCount;
@Column(name = "like_count", comment = "关注数")
private long likeCount;
@Column(comment = "排序顺序,值小靠前")
private int display = 1000;
@Transient
private Map<String, ForumSection> sections;
public ForumSection findForumSection(String forumSectionid) {
return sections == null ? null : sections.get(forumSectionid);
}
public synchronized void increLikeCount() {
this.likeCount++;
}
public synchronized void increPostCount(String sectionid) {
this.postCount++;
if (sections != null && sectionid != null && !sectionid.isEmpty()) {
ForumSection section = sections.get(sectionid);
if (section != null) {
section.increPostCount();
}
}
}
public synchronized void increFollowers() {
this.followers++;
}
public synchronized void decreFollowers() {
this.followers--;
}
public boolean containsManagerid(int userid) {
return forumManagerids != null && forumManagerids.contains(userid);
}
public boolean containsSection(String forumSectionid) {
return forumSections != null && forumSectionid != null && Utility.contains(forumSections, forumSectionid);
}
public boolean emptyForumNotice() {
return this.forumNotice == null || this.forumNotice.isEmpty();
}
public boolean emptyCssImgUrl() {
return this.forumCssImgUrl == null || this.forumCssImgUrl.isEmpty();
}
public boolean emptyCssUrl() {
return this.forumCssUrl == null || this.forumCssUrl.isEmpty();
}
public boolean emptyCssContent() {
return this.forumCssContent == null || this.forumCssContent.isEmpty();
}
public void setForumid(String forumid) {
this.forumid = forumid;
}
public String getForumid() {
return this.forumid;
}
public void setForumName(String forumName) {
this.forumName = forumName;
}
public String getForumName() {
return this.forumName;
}
public void setForumFaceUrl(String forumFaceUrl) {
this.forumFaceUrl = forumFaceUrl;
}
public String getForumFaceUrl() {
return this.forumFaceUrl;
}
public String getForumCssImgUrl() {
return forumCssImgUrl;
}
public void setForumCssImgUrl(String forumCssImgUrl) {
this.forumCssImgUrl = forumCssImgUrl;
}
public String getForumCssUrl() {
return forumCssUrl;
}
public void setForumCssUrl(String forumCssUrl) {
this.forumCssUrl = forumCssUrl;
}
public String getForumCssContent() {
return forumCssContent;
}
public void setForumCssContent(String forumCssContent) {
this.forumCssContent = forumCssContent;
}
public String[] getForumSections() {
return forumSections;
}
public void setForumSections(String[] forumSections) {
this.forumSections = forumSections;
}
public Set<Integer> getForumManagerids() {
return forumManagerids;
}
public void setForumManagerids(Set<Integer> forumManagerids) {
this.forumManagerids = forumManagerids;
}
public String getForumGroupid() {
return forumGroupid;
}
public void setForumGroupid(String forumGroupid) {
this.forumGroupid = forumGroupid;
}
public String getForumDesc() {
return forumDesc;
}
public void setForumDesc(String forumDesc) {
this.forumDesc = forumDesc;
}
public String getForumNotice() {
return forumNotice;
}
public void setForumNotice(String forumNotice) {
this.forumNotice = forumNotice;
}
public long getFollowers() {
return followers;
}
public void setFollowers(long followers) {
this.followers = followers;
}
public void setPostCount(long postCount) {
this.postCount = postCount;
}
public long getPostCount() {
return this.postCount;
}
public long getLikeCount() {
return likeCount;
}
public void setLikeCount(long likeCount) {
this.likeCount = likeCount;
}
public void setDisplay(int display) {
this.display = display;
}
@ConvertColumn(ignore = true, type = ConvertType.PROTOBUF_JSON)
public int getDisplay() {
return this.display;
}
@Override
public int compareTo(ForumInfo o) {
return this.display - o.display;
}
public Map<String, ForumSection> getSections() {
return sections;
}
public void setSections(Map<String, ForumSection> sections) {
this.sections = sections;
}
public String getForumBarHtml() {
return forumBarHtml;
}
public void setForumBarHtml(String forumBarHtml) {
this.forumBarHtml = forumBarHtml;
}
}

View File

@@ -0,0 +1,43 @@
/*
*
*/
package org.redkale.test.source.parser;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.redkale.persistence.Sql;
/**
*
* @author zhangjx
*/
public interface ForumInfoMapper extends BaseMapper<ForumInfo> {
@Sql("SELECT f.forum_groupid, s.forum_section_color "
+ "FROM forum_info f, forum_section s "
+ " WHERE f.forumid = s.forumid AND "
+ "s.forum_sectionid = ${bean.forumSectionid} AND "
+ "f.forumid = ${bean.forumid} AND s.forum_section_color = ${bean.forumSectionColor}")
public ForumResult findForumResult(ForumBean bean);
@Sql("SELECT f.forum_groupid, s.forum_section_color "
+ "FROM forum_info f, forum_section s "
+ " WHERE f.forumid = s.forumid AND "
+ "s.forum_sectionid = ${bean.forumSectionid} AND "
+ "f.forumid = ${bean.forumid} AND s.forum_section_color = ${bean.forumSectionColor}")
public CompletableFuture<ForumResult> findForumResultAsync(ForumBean bean);
@Sql("SELECT f.forum_groupid, s.forum_section_color "
+ "FROM forum_info f, forum_section s "
+ " WHERE f.forumid = s.forumid AND "
+ "s.forum_sectionid = ${bean.forumSectionid} AND "
+ "f.forumid = ${bean.forumid} AND s.forum_section_color = ${bean.forumSectionColor}")
public List<ForumResult> queryForumResult(ForumBean bean);
@Sql("SELECT f.forum_groupid, s.forum_section_color "
+ "FROM forum_info f, forum_section s "
+ " WHERE f.forumid = s.forumid AND "
+ "s.forum_sectionid = ${bean.forumSectionid} AND "
+ "f.forumid = ${bean.forumid} AND s.forum_section_color = ${bean.forumSectionColor}")
public CompletableFuture<List<ForumResult>> queryForumResultAsync(ForumBean bean);
}

View File

@@ -0,0 +1,39 @@
/*
*
*/
package org.redkale.test.source.parser;
import org.redkale.convert.json.JsonConvert;
/**
*
* @author zhangjx
*/
public class ForumResult {
private String forumGroupid;
private String forumSectionColor;
public String getForumGroupid() {
return forumGroupid;
}
public void setForumGroupid(String forumGroupid) {
this.forumGroupid = forumGroupid;
}
public String getForumSectionColor() {
return forumSectionColor;
}
public void setForumSectionColor(String forumSectionColor) {
this.forumSectionColor = forumSectionColor;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -0,0 +1,134 @@
package org.redkale.test.source.parser;
import java.util.Set;
import org.redkale.convert.*;
import org.redkale.persistence.*;
/**
*
* @author zhangjx
*/
@Table(name = "forum_section", comment = "论坛小版块信息表")
public class ForumSection extends BaseEntity {
@Id
@Column(name = "forum_sectionid", length = 64, comment = "论坛小版块ID")
private String forumSectionid;
@Column(length = 64, comment = "论坛ID")
private String forumid;
@Column(name = "forum_section_name", length = 128, comment = "论坛小版块的名称")
private String forumSectionName;
@Column(name = "forum_section_face_url", length = 255, comment = "论坛小版块的图标url")
private String forumSectionFaceUrl;
@Column(name = "forum_section_managerids", length = 1024, comment = "论坛小版块的ID集合")
private Set<Integer> forumSectionManagerids;
@Column(name = "forum_section_desc", length = 32, comment = "论坛小版块说明")
private String forumSectionDesc;
@Column(name = "forum_section_color", length = 255, comment = "论坛小版块小标题的背景色")
private String forumSectionColor;
@Column(name = "forum_section_bar_html", length = 1024, comment = "版块的提示栏")
private String forumSectionBarHtml;
@Column(name = "post_count", comment = "帖子数")
private long postCount;
@Column(comment = "排序顺序,值小靠前")
private int display = 1000;
public void increPostCount() {
this.postCount++;
}
public boolean containsSectionManagerid(int userid) {
return forumSectionManagerids != null && forumSectionManagerids.contains(userid);
}
public void setForumSectionid(String forumSectionid) {
this.forumSectionid = forumSectionid;
}
public String getForumSectionid() {
return this.forumSectionid;
}
public String getForumid() {
return forumid;
}
public void setForumid(String forumid) {
this.forumid = forumid;
}
public void setForumSectionName(String forumSectionName) {
this.forumSectionName = forumSectionName;
}
public String getForumSectionName() {
return this.forumSectionName;
}
public void setForumSectionFaceUrl(String forumSectionFaceUrl) {
this.forumSectionFaceUrl = forumSectionFaceUrl;
}
public String getForumSectionFaceUrl() {
return this.forumSectionFaceUrl;
}
public String getForumSectionColor() {
return forumSectionColor;
}
public void setForumSectionColor(String forumSectionColor) {
this.forumSectionColor = forumSectionColor;
}
public void setForumSectionDesc(String forumSectionDesc) {
this.forumSectionDesc = forumSectionDesc;
}
public Set<Integer> getForumSectionManagerids() {
return forumSectionManagerids;
}
public void setForumSectionManagerids(Set<Integer> forumSectionManagerids) {
this.forumSectionManagerids = forumSectionManagerids;
}
public String getForumSectionDesc() {
return this.forumSectionDesc;
}
public void setPostCount(long postCount) {
this.postCount = postCount;
}
public long getPostCount() {
return this.postCount;
}
public void setDisplay(int display) {
this.display = display;
}
@ConvertColumn(ignore = true, type = ConvertType.PROTOBUF_JSON)
public int getDisplay() {
return this.display;
}
public String getForumSectionBarHtml() {
return forumSectionBarHtml;
}
public void setForumSectionBarHtml(String forumSectionBarHtml) {
this.forumSectionBarHtml = forumSectionBarHtml;
}
}