This commit is contained in:
@@ -40,6 +40,10 @@ public abstract class Factory<R extends Reader, W extends Writer> {
|
||||
|
||||
private final HashMap<AccessibleObject, ConvertColumnEntry> columnEntrys = new HashMap();
|
||||
|
||||
private final Set<Class> skipIgnores = new HashSet<>();
|
||||
|
||||
private boolean skipAllIgnore = false;
|
||||
|
||||
protected Factory(Factory<R, W> parent) {
|
||||
this.parent = parent;
|
||||
if (parent == null) {
|
||||
@@ -111,11 +115,38 @@ public abstract class Factory<R extends Reader, W extends Writer> {
|
||||
if (en != null) return en;
|
||||
final ConvertType ct = this.getConvertType();
|
||||
for (ConvertColumn ref : field.getAnnotationsByType(ConvertColumn.class)) {
|
||||
if (ref.type().contains(ct)) return new ConvertColumnEntry(ref);
|
||||
if (ref.type().contains(ct)) {
|
||||
ConvertColumnEntry entry = new ConvertColumnEntry(ref);
|
||||
if (skipAllIgnore) {
|
||||
entry.setIgnore(false);
|
||||
return entry;
|
||||
}
|
||||
if (skipIgnores.isEmpty()) return entry;
|
||||
if (skipIgnores.contains(((Member) field).getDeclaringClass())) entry.setIgnore(false);
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使所有类的所有被声明为ConvertColumn.ignore = true 的字段或方法变为ConvertColumn.ignore = false
|
||||
* <p>
|
||||
* @param skipIgnore
|
||||
*/
|
||||
public final void registerSkipAllIgnore(final boolean skipIgnore) {
|
||||
this.skipAllIgnore = skipIgnore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使该类所有被声明为ConvertColumn.ignore = true 的字段或方法变为ConvertColumn.ignore = false
|
||||
* <p>
|
||||
* @param type
|
||||
*/
|
||||
public final void registerSkipIgnore(final Class type) {
|
||||
skipIgnores.add(type);
|
||||
}
|
||||
|
||||
public final boolean register(final Class type, String column, ConvertColumnEntry entry) {
|
||||
if (type == null || column == null || entry == null) return false;
|
||||
try {
|
||||
|
||||
@@ -483,6 +483,16 @@ public final class JsonReader implements Reader {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final int start = currpos;
|
||||
for (;;) {
|
||||
char ch = text0[currpos];
|
||||
if (ch == ',' || ch <= ' ' || ch == '}' || ch == ']' || ch == ':') break;
|
||||
currpos++;
|
||||
}
|
||||
if (currpos == start) throw new ConvertException("expected a string after a key but '" + text0[position] + "' (position = " + position + ")");
|
||||
this.position = currpos - 1;
|
||||
return new String(text0, start, currpos - start);
|
||||
}
|
||||
this.position = currpos;
|
||||
throw new ConvertException("expected a ':' after a key but '" + text0[position] + "' (position = " + position + ")");
|
||||
|
||||
@@ -18,7 +18,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
*/
|
||||
public abstract class BasedHttpServlet extends HttpServlet {
|
||||
|
||||
private Map.Entry<String, Entry>[] actions;
|
||||
@@ -28,7 +28,7 @@ public abstract class BasedHttpServlet extends HttpServlet {
|
||||
for (Map.Entry<String, Entry> en : actions) {
|
||||
if (request.getRequestURI().startsWith(en.getKey())) {
|
||||
Entry entry = en.getValue();
|
||||
if (entry.ignore || authenticate(request, response)) entry.servlet.execute(request, response);
|
||||
if (entry.ignore || authenticate(entry.moduleid, entry.actionid, request, response)) entry.servlet.execute(request, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public abstract class BasedHttpServlet extends HttpServlet {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean authenticate(HttpRequest request, HttpResponse response) throws IOException;
|
||||
public abstract boolean authenticate(int module, int actionid, HttpRequest request, HttpResponse response) throws IOException;
|
||||
|
||||
private HashMap<String, Entry> load() {
|
||||
final boolean typeIgnore = this.getClass().getAnnotation(AuthIgnore.class) != null;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
package com.wentch.redkale.net.http;
|
||||
|
||||
import com.wentch.redkale.util.ByteArray;
|
||||
import com.wentch.redkale.convert.json.*;
|
||||
import com.wentch.redkale.net.*;
|
||||
import com.wentch.redkale.util.AnyValue.DefaultAnyValue;
|
||||
|
||||
@@ -27,6 +27,53 @@ public final class HttpResourceServlet extends HttpServlet {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HttpResourceServlet.class.getSimpleName());
|
||||
|
||||
protected class WatchThread extends Thread {
|
||||
|
||||
protected final File root;
|
||||
|
||||
protected final WatchService watcher;
|
||||
|
||||
public WatchThread(File root) throws IOException {
|
||||
this.root = root;
|
||||
this.setName("Servlet-ResourceWatch-Thread");
|
||||
this.setDaemon(true);
|
||||
this.watcher = this.root.toPath().getFileSystem().newWatchService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final String rootstr = root.getCanonicalPath();
|
||||
while (!this.isInterrupted()) {
|
||||
final WatchKey key = watcher.take();
|
||||
final Path parent = keymaps.get(key);
|
||||
if (parent == null) {
|
||||
key.cancel();
|
||||
continue;
|
||||
}
|
||||
key.pollEvents().stream().forEach((event) -> {
|
||||
try {
|
||||
Path path = parent.resolve((Path) event.context());
|
||||
final String uri = path.toString().substring(rootstr.length()).replace('\\', '/');
|
||||
//logger.log(Level.FINEST, "file(" + uri + ") happen " + event.kind() + " event");
|
||||
Thread.sleep(1000L); //等待update file完毕
|
||||
if (event.kind() == ENTRY_DELETE) {
|
||||
files.remove(uri);
|
||||
} else if (event.kind() == ENTRY_MODIFY) {
|
||||
FileEntry en = files.get(uri);
|
||||
if (en != null) en.update();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.FINE, event.context() + " occur erroneous", ex);
|
||||
}
|
||||
});
|
||||
key.reset();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//缓存总大小, 默认128M
|
||||
protected long cachelimit = 128 * 1024 * 1024L;
|
||||
|
||||
@@ -39,29 +86,33 @@ public final class HttpResourceServlet extends HttpServlet {
|
||||
|
||||
protected final ConcurrentHashMap<String, FileEntry> files = new ConcurrentHashMap<>();
|
||||
|
||||
protected WatchService watcher;
|
||||
|
||||
protected final ConcurrentHashMap<WatchKey, Path> keymaps = new ConcurrentHashMap<>();
|
||||
|
||||
protected SimpleEntry<Pattern, String>[] locationRewrites;
|
||||
|
||||
protected Thread watchThread;
|
||||
protected WatchThread watchThread;
|
||||
|
||||
protected List<SimpleEntry<File, WatchThread>> resx;
|
||||
|
||||
protected Predicate<String> ranges;
|
||||
|
||||
@Override
|
||||
public void init(Context context, AnyValue config) {
|
||||
String[] rootstrs = null;
|
||||
if (config != null) {
|
||||
String rootstr = config.getValue("webroot", "root").trim();
|
||||
if (rootstr.indexOf(':') < 0 && rootstr.indexOf('/') != 0 && System.getProperty("APP_HOME") != null) {
|
||||
rootstr = new File(System.getProperty("APP_HOME"), rootstr).getPath();
|
||||
rootstrs = config.getValue("webroot", "root").trim().split(",");
|
||||
for (int i = 0; i < rootstrs.length; i++) {
|
||||
String rootstr = rootstrs[i];
|
||||
if (rootstr.indexOf(':') < 0 && rootstr.indexOf('/') != 0 && System.getProperty("APP_HOME") != null) {
|
||||
rootstrs[i] = new File(System.getProperty("APP_HOME"), rootstr).getPath();
|
||||
}
|
||||
}
|
||||
String rangesValue = config.getValue("ranges");
|
||||
this.ranges = rangesValue != null ? Pattern.compile(rangesValue).asPredicate() : null;
|
||||
try {
|
||||
this.root = new File(rootstr).getCanonicalFile();
|
||||
this.root = new File(rootstrs[0]).getCanonicalFile();
|
||||
} catch (IOException ioe) {
|
||||
this.root = new File(rootstr);
|
||||
this.root = new File(rootstrs[0]);
|
||||
}
|
||||
AnyValue cacheconf = config.getAnyValue("caches");
|
||||
if (cacheconf != null) {
|
||||
@@ -83,62 +134,36 @@ public final class HttpResourceServlet extends HttpServlet {
|
||||
if (this.cachelimit < 1) return;
|
||||
if (this.root != null) {
|
||||
try {
|
||||
this.watcher = this.root.toPath().getFileSystem().newWatchService();
|
||||
this.watchThread = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final String rootstr = root.getCanonicalPath();
|
||||
while (!this.isInterrupted()) {
|
||||
final WatchKey key = watcher.take();
|
||||
final Path parent = keymaps.get(key);
|
||||
if (parent == null) {
|
||||
key.cancel();
|
||||
continue;
|
||||
}
|
||||
key.pollEvents().stream().forEach((event) -> {
|
||||
try {
|
||||
Path path = parent.resolve((Path) event.context());
|
||||
final String uri = path.toString().substring(rootstr.length()).replace('\\', '/');
|
||||
//logger.log(Level.FINEST, "file(" + uri + ") happen " + event.kind() + " event");
|
||||
Thread.sleep(1000L); //等待update file完毕
|
||||
if (event.kind() == ENTRY_DELETE) {
|
||||
files.remove(uri);
|
||||
} else if (event.kind() == ENTRY_MODIFY) {
|
||||
FileEntry en = files.get(uri);
|
||||
if (en != null) en.update();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.FINE, event.context() + " occur erroneous", ex);
|
||||
}
|
||||
});
|
||||
key.reset();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
};
|
||||
this.watchThread.setName("Servlet-ResourceWatch-Thread");
|
||||
this.watchThread.setDaemon(true);
|
||||
this.watchThread = new WatchThread(this.root);
|
||||
this.watchThread.start();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, HttpResourceServlet.class.getSimpleName() + " start watch-thread error", ex);
|
||||
}
|
||||
if (rootstrs != null && rootstrs.length > 1) {
|
||||
resx = new ArrayList<>(rootstrs.length - 1);
|
||||
for (int i = 1; i < rootstrs.length; i++) {
|
||||
try {
|
||||
File f = new File(rootstrs[i]).getCanonicalFile();
|
||||
WatchThread t = new WatchThread(f);
|
||||
t.start();
|
||||
resx.add(new SimpleEntry<>(f, t));
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(Context context, AnyValue config) {
|
||||
if (this.watcher != null) {
|
||||
if (this.watchThread != null) {
|
||||
try {
|
||||
this.watcher.close();
|
||||
this.watchThread.watcher.close();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.log(Level.WARNING, HttpResourceServlet.class.getSimpleName() + " close watch-thread error", ex);
|
||||
}
|
||||
}
|
||||
if (this.watchThread != null && this.watchThread.isAlive()) {
|
||||
this.watchThread.interrupt();
|
||||
if (this.watchThread.isAlive()) this.watchThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,10 +193,10 @@ public final class HttpResourceServlet extends HttpServlet {
|
||||
}
|
||||
if (uri.length() == 0 || uri.equals("/")) uri = "/index.html";
|
||||
//System.out.println(request);
|
||||
FileEntry entry = watcher == null ? createFileEntry(uri) : files.get(uri);
|
||||
FileEntry entry = watchThread == null ? createFileEntry(uri) : files.get(uri);
|
||||
if (entry == null) {
|
||||
entry = createFileEntry(uri);
|
||||
if (entry != null && watcher != null) files.put(uri, entry);
|
||||
if (entry != null && watchThread != null) files.put(uri, entry);
|
||||
}
|
||||
if (entry == null) {
|
||||
response.finish404();
|
||||
@@ -182,12 +207,30 @@ public final class HttpResourceServlet extends HttpServlet {
|
||||
|
||||
private FileEntry createFileEntry(String uri) {
|
||||
File file = new File(root, uri);
|
||||
if (!file.isFile() || !file.canRead()) return null;
|
||||
if (!file.isFile() || !file.canRead()) {
|
||||
if (resx != null) {
|
||||
for (SimpleEntry<File, WatchThread> en : resx) {
|
||||
File f = new File(en.getKey(), uri);
|
||||
if (f.isFile() && f.canRead()) {
|
||||
FileEntry fe = new FileEntry(this, f);
|
||||
if (watchThread == null) return fe;
|
||||
try {
|
||||
Path p = f.getParentFile().toPath();
|
||||
keymaps.put(p.register(en.getValue().watcher, ENTRY_MODIFY, ENTRY_DELETE), p);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.INFO, HttpResourceServlet.class.getSimpleName() + " create FileEntry(" + uri + ") erroneous", e);
|
||||
}
|
||||
return fe;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
FileEntry en = new FileEntry(this, file);
|
||||
if (watcher == null) return en;
|
||||
if (watchThread == null) return en;
|
||||
try {
|
||||
Path p = file.getParentFile().toPath();
|
||||
keymaps.put(p.register(watcher, ENTRY_MODIFY, ENTRY_DELETE), p);
|
||||
keymaps.put(p.register(watchThread.watcher, ENTRY_MODIFY, ENTRY_DELETE), p);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.INFO, HttpResourceServlet.class.getSimpleName() + " create FileEntry(" + uri + ") erroneous", e);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public final class HttpServer extends Server {
|
||||
final int port = this.address.getPort();
|
||||
AtomicLong createBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("HTTP_" + port + ".Buffer.creatCounter");
|
||||
AtomicLong cycleBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("HTTP_" + port + ".Buffer.cycleCounter");
|
||||
int rcapacity = Math.max(this.capacity, 8 * 1024);
|
||||
int rcapacity = Math.max(this.capacity, 16 * 1024 + 8); //兼容 HTTP 2.0
|
||||
ObjectPool<ByteBuffer> bufferPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, this.bufferPoolSize,
|
||||
(Object... params) -> ByteBuffer.allocateDirect(rcapacity), null, (e) -> {
|
||||
if (e == null || e.isReadOnly() || e.capacity() != rcapacity) return false;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
package com.wentch.redkale.net.http;
|
||||
|
||||
import com.wentch.redkale.util.ByteArray;
|
||||
import java.io.*;
|
||||
import java.nio.charset.*;
|
||||
import java.util.*;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
package com.wentch.redkale.source;
|
||||
|
||||
import com.wentch.redkale.source.DataSource;
|
||||
import com.wentch.redkale.source.DistributeGenerator.DistributeTables;
|
||||
import static com.wentch.redkale.source.FilterInfo.formatToString;
|
||||
import com.wentch.redkale.util.*;
|
||||
@@ -351,9 +350,7 @@ public final class DataJDBCSource implements DataSource {
|
||||
EntityInfo<T> info = EntityInfo.load(clazz, this);
|
||||
EntityCache<T> cache = info.getCache();
|
||||
if (cache == null) return;
|
||||
cache.clear();
|
||||
List<T> all = queryList(clazz, null);
|
||||
cache.fullLoad(all);
|
||||
cache.fullLoad(queryList(clazz, null));
|
||||
}
|
||||
|
||||
//----------------------insert-----------------------------
|
||||
@@ -565,22 +562,6 @@ public final class DataJDBCSource implements DataSource {
|
||||
public <T> void delete(Class<T> clazz, Serializable... ids) {
|
||||
Connection conn = createWriteSQLConnection();
|
||||
try {
|
||||
if (ids != null && ids.length == 1 && ids[0] != null && ids[0].getClass().isArray()) {
|
||||
Class clz = ids[0].getClass();
|
||||
if (clz == long[].class) {
|
||||
long[] vs = (long[]) ids[0];
|
||||
ids = new Serializable[vs.length];
|
||||
for (int i = 0; i < vs.length; i++) {
|
||||
ids[i] = vs[i];
|
||||
}
|
||||
} else if (clz == int[].class) {
|
||||
int[] vs = (int[]) ids[0];
|
||||
ids = new Serializable[vs.length];
|
||||
for (int i = 0; i < vs.length; i++) {
|
||||
ids[i] = vs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
delete(conn, clazz, ids);
|
||||
} finally {
|
||||
closeSQLConnection(conn);
|
||||
@@ -641,11 +622,24 @@ public final class DataJDBCSource implements DataSource {
|
||||
try {
|
||||
final EntityXInfo<T> info = EntityXInfo.load(this, clazz);
|
||||
String sql = "DELETE FROM " + info.getTable() + " WHERE " + info.getSQLColumn(column);
|
||||
if (keys.length == 1) {
|
||||
if (keys.length == 1 && !keys[0].getClass().isArray()) {
|
||||
sql += " = " + formatToString(keys[0]);
|
||||
} else {
|
||||
sql += " IN (";
|
||||
boolean flag = false;
|
||||
if (keys.length == 1 && keys[0].getClass().isArray()) {
|
||||
Class keytype = keys[0].getClass();
|
||||
if (keytype.getComponentType().isPrimitive()) {
|
||||
Object array = keys[0];
|
||||
Serializable[] keys0 = new Serializable[Array.getLength(array)];
|
||||
for (int i = 0; i < keys0.length; i++) {
|
||||
keys0[i] = (Serializable) Array.get(array, i);
|
||||
}
|
||||
keys = keys0;
|
||||
} else {
|
||||
keys = (Serializable[]) keys[0];
|
||||
}
|
||||
}
|
||||
for (final Serializable value : keys) {
|
||||
if (flag) sql += ",";
|
||||
sql += formatToString(value);
|
||||
@@ -662,7 +656,8 @@ public final class DataJDBCSource implements DataSource {
|
||||
final EntityCache<T> cache = info.inner.getCache();
|
||||
if (cache == null) return;
|
||||
final Attribute<T, ?> attr = info.getAttribute(column);
|
||||
Serializable[] ids = cache.delete((T t) -> Arrays.binarySearch(keys, attr.get(t)) >= 0);
|
||||
final Serializable[] keys2 = keys;
|
||||
Serializable[] ids = cache.delete((T t) -> Arrays.binarySearch(keys2, attr.get(t)) >= 0);
|
||||
if (cacheListener != null) cacheListener.delete(name, clazz, ids);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -1323,26 +1318,107 @@ public final class DataJDBCSource implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------list----------------------------
|
||||
//-----------------------list set----------------------------
|
||||
@Override
|
||||
public <T> int[] queryColumnIntSet(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
return formatCollectionToIntArray(queryColumnSet(selectedColumn, clazz, column, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long[] queryColumnLongSet(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
return formatCollectionToLongArray(queryColumnSet(selectedColumn, clazz, column, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int[] queryColumnIntList(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
return formatCollectionToIntArray(queryColumnList(selectedColumn, clazz, column, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long[] queryColumnLongList(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
return formatCollectionToLongArray(queryColumnList(selectedColumn, clazz, column, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> Set<V> queryColumnSet(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
return queryColumnSet(selectedColumn, clazz, column, FilterExpress.EQUAL, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> List<V> queryColumnList(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
return queryColumnList(selectedColumn, clazz, column, FilterExpress.EQUAL, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int[] queryColumnIntSet(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
return formatCollectionToIntArray(queryColumnSet(selectedColumn, clazz, column, express, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long[] queryColumnLongSet(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
return formatCollectionToLongArray(queryColumnSet(selectedColumn, clazz, column, express, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int[] queryColumnIntList(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
return formatCollectionToIntArray(queryColumnList(selectedColumn, clazz, column, express, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long[] queryColumnLongList(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
return formatCollectionToLongArray(queryColumnList(selectedColumn, clazz, column, express, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> Set<V> queryColumnSet(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
return (Set<V>) queryColumnCollection(true, selectedColumn, clazz, column, express, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> List<V> queryColumnList(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
return (List<V>) queryColumnCollection(false, selectedColumn, clazz, column, express, key);
|
||||
}
|
||||
|
||||
private static int[] formatCollectionToIntArray(Collection<Integer> collection) {
|
||||
if (collection == null || collection.isEmpty()) return new int[0];
|
||||
int[] rs = new int[collection.size()];
|
||||
int i = 0;
|
||||
for (int v : collection) {
|
||||
rs[i++] = v;
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
|
||||
private static long[] formatCollectionToLongArray(Collection<Long> collection) {
|
||||
if (collection == null || collection.isEmpty()) return new long[0];
|
||||
long[] rs = new long[collection.size()];
|
||||
int i = 0;
|
||||
for (long v : collection) {
|
||||
rs[i++] = v;
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据指定字段值查询对象某个字段的集合
|
||||
*
|
||||
* @param <T>
|
||||
* @param <V>
|
||||
* @param set
|
||||
* @param selectedColumn
|
||||
* @param clazz
|
||||
* @param column
|
||||
* @param express
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public <T, V> List<V> queryColumnList(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
protected final <T, V> Collection<V> queryColumnCollection(final boolean set, String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
final EntityXInfo<T> info = EntityXInfo.load(this, clazz);
|
||||
final EntityCache<T> cache = info.inner.getCache();
|
||||
if (cache != null) {
|
||||
final Attribute<T, ?> attr = info.getAttribute(column);
|
||||
List<T> list = cache.queryList(null, (T t) -> key.equals(attr.get(t)), null);
|
||||
final List<V> rs = new ArrayList<>();
|
||||
Predicate<T> filter = genFilter(info.getAttribute(column), express, key);
|
||||
List<T> list = cache.queryList(SelectColumn.createIncludes(selectedColumn), filter, null);
|
||||
final Collection<V> rs = set ? new LinkedHashSet<>() : new ArrayList<>();
|
||||
if (!list.isEmpty()) {
|
||||
final Attribute<T, V> selected = (Attribute<T, V>) info.getAttribute(selectedColumn);
|
||||
for (T t : list) {
|
||||
@@ -1353,18 +1429,17 @@ public final class DataJDBCSource implements DataSource {
|
||||
}
|
||||
final Connection conn = createReadSQLConnection();
|
||||
try {
|
||||
final List<V> list = new ArrayList();
|
||||
final String sql = "SELECT " + info.getSQLColumn(selectedColumn) + " FROM " + info.getTable() + " WHERE " + info.getSQLColumn(column) + " = ?";
|
||||
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " query sql=" + sql.replaceFirst("\\?", String.valueOf(key)));
|
||||
final PreparedStatement ps = conn.prepareStatement(sql);
|
||||
ps.setObject(1, key);
|
||||
final ResultSet set = ps.executeQuery();
|
||||
while (set.next()) {
|
||||
list.add((V) set.getObject(1));
|
||||
final Collection<V> collection = set ? new LinkedHashSet<>() : new ArrayList<>();
|
||||
final String sql = genSQL(info.getSQLColumn(selectedColumn), info, column, express, key);
|
||||
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " query sql=" + sql);
|
||||
final Statement ps = conn.createStatement();
|
||||
final ResultSet rs = ps.executeQuery(sql);
|
||||
while (rs.next()) {
|
||||
collection.add((V) rs.getObject(1));
|
||||
}
|
||||
set.close();
|
||||
rs.close();
|
||||
ps.close();
|
||||
return list;
|
||||
return collection;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
@@ -1422,55 +1497,7 @@ public final class DataJDBCSource implements DataSource {
|
||||
final EntityXInfo<T> info = EntityXInfo.load(this, clazz);
|
||||
final EntityCache<T> cache = info.inner.getCache();
|
||||
if (cache != null) {
|
||||
final Attribute<T, ?> attr = info.getAttribute(column);
|
||||
Predicate<T> filter = null;
|
||||
switch (express) {
|
||||
case EQUAL:
|
||||
filter = (T t) -> key.equals(attr.get(t));
|
||||
break;
|
||||
case NOTEQUAL:
|
||||
filter = (T t) -> !key.equals(attr.get(t));
|
||||
break;
|
||||
case GREATERTHAN:
|
||||
filter = (T t) -> ((Number) attr.get(t)).longValue() > ((Number) key).longValue();
|
||||
break;
|
||||
case LESSTHAN:
|
||||
filter = (T t) -> ((Number) attr.get(t)).longValue() < ((Number) key).longValue();
|
||||
break;
|
||||
case GREATERTHANOREQUALTO:
|
||||
filter = (T t) -> ((Number) attr.get(t)).longValue() >= ((Number) key).longValue();
|
||||
break;
|
||||
case LESSTHANOREQUALTO:
|
||||
filter = (T t) -> ((Number) attr.get(t)).longValue() <= ((Number) key).longValue();
|
||||
break;
|
||||
case LIKE:
|
||||
filter = (T t) -> {
|
||||
Object rs = attr.get(t);
|
||||
return rs != null && rs.toString().contains(key.toString());
|
||||
};
|
||||
break;
|
||||
case NOTLIKE:
|
||||
filter = (T t) -> {
|
||||
Object rs = attr.get(t);
|
||||
return rs == null || !rs.toString().contains(key.toString());
|
||||
};
|
||||
break;
|
||||
case ISNULL:
|
||||
filter = (T t) -> attr.get(t) == null;
|
||||
break;
|
||||
case ISNOTNULL:
|
||||
filter = (T t) -> attr.get(t) != null;
|
||||
break;
|
||||
case OPAND:
|
||||
filter = (T t) -> (((Number) attr.get(t)).longValue() & ((Number) key).longValue()) > 0;
|
||||
break;
|
||||
case OPOR:
|
||||
filter = (T t) -> (((Number) attr.get(t)).longValue() | ((Number) key).longValue()) > 0;
|
||||
break;
|
||||
case OPANDNO:
|
||||
filter = (T t) -> (((Number) attr.get(t)).longValue() & ((Number) key).longValue()) == 0;
|
||||
break;
|
||||
}
|
||||
Predicate<T> filter = genFilter(info.getAttribute(column), express, key);
|
||||
List<T> rs = cache.queryList(selects, filter, null);
|
||||
if (!rs.isEmpty() || cache.isFullLoaded()) return rs;
|
||||
}
|
||||
@@ -1478,11 +1505,10 @@ public final class DataJDBCSource implements DataSource {
|
||||
try {
|
||||
final SelectColumn sels = selects;
|
||||
final List<T> list = new ArrayList();
|
||||
final String sql = "SELECT * FROM " + info.getTable() + " WHERE " + info.getSQLColumn(column) + " " + express.value() + " ?";
|
||||
final String sql = genSQL("*", info, column, express, key);
|
||||
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " query sql=" + sql);
|
||||
final PreparedStatement ps = conn.prepareStatement(sql);
|
||||
ps.setObject(1, key);
|
||||
final ResultSet set = ps.executeQuery();
|
||||
final Statement ps = conn.createStatement();
|
||||
final ResultSet set = ps.executeQuery(sql);
|
||||
while (set.next()) {
|
||||
final T result = info.createInstance();
|
||||
for (AttributeX<T, Object> attr : info.query.attributes) {
|
||||
@@ -1500,6 +1526,124 @@ public final class DataJDBCSource implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
private String genSQL(String queryColumn, EntityXInfo info, String column, FilterExpress express, Serializable key) {
|
||||
String sql = "SELECT " + queryColumn + " FROM " + info.getTable() + " WHERE " + info.getSQLColumn(column) + " " + express.value();
|
||||
if (key instanceof Number) {
|
||||
sql += " " + key;
|
||||
} else if (key instanceof Collection) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object o : (Collection) key) {
|
||||
if (sb.length() > 0) sb.append(',');
|
||||
if (o instanceof Number) {
|
||||
sb.append('"').append(o).append('"');
|
||||
} else {
|
||||
sb.append('"').append(o.toString().replace("\"", "\\\"")).append('"');
|
||||
}
|
||||
}
|
||||
sql += " (" + sb + ")";
|
||||
} else if (key.getClass().isArray()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int len = Array.getLength(key);
|
||||
for (int i = 0; i < len; i++) {
|
||||
Object o = Array.get(key, i);
|
||||
if (sb.length() > 0) sb.append(',');
|
||||
if (o instanceof Number) {
|
||||
sb.append('"').append(o).append('"');
|
||||
} else {
|
||||
sb.append('"').append(o.toString().replace("\"", "\\\"")).append('"');
|
||||
}
|
||||
}
|
||||
sql += " (" + sb + ")";
|
||||
} else {
|
||||
sql += " \"" + key.toString().replace("\"", "\\\"") + "\"";
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
private <T> Predicate<T> genFilter(final Attribute<T, ?> attr, FilterExpress express, Serializable key) {
|
||||
Predicate<T> filter = null;
|
||||
switch (express) {
|
||||
case EQUAL:
|
||||
filter = (T t) -> key.equals(attr.get(t));
|
||||
break;
|
||||
case NOTEQUAL:
|
||||
filter = (T t) -> !key.equals(attr.get(t));
|
||||
break;
|
||||
case GREATERTHAN:
|
||||
filter = (T t) -> ((Number) attr.get(t)).longValue() > ((Number) key).longValue();
|
||||
break;
|
||||
case LESSTHAN:
|
||||
filter = (T t) -> ((Number) attr.get(t)).longValue() < ((Number) key).longValue();
|
||||
break;
|
||||
case GREATERTHANOREQUALTO:
|
||||
filter = (T t) -> ((Number) attr.get(t)).longValue() >= ((Number) key).longValue();
|
||||
break;
|
||||
case LESSTHANOREQUALTO:
|
||||
filter = (T t) -> ((Number) attr.get(t)).longValue() <= ((Number) key).longValue();
|
||||
break;
|
||||
case IN:
|
||||
case NOTIN:
|
||||
if (key instanceof Collection) {
|
||||
filter = (T t) -> {
|
||||
Object rs = attr.get(t);
|
||||
return rs != null && ((Collection) key).contains(rs);
|
||||
};
|
||||
} else {
|
||||
Serializable[] keys;
|
||||
if (key.getClass().isArray()) {
|
||||
Class keytype = key.getClass();
|
||||
if (keytype.getComponentType().isPrimitive()) {
|
||||
Object array = key;
|
||||
Serializable[] keys0 = new Serializable[Array.getLength(array)];
|
||||
for (int i = 0; i < keys0.length; i++) {
|
||||
keys0[i] = (Serializable) Array.get(array, i);
|
||||
}
|
||||
keys = keys0;
|
||||
} else {
|
||||
keys = (Serializable[]) key;
|
||||
}
|
||||
} else {
|
||||
keys = new Serializable[]{key};
|
||||
}
|
||||
Serializable[] keys0 = keys;
|
||||
filter = (T t) -> {
|
||||
Object rs = attr.get(t);
|
||||
return rs != null && Arrays.binarySearch(keys0, rs) > -1;
|
||||
};
|
||||
}
|
||||
if (express == FilterExpress.NOTIN) filter = filter.negate();
|
||||
break;
|
||||
case LIKE:
|
||||
filter = (T t) -> {
|
||||
Object rs = attr.get(t);
|
||||
return rs != null && rs.toString().contains(key.toString());
|
||||
};
|
||||
break;
|
||||
case NOTLIKE:
|
||||
filter = (T t) -> {
|
||||
Object rs = attr.get(t);
|
||||
return rs == null || !rs.toString().contains(key.toString());
|
||||
};
|
||||
break;
|
||||
case ISNULL:
|
||||
filter = (T t) -> attr.get(t) == null;
|
||||
break;
|
||||
case ISNOTNULL:
|
||||
filter = (T t) -> attr.get(t) != null;
|
||||
break;
|
||||
case OPAND:
|
||||
filter = (T t) -> (((Number) attr.get(t)).longValue() & ((Number) key).longValue()) > 0;
|
||||
break;
|
||||
case OPOR:
|
||||
filter = (T t) -> (((Number) attr.get(t)).longValue() | ((Number) key).longValue()) > 0;
|
||||
break;
|
||||
case OPANDNO:
|
||||
filter = (T t) -> (((Number) attr.get(t)).longValue() & ((Number) key).longValue()) == 0;
|
||||
break;
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据过滤对象FilterBean查询对象集合
|
||||
*
|
||||
@@ -1528,6 +1672,33 @@ public final class DataJDBCSource implements DataSource {
|
||||
}
|
||||
|
||||
//-----------------------sheet----------------------------
|
||||
/**
|
||||
* 根据指定参数查询对象某个字段的集合
|
||||
* <p>
|
||||
* @param <T>
|
||||
* @param <V>
|
||||
* @param selectedColumn
|
||||
* @param clazz
|
||||
* @param flipper
|
||||
* @param bean
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public <T, V> Sheet<V> queryColumnSheet(String selectedColumn, Class<T> clazz, final Flipper flipper, final FilterBean bean) {
|
||||
Sheet<T> sheet = querySheet(clazz, SelectColumn.createIncludes(selectedColumn), flipper, bean);
|
||||
final Sheet<V> rs = new Sheet<>();
|
||||
if (sheet.isEmpty()) return rs;
|
||||
rs.setTotal(sheet.getTotal());
|
||||
final EntityXInfo<T> info = EntityXInfo.load(this, clazz);
|
||||
final Attribute<T, V> selected = (Attribute<T, V>) info.getAttribute(selectedColumn);
|
||||
final List<V> list = new ArrayList<>();
|
||||
for (T t : sheet.getRows()) {
|
||||
list.add(selected.get(t));
|
||||
}
|
||||
rs.setRows(list);
|
||||
return rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据过滤对象FilterBean和翻页对象Flipper查询一页的数据
|
||||
*
|
||||
@@ -1558,18 +1729,14 @@ public final class DataJDBCSource implements DataSource {
|
||||
final EntityCache<T> cache = info.inner.getCache();
|
||||
if (cache != null) {
|
||||
Predicate<T> filter = null;
|
||||
Comparator<T> sort = null;
|
||||
boolean valid = true;
|
||||
if (bean != null) {
|
||||
FilterInfo finfo = FilterInfo.load(bean.getClass(), this);
|
||||
valid = finfo.isValidCacheJoin();
|
||||
if (valid) {
|
||||
filter = finfo.getFilterPredicate(info.inner, bean);
|
||||
sort = finfo.getSortComparator(info.inner, flipper);
|
||||
}
|
||||
if (valid) filter = finfo.getFilterPredicate(info.inner, bean);
|
||||
}
|
||||
if (valid) {
|
||||
Sheet<T> sheet = cache.querySheet(selects, filter, flipper, sort);
|
||||
Sheet<T> sheet = cache.querySheet(selects, filter, flipper, FilterInfo.getSortComparator(info.inner, flipper));
|
||||
if (!sheet.isEmpty() || cache.isFullLoaded()) return sheet;
|
||||
}
|
||||
}
|
||||
@@ -2084,7 +2251,7 @@ public final class DataJDBCSource implements DataSource {
|
||||
}
|
||||
|
||||
public void createPrimaryValue(T src) {
|
||||
long v = primaryValue.incrementAndGet() * allocationSize + nodeid;
|
||||
long v = allocationSize > 1 ? (primaryValue.incrementAndGet() * allocationSize + nodeid) : primaryValue.incrementAndGet();
|
||||
Class p = inner.getPrimaryType();
|
||||
if (p == int.class || p == Integer.class) {
|
||||
getPrimary().set(src, (Integer) ((Long) v).intValue());
|
||||
|
||||
@@ -59,6 +59,66 @@ final class DataJPASource implements DataSource {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> Sheet<V> queryColumnSheet(String selectedColumn, Class<T> clazz, Flipper flipper, FilterBean bean) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> Set<V> queryColumnSet(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> Set<V> queryColumnSet(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> List<V> queryColumnList(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int[] queryColumnIntSet(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long[] queryColumnLongSet(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int[] queryColumnIntList(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long[] queryColumnLongList(String selectedColumn, Class<T> clazz, String column, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int[] queryColumnIntSet(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long[] queryColumnLongSet(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int[] queryColumnIntList(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long[] queryColumnLongList(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
private static class DataJPAConnection extends DataConnection {
|
||||
|
||||
private final EntityManager manager;
|
||||
|
||||
@@ -330,7 +330,28 @@ public interface DataSource {
|
||||
*/
|
||||
public <T> T find(final Class<T> clazz, final FilterBean bean);
|
||||
|
||||
//-----------------------list----------------------------
|
||||
//-----------------------list set----------------------------
|
||||
public <T> int[] queryColumnIntSet(String selectedColumn, Class<T> clazz, String column, Serializable key);
|
||||
|
||||
public <T> long[] queryColumnLongSet(String selectedColumn, Class<T> clazz, String column, Serializable key);
|
||||
|
||||
public <T> int[] queryColumnIntList(String selectedColumn, Class<T> clazz, String column, Serializable key);
|
||||
|
||||
public <T> long[] queryColumnLongList(String selectedColumn, Class<T> clazz, String column, Serializable key);
|
||||
|
||||
/**
|
||||
* 根据指定字段值查询对象某个字段的集合
|
||||
*
|
||||
* @param <T>
|
||||
* @param <V>
|
||||
* @param selectedColumn
|
||||
* @param clazz
|
||||
* @param column
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public <T, V> Set<V> queryColumnSet(String selectedColumn, Class<T> clazz, String column, Serializable key);
|
||||
|
||||
/**
|
||||
* 根据指定字段值查询对象某个字段的集合
|
||||
*
|
||||
@@ -344,6 +365,42 @@ public interface DataSource {
|
||||
*/
|
||||
public <T, V> List<V> queryColumnList(String selectedColumn, Class<T> clazz, String column, Serializable key);
|
||||
|
||||
public <T> int[] queryColumnIntSet(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key);
|
||||
|
||||
public <T> long[] queryColumnLongSet(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key);
|
||||
|
||||
public <T> int[] queryColumnIntList(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key);
|
||||
|
||||
public <T> long[] queryColumnLongList(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key);
|
||||
|
||||
/**
|
||||
* 根据指定字段值查询对象某个字段的集合
|
||||
*
|
||||
* @param <T>
|
||||
* @param <V>
|
||||
* @param selectedColumn
|
||||
* @param clazz
|
||||
* @param column
|
||||
* @param express
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public <T, V> Set<V> queryColumnSet(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key);
|
||||
|
||||
/**
|
||||
* 根据指定字段值查询对象某个字段的集合
|
||||
*
|
||||
* @param <T>
|
||||
* @param <V>
|
||||
* @param selectedColumn
|
||||
* @param clazz
|
||||
* @param column
|
||||
* @param express
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public <T, V> List<V> queryColumnList(String selectedColumn, Class<T> clazz, String column, FilterExpress express, Serializable key);
|
||||
|
||||
/**
|
||||
* 根据指定字段值查询对象集合
|
||||
*
|
||||
@@ -415,6 +472,19 @@ public interface DataSource {
|
||||
public <T> List<T> queryList(final Class<T> clazz, final SelectColumn selects, final FilterBean bean);
|
||||
|
||||
//-----------------------sheet----------------------------
|
||||
/**
|
||||
* 根据指定参数查询对象某个字段的集合
|
||||
* <p>
|
||||
* @param <T>
|
||||
* @param <V>
|
||||
* @param selectedColumn
|
||||
* @param clazz
|
||||
* @param flipper
|
||||
* @param bean
|
||||
* @return
|
||||
*/
|
||||
public <T, V> Sheet<V> queryColumnSheet(String selectedColumn, Class<T> clazz, final Flipper flipper, final FilterBean bean);
|
||||
|
||||
/**
|
||||
* 根据过滤对象FilterBean和翻页对象Flipper查询一页的数据
|
||||
*
|
||||
|
||||
@@ -35,5 +35,10 @@ public @interface DistributeGenerator {
|
||||
|
||||
int initialValue() default 1;
|
||||
|
||||
/**
|
||||
* 如果allocationSize的值小于或等于1,则主键不会加上nodeid
|
||||
* <p>
|
||||
* @return
|
||||
*/
|
||||
int allocationSize() default 1000;
|
||||
}
|
||||
|
||||
@@ -96,9 +96,9 @@ final class EntityCache<T> {
|
||||
return rs.isPresent() ? (needcopy ? reproduce.copy(this.creator.create(), rs.get()) : rs.get()) : null;
|
||||
}
|
||||
|
||||
public List<T> queryList(final SelectColumn selects, final Predicate<T> filter, final Comparator<T> sort) {
|
||||
public Collection<T> queryCollection(final boolean set, final SelectColumn selects, final Predicate<T> filter, final Comparator<T> sort) {
|
||||
boolean parallel = isParallel();
|
||||
final List<T> rs = parallel ? new CopyOnWriteArrayList<>() : new ArrayList<>();
|
||||
final Collection<T> rs = parallel ? (set ? new CopyOnWriteArraySet<>() : new CopyOnWriteArrayList<>()) : (set ? new LinkedHashSet<>() : new ArrayList<>());
|
||||
Stream<T> stream = listStream();
|
||||
if (filter != null) stream = stream.filter(filter);
|
||||
if (sort != null) stream = stream.sorted(sort);
|
||||
@@ -115,7 +115,15 @@ final class EntityCache<T> {
|
||||
rs.add(item);
|
||||
});
|
||||
}
|
||||
return parallel ? new ArrayList<>(rs) : rs;
|
||||
return parallel ? (set ? new LinkedHashSet<>(rs) : new ArrayList<>(rs)) : rs;
|
||||
}
|
||||
|
||||
public Set<T> querySet(final SelectColumn selects, final Predicate<T> filter, final Comparator<T> sort) {
|
||||
return (Set<T>) queryCollection(true, selects, filter, sort);
|
||||
}
|
||||
|
||||
public List<T> queryList(final SelectColumn selects, final Predicate<T> filter, final Comparator<T> sort) {
|
||||
return (List<T>) queryCollection(false, selects, filter, sort);
|
||||
}
|
||||
|
||||
public Sheet<T> querySheet(final SelectColumn selects, final Predicate<T> filter, final Flipper flipper, final Comparator<T> sort) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Logger;
|
||||
import javax.persistence.*;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -60,6 +61,7 @@ final class FilterInfo<T extends FilterBean> {
|
||||
do {
|
||||
for (Field field : cltmp.getDeclaredFields()) {
|
||||
if (field.getAnnotation(Ignore.class) != null) continue;
|
||||
if (field.getAnnotation(Transient.class) != null) continue;
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
if (fields.contains(field.getName())) continue;
|
||||
char[] chars = field.getName().toCharArray();
|
||||
@@ -155,7 +157,7 @@ final class FilterInfo<T extends FilterBean> {
|
||||
return rootNode.getFilterPredicate(info, bean);
|
||||
}
|
||||
|
||||
public <E> Comparator<E> getSortComparator(EntityInfo<E> info, Flipper flipper) {
|
||||
public static <E> Comparator<E> getSortComparator(EntityInfo<E> info, Flipper flipper) {
|
||||
if (flipper == null || flipper.getSort() == null || flipper.getSort().isEmpty()) return null;
|
||||
Comparator<E> comparator = null;
|
||||
for (String item : flipper.getSort().split(",")) {
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.http;
|
||||
package com.wentch.redkale.util;
|
||||
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.nio.*;
|
||||
import java.nio.charset.*;
|
||||
|
||||
@@ -55,6 +54,10 @@ public final class ByteArray {
|
||||
System.arraycopy(this.content, 0, buf, 0, count);
|
||||
}
|
||||
|
||||
public byte[] directBytes() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public int find(int offset, char value) {
|
||||
return find(offset, (byte) value);
|
||||
}
|
||||
@@ -80,6 +83,10 @@ public final class ByteArray {
|
||||
if (count > 0) count--;
|
||||
}
|
||||
|
||||
public void addInt(int value) {
|
||||
add((byte) (value >> 24 & 0xFF), (byte) (value >> 16 & 0xFF), (byte) (value >> 8 & 0xFF), (byte) (value & 0xFF));
|
||||
}
|
||||
|
||||
public void add(byte value) {
|
||||
if (count >= content.length - 1) {
|
||||
byte[] ns = new byte[content.length + 8];
|
||||
@@ -89,6 +96,16 @@ public final class ByteArray {
|
||||
content[count++] = value;
|
||||
}
|
||||
|
||||
public void add(byte... values) {
|
||||
if (count >= content.length - values.length) {
|
||||
byte[] ns = new byte[content.length + values.length];
|
||||
System.arraycopy(content, 0, ns, 0, count);
|
||||
this.content = ns;
|
||||
}
|
||||
System.arraycopy(content, count, values, 0, values.length);
|
||||
count += values.length;
|
||||
}
|
||||
|
||||
public void add(ByteBuffer buffer, int len) {
|
||||
if (len < 1) return;
|
||||
if (count >= content.length - len) {
|
||||
@@ -78,10 +78,18 @@ public final class Utility {
|
||||
return today.getYear() * 10000 + today.getMonthValue() * 100 + today.getDayOfMonth();
|
||||
}
|
||||
|
||||
public static String binToHexString(byte[] bytes) {
|
||||
return new String(binToHex(bytes));
|
||||
}
|
||||
|
||||
public static char[] binToHex(byte[] bytes) {
|
||||
return binToHex(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
public static String binToHexString(byte[] bytes, int offset, int len) {
|
||||
return new String(binToHex(bytes, offset, len));
|
||||
}
|
||||
|
||||
public static char[] binToHex(byte[] bytes, int offset, int len) {
|
||||
final char[] sb = new char[len * 2];
|
||||
final int end = offset + len;
|
||||
|
||||
Reference in New Issue
Block a user