Неделю назад MyBatis и Apache ignite объявили о поддержке apache ignite в качестве кеша MyBatis (кеш L2).
технически MyBatis поддерживает два уровня кэширования:
- Локальный кеш, который всегда включен по умолчанию
- L2 кеш, опционально
Поскольку проект Apache Ignite быстро развивается с его различными функциональными возможностями, в этом посте мы рассмотрим поддержку MyBatis в некоторых деталях.
Кэш второго уровня хранит данные сущностей, но НЕ сами сущности или объекты. Данные хранятся в «сериализованном» формате, который выглядит как хэш-карта, где ключ — это идентификатор объекта, а значение — это список примитивных значений.
Вот пример того, как записи кэша выглядят в Apache ignite:
- Ключ кеша :
1
CacheKey [idHash=1499858,
hash
=2019660929, checksum=800710994, count=6, multiplier=37, hashcode=2019660929, updateList=[com.blu.ignite.mapper.UserMapper.getUserObject, 0, 2147483647, SELECT * FROM all_objects t where t.OBJECT_TYPE=
'TABLE'
and t.object_name=?, USERS, SqlSessionFactoryBean]]
- Класс значения :
java.util.ArrayList
- Значение кэша :
1
[UserObject [idHash=243119413,
hash
=1658511469, owner=C
##DONOTDELETE, object_type=TABLE, object_id=94087, created=Mon Feb 15 13:59:41 MSK 2016, object_name=USERS]]
Как и в примере, я выбрал объекты ‘all_objects’ и следующий запрос из базы данных Oracle
1
2
3
4
5
|
SELECT count (*) FROM all_objects; SELECT * FROM all_objects t where t.OBJECT_TYPE= 'TABLE' and t.object_name= 'EMP' ; SELECT * FROM all_objects t where t.OBJECT_TYPE= 'TABLE' ; |
В моем случае это время выполнения данного запроса составляет в среднем ~ 660 мс.
1
|
SELECT count (*) FROM all_objects; |
Время выполнения следующего запроса составляет более 700 мс:
1
|
SELECT t.object_type, count (*) FROM all_objects t group by t.OBJECT_TYPE; |
давайте добавим apache ignite в качестве кэша второго уровня и рассмотрим результат. Если вы хотите узнать, как установить и настроить apache ignite с помощью spring и myBatis, обратитесь к моему предыдущему сообщению в блоге . Более того, все источники вы можете найти в репозиториях GitHub .
Для начала давайте добавим в проект зависимость myBatis maven.
1
2
3
4
5
|
< dependency > < groupId >org.mybatis.caches</ groupId > < artifactId >mybatis-ignite</ artifactId > < version >1.0.0-beta1</ version > </ dependency > |
Затем просто укажите его в XML-преобразователе следующим образом
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
< mapper namespace = "com.blu.ignite.mapper.UserMapper" > < cache type = "org.mybatis.caches.ignite.IgniteCacheAdapter" /> < select id = "getUserObject" parameterType = "String" resultType = "com.blu.ignite.dto.UserObject" useCache = "true" > SELECT * FROM all_objects t where t.OBJECT_TYPE='TABLE' and t.object_name=#{objectName} </ select > < select id = "getAllObjectsTypeByGroup" parameterType = "String" resultType = "com.blu.ignite.dto.UobjectGroupBy" useCache = "true" > SELECT t.object_type, count(*) as cnt FROM all_objects t group by t.OBJECT_TYPE </ select > < select id = "allObjectCount" parameterType = "String" resultType = "String" useCache = "true" > SELECT count(*) FROM all_objects </ select > </ mapper > |
Также у меня есть следующий Java-картограф:
1
2
3
4
5
6
7
|
public interface UserMapper { User getUser( String id); List getUniqueJob(); UserObject getUserObject(String objectName); String allObjectCount(); List getAllObjectsTypeByGroup(); } |
и веб-сервис следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@WebService (name = "BusinessRulesServices" , serviceName= "BusinessRulesServices" , public class WebServices { private UserServices userServices; @WebMethod (operationName = "getUserName" ) public String getUserName(String userId){ User user = userServices.getUser(userId); return user.getuName(); } @WebMethod (operationName = "getUserObject" ) public UserObject getUserObject(String objectName){ return userServices.getUserObject(objectName); } @WebMethod (operationName = "getUniqueJobs" ) public List getUniqueJobs(){ return userServices.getUniqueJobs(); } @WebMethod (exclude = true ) public void setDao(UserServices userServices){ this .userServices = userServices; } @WebMethod (operationName = "allObjectCount" ) public String allObjectCount(){ return userServices.allObjectCount(); } @WebMethod (operationName = "getAllObjectsTypeCntByGroup" ) public List getAllObjectsTypeCntByGroup(){ return userServices.getAllObjectCntbyGroup(); } } |
Если я вызову веб-метод ‘getAllObjectsTypeCntByGroup’ в soupUI, в первый раз он получит очень большое время отклика, приблизительно 1700 мс, потому что результат отсутствует в кэше. Со второго раза время отклика составит от ~ 4 до ~ 5 мс.
Вызов веб-метода в первый раз будет выглядеть так:
Время ответа второго или более позднего вызова веб-метода
В apache ignite cache запись будет выглядеть следующим образом:
- Ключ кеша :
1
CacheKey [idHash=46158416,
hash
=1558187086, checksum=2921583030, count=5, multiplier=37, hashcode=1558187086, updateList=[com.blu.ignite.mapper.UserMapper.getAllObjectsTypeByGroup, 0, 2147483647, SELECT t.object_type, count(*) as cnt FROM all_objects t group by t.OBJECT_TYPE, SqlSessionFactoryBean]]
- Класс значения :
java.util.ArrayList
- Значение кэша :
1
[UobjectGroupBy [idHash=2103707742,
hash
=1378996400, cnt=1, object_type=EDITION], UobjectGroupBy [idHash=333378159,
hash
=872886462, cnt=444, object_type=INDEX PARTITION], UobjectGroupBy [idHash=756814918,
hash
=1462794064, cnt=32, object_type=TABLE SUBPARTITION], UobjectGroupBy [idHash=931078572,
hash
=953621437, cnt=2, object_type=CONSUMER GROUP], UobjectGroupBy [idHash=1778706917,
hash
=1681913927, cnt=256, object_type=SEQUENCE], UobjectGroupBy [idHash=246231872,
hash
=1764800190, cnt=519, object_type=TABLE PARTITION], UobjectGroupBy [idHash=1138665719,
hash
=1030673983, cnt=4, object_type=SCHEDULE], UobjectGroupBy [idHash=232948577,
hash
=1038362844, cnt=1, object_type=RULE], UobjectGroupBy [idHash=1080301817,
hash
=646054631, cnt=310, object_type=JAVA DATA], UobjectGroupBy [idHash=657724550,
hash
=1248576975, cnt=201, object_type=PROCEDURE], UobjectGroupBy [idHash=295410055,
hash
=33504659, cnt=54, object_type=OPERATOR], UobjectGroupBy [idHash=150727006,
hash
=499210168, cnt=2, object_type=DESTINATION], UobjectGroupBy [idHash=1865360077,
hash
=727903197, cnt=9, object_type=WINDOW], UobjectGroupBy [idHash=582342926,
hash
=1060308675, cnt=4, object_type=SCHEDULER GROUP], UobjectGroupBy [idHash=1968399647,
hash
=1205380883, cnt=1306, object_type=PACKAGE], UobjectGroupBy [idHash=1495061270,
hash
=1345537223, cnt=1245, object_type=PACKAGE BODY], UobjectGroupBy [idHash=1328790450,
hash
=1823695135, cnt=228, object_type=LIBRARY], UobjectGroupBy [idHash=1128429299,
hash
=1267824468, cnt=10, object_type=PROGRAM], UobjectGroupBy [idHash=760711193,
hash
=1240703242, cnt=17, object_type=RULE SET], UobjectGroupBy [idHash=317487814,
hash
=61657487, cnt=10, object_type=CONTEXT], UobjectGroupBy [idHash=1079028994,
hash
=1960895356, cnt=229, object_type=TYPE BODY], UobjectGroupBy [idHash=276147733,
hash
=873140579, cnt=44, object_type=XML SCHEMA], UobjectGroupBy [idHash=24378178,
hash
=1621363993, cnt=1014, object_type=JAVA RESOURCE], UobjectGroupBy [idHash=1891142624,
hash
=90282027, cnt=10, object_type=DIRECTORY], UobjectGroupBy [idHash=902107208,
hash
=1995006200, cnt=593, object_type=TRIGGER], UobjectGroupBy [idHash=142411235,
hash
=444983119, cnt=14, object_type=JOB CLASS], UobjectGroupBy [idHash=373966405,
hash
=1518992835, cnt=3494, object_type=INDEX], UobjectGroupBy [idHash=580466919,
hash
=1394644601, cnt=2422, object_type=TABLE], UobjectGroupBy [idHash=1061370796,
hash
=1861472837, cnt=37082, object_type=SYNONYM], UobjectGroupBy [idHash=1609659322,
hash
=1543110475, cnt=6487, object_type=VIEW], UobjectGroupBy [idHash=458063471,
hash
=1317758482, cnt=346, object_type=FUNCTION], UobjectGroupBy [idHash=1886921697,
hash
=424653540, cnt=7, object_type=INDEXTYPE], UobjectGroupBy [idHash=1455482905,
hash
=1776171634, cnt=30816, object_type=JAVA CLASS], UobjectGroupBy [idHash=49819096,
hash
=2110362533, cnt=2, object_type=JAVA SOURCE], UobjectGroupBy [idHash=1916179950,
hash
=1760023032, cnt=10, object_type=CLUSTER], UobjectGroupBy [idHash=1138808674,
hash
=215713426, cnt=2536, object_type=TYPE], UobjectGroupBy [idHash=305229607,
hash
=340664529, cnt=23, object_type=JOB], UobjectGroupBy [idHash=1365509716,
hash
=623631686, cnt=12, object_type=EVALUATION CONTEXT]]
Вывод
Использование дорогостоящей базы данных можно сократить с помощью кэша L2, а правильное использование кэша L2 в MyBatis может повысить производительность приложения от 10 до 20 раз. Apache Ignite в сетке данных памяти является очень подходящим кандидатом для этой цели, конечно, вы также можете использовать Hazelcash, EhCache или любые другие инструменты кэширования.
Ссылка: | Подводные камни кэшей MyBatis с помощью Apache Ignite от нашего партнера по JCG Шамима Бхуияна в блоге My workspace . |