From ca06085dfbcd43730aed7a3a07691bd2a6d66eb2 Mon Sep 17 00:00:00 2001 From: redkale Date: Thu, 20 Jun 2024 12:18:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96PatternSimpledCoder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cachesource.md | 60 +++++++++++++++- .../java/org/redkale/convert/DeMember.java | 15 +++- .../java/org/redkale/convert/EnMember.java | 18 ++++- .../org/redkale/convert/ObjectDecoder.java | 2 + .../org/redkale/convert/ObjectEncoder.java | 2 + .../convert/ext/PatternSimpledCoder.java | 57 ++++++++++++--- .../java/org/redkale/util/SelectColumn.java | 47 ++++++++++--- .../redkale/test/util/SelectColumnTest.java | 69 +++++++++++++++++++ 8 files changed, 245 insertions(+), 25 deletions(-) create mode 100644 src/test/java/org/redkale/test/util/SelectColumnTest.java diff --git a/docs/cachesource.md b/docs/cachesource.md index 0b50154c3..60d6d2c67 100644 --- a/docs/cachesource.md +++ b/docs/cachesource.md @@ -1,2 +1,58 @@ -# 缓存数据源 -文档完善中…… \ No newline at end of file +# 缓存组件 CacheSource +  ```CachedCacheSource```是框架主要的缓存组件,主要提供redis和内存两大实现,接口大部分与redis命令保持一致。 + +## 使用CacheSouce存放登录会话 +```java +public class UserService implements Service { + + //用户简单信息缓存 + private final Map users = new ConcurrentHashMap<>(); + + //使用CacheSource必须要指明泛型 + @Resource(name = "usersessions") + protected CacheSource sessions; + + //登录 + public RetResult login(LoginBean bean) { //bean.sessionid 在接入层进行赋值 + UserInfo user = null; + // 登陆逻辑 user = ... + users.put(user.getUserid(), user); + sessions.setLong(600, bean.getSessionid(), user.getUserid()); //session过期时间设置为10分钟 + return new RetResult<>(user); + } + + //获取当前用户信息 + public UserInfo current(String sessionid) { //给HTTP的BaseServlet用 + Long userid = sessions.getexLong(sessionid, 600); + return userid == null ? null : users.get(userid.intValue()); + } + + //注销 + public void logout(String sessionid) { + sessions.del(sessionid); + } +} +``` + +## source.properties 配置说明 +``` + +# usersession为@Resource.name值 +# type可以不用设置,框架会根据url判断使用哪个CacheSource实现类 +redkale.cachesource.usersession.type = org.redkalex.cache.redis.RedisCacheSource +# 最大连接数 +redkale.cachesource.usersession.maxconns = 16 +# 节点地址 +redkale.cachesource.usersession.nodes = redis://127.0.0.1:6363 +# 节点密码 +redkale.cachesource.usersession.password = 12345678 +# 节点db +redkale.cachesource.usersession.db = 0 + +#简化写法: 可以不用.node[0], 将参数都合并到url中 +redkale.cachesource.usersession.url = redis://user:123456@127.0.0.1:6363?db=0 + +@Resource.name=""的CacheSource +redkale.cachesource.nodes = redis://127.0.0.1:6363 +redkale.cachesource.password = 12345678 +``` \ No newline at end of file diff --git a/src/main/java/org/redkale/convert/DeMember.java b/src/main/java/org/redkale/convert/DeMember.java index b3f428a3e..d66f8aebc 100644 --- a/src/main/java/org/redkale/convert/DeMember.java +++ b/src/main/java/org/redkale/convert/DeMember.java @@ -28,16 +28,27 @@ public final class DeMember { final String comment; - protected int index; + protected int index; // 从1开始 protected int position; // 从1开始 - protected int tag; // 主要给protobuf使用 + protected int tag; // 主要给protobuf使用 从1开始 protected final Attribute attribute; protected Decodeable decoder; + public DeMember(final Attribute attribute, int tag, Decodeable decoder) { + this.attribute = attribute; + this.tag = tag; + this.index = tag; + this.position = position; + this.decoder = decoder; + this.comment = ""; + this.field = null; + this.method = null; + } + public DeMember(final Attribute attribute, Field field, Method method) { this.attribute = attribute; this.field = field; diff --git a/src/main/java/org/redkale/convert/EnMember.java b/src/main/java/org/redkale/convert/EnMember.java index 5e3d5d304..6c8ccf96b 100644 --- a/src/main/java/org/redkale/convert/EnMember.java +++ b/src/main/java/org/redkale/convert/EnMember.java @@ -44,11 +44,25 @@ public final class EnMember { final BiFunction fieldFunc; // 一般为null - int index; + int index; // 从1开始 int position; // 从1开始 - int tag; // 主要给protobuf使用 + int tag; // 主要给protobuf使用 从1开始 + + public EnMember(Attribute attribute, int tag, Encodeable encoder) { + this.attribute = attribute; + this.encoder = encoder; + Class t = attribute.type(); + this.string = CharSequence.class.isAssignableFrom(t); + this.bool = t == Boolean.class || t == boolean.class; + this.jsonFieldNameChars = ('"' + attribute.field() + "\":").toCharArray(); + this.jsonFieldNameBytes = ('"' + attribute.field() + "\":").getBytes(); + this.comment = ""; + this.field = null; + this.method = null; + this.fieldFunc = null; + } public EnMember( Attribute attribute, Encodeable encoder, Field field, Method method, BiFunction fieldFunc) { diff --git a/src/main/java/org/redkale/convert/ObjectDecoder.java b/src/main/java/org/redkale/convert/ObjectDecoder.java index 5b39be9b9..87dd36bf2 100644 --- a/src/main/java/org/redkale/convert/ObjectDecoder.java +++ b/src/main/java/org/redkale/convert/ObjectDecoder.java @@ -8,6 +8,7 @@ package org.redkale.convert; import java.lang.reflect.*; import java.util.*; import java.util.concurrent.locks.*; +import org.redkale.annotation.Nullable; import org.redkale.convert.ext.StringSimpledCoder; import org.redkale.util.*; @@ -37,6 +38,7 @@ public class ObjectDecoder implements Decodeable { protected Map memberTagMap; + @Nullable protected ConvertFactory factory; protected volatile boolean inited = false; diff --git a/src/main/java/org/redkale/convert/ObjectEncoder.java b/src/main/java/org/redkale/convert/ObjectEncoder.java index 7ed18da3d..cba9a15fd 100644 --- a/src/main/java/org/redkale/convert/ObjectEncoder.java +++ b/src/main/java/org/redkale/convert/ObjectEncoder.java @@ -9,6 +9,7 @@ import java.lang.reflect.*; import java.util.*; import java.util.concurrent.locks.*; import org.redkale.annotation.ConstructorParameters; +import org.redkale.annotation.Nullable; import org.redkale.convert.ext.StringSimpledCoder; import org.redkale.util.*; @@ -30,6 +31,7 @@ public class ObjectEncoder implements Encodeable { protected EnMember[] members; + @Nullable protected ConvertFactory factory; protected volatile boolean inited = false; diff --git a/src/main/java/org/redkale/convert/ext/PatternSimpledCoder.java b/src/main/java/org/redkale/convert/ext/PatternSimpledCoder.java index 82711805f..bfc257ab5 100644 --- a/src/main/java/org/redkale/convert/ext/PatternSimpledCoder.java +++ b/src/main/java/org/redkale/convert/ext/PatternSimpledCoder.java @@ -5,8 +5,10 @@ */ package org.redkale.convert.ext; +import java.util.HashMap; import java.util.regex.Pattern; import org.redkale.convert.*; +import org.redkale.util.Attribute; /** * Pattern 的SimpledCoder实现 @@ -21,22 +23,57 @@ public class PatternSimpledCoder extends Sim public static final PatternSimpledCoder instance = new PatternSimpledCoder(); + protected final PatternObjectEncoder encoder = new PatternObjectEncoder(); + + protected final PatternObjectDecoder decoder = new PatternObjectDecoder(); + @Override public void convertTo(W out, Pattern value) { - if (value == null) { - out.writeNull(); - } else { - out.writeString(value.flags() + "," + value.pattern()); - } + encoder.convertTo(out, value); } @Override public Pattern convertFrom(R in) { - String value = in.readString(); - if (value == null) { - return null; + return decoder.convertFrom(in); + } + + protected static class PatternObjectEncoder extends ObjectEncoder { + protected PatternObjectEncoder() { + super(Pattern.class); + EnMember flagsMember = new EnMember( + Attribute.create(Pattern.class, "flags", int.class, t -> t.flags(), null), + 1, + IntSimpledCoder.instance); + EnMember patternMember = new EnMember( + Attribute.create(Pattern.class, "pattern", String.class, t -> t.pattern(), null), + 2, + StringSimpledCoder.instance); + this.members = new EnMember[] {flagsMember, patternMember}; + this.inited = true; + } + } + + protected static class PatternObjectDecoder extends ObjectDecoder { + protected PatternObjectDecoder() { + super(Pattern.class); + DeMember flagsMember = new DeMember( + Attribute.create(Pattern.class, "flags", int.class, t -> t.flags(), null), + 1, + IntSimpledCoder.instance); + DeMember patternMember = new DeMember( + Attribute.create(Pattern.class, "pattern", String.class, t -> t.pattern(), null), + 2, + StringSimpledCoder.instance); + this.creator = args -> Pattern.compile((String) args[1], (Integer) args[0]); + this.members = new DeMember[] {flagsMember, patternMember}; + this.creatorConstructorMembers = this.members; + this.memberFieldMap = new HashMap<>(this.members.length); + this.memberTagMap = new HashMap<>(this.members.length); + for (DeMember member : this.members) { + this.memberFieldMap.put(member.getAttribute().field(), member); + this.memberTagMap.put(member.getTag(), member); + } + this.inited = true; } - int pos = value.indexOf(','); - return Pattern.compile(value.substring(pos + 1), Integer.parseInt(value.substring(0, pos))); } } diff --git a/src/main/java/org/redkale/util/SelectColumn.java b/src/main/java/org/redkale/util/SelectColumn.java index 476281aa1..03e0233bd 100644 --- a/src/main/java/org/redkale/util/SelectColumn.java +++ b/src/main/java/org/redkale/util/SelectColumn.java @@ -8,6 +8,7 @@ package org.redkale.util; import java.util.Arrays; import java.util.function.Predicate; import java.util.regex.Pattern; +import org.redkale.convert.json.JsonConvert; /** * 判断字符串数组是否包含或排除指定字符串的操作类 @@ -234,16 +235,44 @@ public class SelectColumn implements Predicate { this.patterns = patterns; } + @Override + public int hashCode() { + int hash = 7; + hash = 29 * hash + Arrays.deepHashCode(this.patterns); + hash = 29 * hash + Arrays.deepHashCode(this.columns); + hash = 29 * hash + (this.excludable ? 1 : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final SelectColumn other = (SelectColumn) obj; + if (this.excludable != other.excludable) { + return false; + } + if (!Arrays.deepEquals(this.patterns, other.patterns)) { + return false; + } + return Arrays.deepEquals(this.columns, other.columns); + } + @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName()).append("{excludable=").append(excludable); - if (columns != null) { - sb.append(", columns=").append(Arrays.toString(columns)); - } - if (patterns != null) { - sb.append(", patterns=").append(Arrays.toString(patterns)); - } - return sb.append('}').toString(); + // StringBuilder sb = new StringBuilder(); + // sb.append(getClass().getSimpleName()).append("{\"excludable\":").append(excludable); + // if (columns != null) { + // sb.append(", columns=").append(Arrays.toString(columns)); + // } + // if (patterns != null) { + // sb.append(", patterns=").append(Arrays.toString(patterns)); + // } + // return sb.append('}').toString(); + return JsonConvert.root().convertTo(this); } } diff --git a/src/test/java/org/redkale/test/util/SelectColumnTest.java b/src/test/java/org/redkale/test/util/SelectColumnTest.java new file mode 100644 index 000000000..dd2801134 --- /dev/null +++ b/src/test/java/org/redkale/test/util/SelectColumnTest.java @@ -0,0 +1,69 @@ +/* + +*/ + +package org.redkale.test.util; + +import java.util.regex.Pattern; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.redkale.convert.json.JsonConvert; +import org.redkale.util.SelectColumn; + +/** + * + * @author zhangjx + */ +public class SelectColumnTest { + + public static void main(String[] args) throws Throwable { + SelectColumnTest test = new SelectColumnTest(); + test.run1(); + } + + @Test + public void run1() throws Exception { + SelectColumn sel = SelectColumn.includes(User::getUserId, User::getUserName); + SelectColumn sel2 = SelectColumn.includes("userId", "userName"); + Assertions.assertTrue(sel.equals(sel2)); + sel.setPatterns(new Pattern[] {Pattern.compile("aaa", 2)}); + System.out.println(JsonConvert.root().convertTo(sel)); + String json = "{\"flags\":2,\"pattern\":\"aaa\"}"; + Pattern pattern = JsonConvert.root().convertFrom(Pattern.class, json); + Assertions.assertEquals(2, pattern.flags()); + Assertions.assertEquals("aaa", pattern.pattern()); + } + + public static class User { + + private long userId; + + private String userName; + + private int age; + + public long getUserId() { + return userId; + } + + public void setUserId(long userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + } +}