Commit 8b56bbc5 authored by 楊慶堂's avatar 楊慶堂

加上 synchronized 減少資料庫查詢次數

parent cd5e8822
...@@ -22,6 +22,8 @@ import org.slf4j.LoggerFactory; ...@@ -22,6 +22,8 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
/** */ /** */
public class I18NReadEventListener implements PostLoadEventListener { public class I18NReadEventListener implements PostLoadEventListener {
...@@ -32,6 +34,8 @@ public class I18NReadEventListener implements PostLoadEventListener { ...@@ -32,6 +34,8 @@ public class I18NReadEventListener implements PostLoadEventListener {
private SessionFactoryImplementor sessionFactory; private SessionFactoryImplementor sessionFactory;
private Interner<String> pool = Interners.newWeakInterner();
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private Cache<String, Map> cache = private Cache<String, Map> cache =
CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.MINUTES).build(); CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.MINUTES).build();
...@@ -80,7 +84,7 @@ public class I18NReadEventListener implements PostLoadEventListener { ...@@ -80,7 +84,7 @@ public class I18NReadEventListener implements PostLoadEventListener {
* @throws InvocationTargetException * @throws InvocationTargetException
*/ */
private Map<String, String> getTranslate( private Map<String, String> getTranslate(
StatelessSession session, I18NTranslates i18n, Object entity, Class clazz) StatelessSession session, I18NTranslates i18n, Object entity, @SuppressWarnings("rawtypes") Class clazz)
throws IllegalAccessException, InvocationTargetException { throws IllegalAccessException, InvocationTargetException {
Object id = getPKValue(clazz, entity); Object id = getPKValue(clazz, entity);
String language = LocaleContextHolder.getLocale().toString(); String language = LocaleContextHolder.getLocale().toString();
...@@ -93,6 +97,7 @@ public class I18NReadEventListener implements PostLoadEventListener { ...@@ -93,6 +97,7 @@ public class I18NReadEventListener implements PostLoadEventListener {
return translateTable.get(id); return translateTable.get(id);
} }
@SuppressWarnings("unchecked")
private Map<String, Map<String, String>> translateTable( private Map<String, Map<String, String>> translateTable(
StatelessSession session, StatelessSession session,
String table, String table,
...@@ -101,12 +106,16 @@ public class I18NReadEventListener implements PostLoadEventListener { ...@@ -101,12 +106,16 @@ public class I18NReadEventListener implements PostLoadEventListener {
String idColumn) { String idColumn) {
String key = "Table:" + table + "_" + language; String key = "Table:" + table + "_" + language;
Map<String, Map<String, String>> result = cache.getIfPresent(key); Map<String, Map<String, String>> result = cache.getIfPresent(key);
if (result == null) {
synchronized (pool.intern(key)) {
result = cache.getIfPresent(key);
if (result == null) { if (result == null) {
logger.trace("translate query, table: {}", table); logger.trace("translate query, table: {}", table);
String sql = String.format("select * from %s where languageCode = ?", table); String sql = String.format("select * from %s where languageCode = ?", table);
SQLQuery query1 = session.createSQLQuery(sql); SQLQuery query1 = session.createSQLQuery(sql);
query1.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); query1.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
query1.addScalar(idColumn); query1.addScalar(idColumn);
query1.addScalar("languageCode");
for (I18NTranslate i18nTranslate : mapping) { for (I18NTranslate i18nTranslate : mapping) {
query1.addScalar(i18nTranslate.column()); query1.addScalar(i18nTranslate.column());
} }
...@@ -114,13 +123,17 @@ public class I18NReadEventListener implements PostLoadEventListener { ...@@ -114,13 +123,17 @@ public class I18NReadEventListener implements PostLoadEventListener {
List<Map<String, String>> result1 = query1.list(); List<Map<String, String>> result1 = query1.list();
result = new HashMap<>(); result = new HashMap<>();
for (Map<String, String> map : result1) { for (Map<String, String> map : result1) {
map.remove("languageCode");
result.put(map.get(idColumn), map); result.put(map.get(idColumn), map);
} }
cache.put(key, result); cache.put(key, result);
} }
}
}
return result; return result;
} }
private Object getPKValue(Class<?> clazz, Object entity) private Object getPKValue(Class<?> clazz, Object entity)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Collection<Field> fields = getAllDeclaredFields(clazz); Collection<Field> fields = getAllDeclaredFields(clazz);
...@@ -132,29 +145,11 @@ public class I18NReadEventListener implements PostLoadEventListener { ...@@ -132,29 +145,11 @@ public class I18NReadEventListener implements PostLoadEventListener {
} }
for (Method method : clazz.getDeclaredMethods()) { for (Method method : clazz.getDeclaredMethods()) {
if (method.getAnnotation(Id.class) != null) { if (method.getAnnotation(Id.class) != null) {
return method.invoke(entity, null); return method.invoke(entity);
} }
} }
return null; return null;
} }
/**
* Returns the entity's @{@link I18NTranslate} fields.
*
* <p>These fields are made accessible.
*/
private static Collection<Field> getLocalizedFields(Class<?> clazz) {
Collection<Field> fields = getAllDeclaredFields(clazz);
List<Field> localizedFields = new ArrayList<>();
fields
.stream()
.filter(field -> field.getAnnotation(I18NTranslate.class) != null)
.forEach(
field -> {
field.setAccessible(true);
localizedFields.add(field);
});
return localizedFields;
}
private static Collection<Field> getAllDeclaredFields(Class<?> clazz) { private static Collection<Field> getAllDeclaredFields(Class<?> clazz) {
List<Field> fields = new ArrayList<>(); List<Field> fields = new ArrayList<>();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment