مقدمة
ما هو ذاكرة التخزين المؤقت MyBatis Level 2؟
تتم مشاركة ذاكرة التخزين المؤقت الثانوية بواسطة SQLSessions متعددة ، ونطاقها هو نفس مساحة اسم الخريطة.
وهذا هو ، في SQLSessions المختلفة ، تحت نفس مساحة الاسم ، نفس عبارة SQL ، والمعلمات في قالب SQL هي أيضًا نفسها ، وسيتم ضرب ذاكرة التخزين المؤقت.
بعد التنفيذ الأول ، سيتم كتابة البيانات التي تم الاستعلام عنها في قاعدة البيانات إلى ذاكرة التخزين المؤقت ، وسيتم استرداد البيانات من ذاكرة التخزين المؤقت بعد الآن من قاعدة البيانات ، وبالتالي تحسين كفاءة الاستعلام.
لا يمكّن MyBatis ذاكرة التخزين المؤقت الثانوية بشكل افتراضي ، ومن الضروري تمكين ذاكرة التخزين المؤقت الثانوية في التكوين العالمي (mybatis-config.xml).
تصف هذه المقالة طريقة استخدام Redis كذاكرة التخزين المؤقت للتكامل مع Springboot و MyBatis.
1. تبعية بوم
استخدم حزمة تكامل Redis Springboot لتسهيل الوصول إلى Redis. يستخدم Jedis على عميل Redis.
بالإضافة إلى ذلك ، سيتم تسلسل وقراءة ذاكرة التخزين المؤقت KV وكتابة ، لذلك يتم تقديم حزمة التسلسل.
<Rependency> <roupeD> org.springframework.boot </rougiD> <insifactid> Spring-Boot-Starter-Redis </shintifactid> </sependency> <reperence> <roupid> redis.clients </rougiD> <roupl> com.alibaba </rougiD> <intifactid> fastjson </stifactid> <soph>
بعد الانتهاء من التبعية ، فإن الخطوة التالية هي ضبط عميل REDIS.
2. الفاصوليا المستخدمة عن طريق وصول redis
أضف التكوين ، وتكوين Bean JedisconnectionFactory ، واتركه للاستخدام لاحقًا.
بشكل عام ، سيتم أيضًا إنشاء Bean Redistemplate ، ولكن لا يتم استخدامه في السيناريو التالي.
ConfigurationPublic class redisconfig {value ("$ {spring.redis.host}") مضيف سلسلة خاصة ؛ . config.setMaxidle (maxidle) ؛ config.setMaxTotal (maxtotal) ؛ config.setMaxWaitMillis (maxwaitmillis) ؛ config.setMinidle (minidle) ؛ إرجاع التكوين. } bean (name = "jedisconnectionfactory") public jedisconnectionfactory getConnectionFactory () {jedisconnectionfactory factory = new JedisconnectionFactory () ؛ JedispoolConfig config = getRedisconFig () ؛ Factory.SetPoolConfig (config) ؛ Factory.SethostName (مضيف) ؛ Factory.SetPort (Port) ؛ Factory.SetDatabase (قاعدة البيانات) ؛ Factory.SetPassword (كلمة المرور) ؛ المصنع. عودة المصنع } bean (name = "redistemplate") public redistemplate <؟ قالب العودة. }}هنا ، يتم استخدام Value لقراءة التكوين المتعلق بـ Redis ، وهناك طريقة قراءة تكوين أبسط (ConfigurationProperties (بادئة = ...)) ، والتي يمكنك تجربتها.
التكوينات ذات الصلة بإعادة الإعادة هي كما يلي
#redisspring.redis.host = 10.93.84.53spring.redis.port = 6379Spring.redis.password = bigdata123spring.redis.database = 15spring.redis. timeout = 0spring.redis.pool.maxtotal = 8spring.redis.pool.maxwaitmillis = 1000spring.redis.pool.maxidle = 8spring.redis.pool.minidle = 0
لن يتم شرح معنى التكوين لعميل redis هنا. ترتبط البلياردو بشكل عام بالأداء ، ويجب تعيينها بناءً على مقدار التزامن من المقابض والذاكرة والموارد الأخرى.
تم إعداد عميل redis ، ونبدأ في تكوين Redis كذاكرة التخزين المؤقت لـ MyBatis.
3. ذاكرة التخزين المؤقت MyBatis
هذه الخطوة هي الخطوة الأكثر أهمية. تتمثل طريقة التنفيذ في تنفيذ واجهة org.apache.ibatis.cache.cache من MyBatis.
تصاميم هذه الواجهة تكتب ذاكرة التخزين المؤقت ، وقراءة ذاكرة التخزين المؤقت ، وتدمير ذاكرة التخزين المؤقت ، والتحكم في الوصول إلى أقفال القراءة والكتابة.
الفصل الذي ننفذه لتنفيذ واجهة ذاكرة التخزين المؤقت هو MyBatisRediscache.
MyBatisrediscache.java
الطبقة العامة MyBatisRediscache تنفذ ذاكرة التخزين المؤقت {private static jedisconnectionfactory jedisconnectionfactory ؛ معرف السلسلة النهائي الخاص ؛ readWritelock readwritelock = جديد reentrantreadwritelock () ؛ public myBatisRedisCache (معرف السلسلة النهائية) {if (id == null) {رمي جديد alficalArgumentException ("مثيلات ذاكرة التخزين المؤقت تتطلب معرف") ؛ } this.id = id ؛ } Override public void clear () {redisconnection connection = null ؛ حاول {connection = jedisconnectionfactory.getConnection () ؛ connection.flushdb () ؛ connection.flushall () ؛ } catch (jedisconnectionException e) {E.PrintStackTrace () ؛ } أخيرًا {if (connection! = null) {connection.close () ؛ }}} Override public string getId () {return this.id ؛ } override الكائن العام getObject (مفتاح الكائن) {object result = null ؛ إعادة التوصيل redisconnection = فارغة ؛ حاول {connection = jedisconnectionfactory.getConnection () ؛ Redisserializer <Object> serializer = new jDkSerializationRedisserializer () ؛ النتيجة = serializer.deserialize (connection.get (serializer.serialize (key))) ؛ } catch (jedisconnectionException e) {E.PrintStackTrace () ؛ } أخيرًا {if (connection! = null) {connection.close () ؛ }} نتيجة الإرجاع ؛ } Override public readWritelock getReadWritelock () {return this.readwritelock ؛ } Override public int getSize () {int result = 0 ؛ إعادة التوصيل redisconnection = فارغة ؛ حاول {connection = jedisconnectionfactory.getConnection () ؛ النتيجة = integer.valueof (connection.dbsize (). toString ()) ؛ } catch (jedisconnectionException e) {E.PrintStackTrace () ؛ } أخيرًا {if (connection! = null) {connection.close () ؛ }} نتيجة الإرجاع ؛ } Override public void putObject (مفتاح الكائن ، قيمة الكائن) {redisconnection connection = null ؛ حاول {connection = jedisconnectionfactory.getConnection () ؛ Redisserializer <Object> serializer = new jDkSerializationRedisserializer () ؛ connection.set (serializer.serialize (key) ، serializer.serialize (value)) ؛ } catch (jedisconnectionException e) {E.PrintStackTrace () ؛ } أخيرًا {if (connection! = null) {connection.close () ؛ }}} Override الكائن العام removeObject (مفتاح الكائن) {redisconnection connection = null ؛ نتيجة الكائن = فارغة ؛ حاول {connection = jedisconnectionfactory.getConnection () ؛ Redisserializer <Object> serializer = new jDkSerializationRedisserializer () ؛ النتيجة = connection.expire (serializer.serialize (key) ، 0) ؛ } catch (jedisconnectionException e) {E.PrintStackTrace () ؛ } أخيرًا {if (connection! = null) {connection.close () ؛ }} نتيجة الإرجاع ؛ } setjedisconnection foud static static (jedisconnectionfactory jedisconnectionfactory) {myBatisRediscache.JedisconnectionFactory = jedisconnectionFactory ؛ }}يلاحظ:
كما ترون ، فإن هذه الفئة ليست فئة تديرها الجهاز الظاهري لـ Spring ، ولكن هناك خاصية ثابتة jedisconnectionfactory تتطلب حقن فول الربيع ، أي الفول المتولد في RECENT.
في فئة عادية ، يتم استخدام SPRING CONTEXTAWARE بشكل عام لاستخدام SpringContextAware introsportive.
يتم استخدام طريقة أخرى هنا ، حقن ثابت. يتم تنفيذ هذه الطريقة من خلال represiscachetransfer.
4. الحقن الثابت
Rediscachetransfer.java
ComponentPublic class rediscachetransfer {autowired public void setjedisconnectionfactory (jedisconnectionfactory jedisconnectionfactory) {mybatisrediscache.setjedisconnectionfactory (jedisconnectionfactory) ؛ }}يمكنك أن ترى أن rediscachetransfer هو حبة سبرينغ بوت. عند تهيئة الحاوية في بداية الإنشاء ، سيتم حقن حبة jedisconnectionfactory في مرور طريقة setjedisconnectionfactory.
يعين SetJedisconnectionFactory الخاصية الثابتة للفئة MyBatisRediscache عن طريق استدعاء طريقة ثابتة.
هذا يحقن jedisconnectionfactory التي تديرها حاوية الربيع في المجال الثابت.
في هذه المرحلة ، تم الانتهاء من الرمز بشكل أساسي ، والما يلي بعض التكوينات. الرئيسية هي (1) التبديل العالمي ؛ (2) مفتاح نطاق مساحة الاسم ؛ (3) تسلسل مثيل النموذج.
5. التبديل العالمي لخزائن MyBatis المستوى 2
كما ذكرنا سابقًا ، لم يتم تشغيل ذاكرة التخزين المؤقت من المستوى الافتراضي 2 ويجب ضبطها على صحيح. هذا هو التبديل لذاكرة التخزين المؤقت من المستوى العالمي 2.
تكوين MyBatis العالمي.
<؟ أو تعطيل ذاكرة التخزين المؤقت. -> <Setting Name = "Cacheenabled" value = "true"/> </settings> </ispification>
يمكن أن يكون تحميل التكوينات العالمية في مصدر البيانات هكذا.
Bean.setMapperLocations (New PathmatchingResourceTornResolver (). getResources ("classpath: mybatis-mapper/*.
يحدد مسار التخزين من mapper.xml. تحت مسار MyBatis-Mapper ، سيتم قراءة جميع اللواحق مع .xml.
Bean.setConfigLocation (classPathResource جديد ("MyBatis-config.xml")) ؛
يتم تحديد مسار تخزين mybatis-config.xml ووضعه مباشرة في دليل الموارد.
bean (name = "moonlightsqlsessionfactory") primary public sqlsessionfactory moonlightsqlsessionfactory (Qalifier ("moonlightdata) dataSource dataSource) يرمي استثناء Bean.setDataSource (DataSource) ؛ Bean.setMapperLocations (New PathmatchingResourceTornResolver (). getResources ("classpath: mybatis-mapper/*. Bean.setConfigLocation (classPathResource جديد ("MyBatis-config.xml")) ؛ return Bean.getObject () ؛ }6. تكوين مساحة اسم نطاق Mapper
كما ذكرنا سابقًا ، فإن نطاق ذاكرة التخزين المؤقت الثانوية هو مساحة الاسم الخريطة ، لذلك يجب كتابة هذا التكوين في Mapper.
<mapper namespace = "com.kangaroo.studio.moonlight.dao.mapper.moonlightmapper"> <cache type = "com.kangaroo.studio.moonlight.dao.cache.mybatisrediscache"/> <resultmap id = "geofencelist" type = "com.kangaroo.studio.moonlight.dao.model.geofence"> <structor> <edarg column = "id" javatype = "java.lang.integer column = "type" javatype = "java.lang.integer" jdbctype = "integer" /> <arg column = "group" javatype = "java.lang.string" jdbctype = "varchar" /> column = "createTime" javatype = "java.lang.String" jdbctype = "varchar" /> <arg column = "updateTime" javatype = "java.lang.string" jdbctype = "varchar" /> < /bustructor> < /resultmap> parametertype = "com.kangaroo.studio.moonlight.dao.model.geofencequeryparam" resultMap = "Geofencelist"> حدد <تضمين refid = "base_column"/> من geofence حيث 1 = 1 <test = "type! concat ('٪' ، #{name} ، '٪') </if> <if test = "group! = null"> و `group` يعجبني concat ('٪' ، #{group} ، '٪') </frate> <entert =" entertim </If> </rection> </pkypper>يلاحظ:
تتمثل علامة ذاكرة التخزين المؤقت أسفل مساحة الاسم في تكوين ذاكرة التخزين المؤقت ، ويتم تطبيق استخدام ذاكرة التخزين المؤقت رسميًا بواسطة MyBatisRediscache قمنا بتنفيذها للتو.
<cache type = "com.kangaroo.studio.moonlight.dao.cache.mybatisrediscache"/>
يتم تنفيذ الاستعلام فقط الاستعلام هنا. يمكنك تشغيل أو إيقاف تشغيل ذاكرة التخزين المؤقت لهذا SQL في علامة SELECT. استخدم قيمة الخاصية usecache = صواب/خطأ.
7. Mapper والنموذج
يجب أن يكون نموذج اقرأ وكتابة ذاكرة التخزين المؤقت التسلسلية: إنه يحتاج فقط إلى تنفيذ الواجهة المسببة للرياضة عند إعلان الفصل.
تنفذ Geofence من الطبقة العامة القابلة للتسلسل {// setter و getter remitt} الفئة العامة GeofenceParam تنفذ serializable {// setter و getter remitt}}Mapper لا يزال كما كان من قبل. عند استخدام mapper.xml ، تحتاج فقط إلى تحديد الوظائف التجريدية.
@mapperpublic interface MoonlightMapper {list <Geofence> QueryGeoFence (GeoFenceQueryParam GeofenceQueryParam) ؛}في هذه المرحلة ، يتم الانتهاء من جميع التعليمات البرمجية والتكوين ، دعنا نختبرها أدناه.
8. اختباره
يتم تنفيذ مثل هذه الواجهة المنشور في وحدة التحكم.
requestmapping (value = "/fence/query" ، method = requestMethod.post) responseBonder public reponseentity <S reponse> QueryFence ( @requestbody geofencequeryparam geofenceQueram) {try {integer pagenum = integer pagesize = geofencequeryparam.getPagesize ()! = null؟ geofencequeryparam.getPagesize (): 10 ؛ pagehelper.startPage (pagenum ، pagesize) ؛ قائمة <Geofence> list = moonlightmapper.querygeofence (GeoFenceQueryParam) ؛ إرجاع استجابة جديدة <> (استجابة جديدة (resultcode.success ، "Query Geofence Success" ، List) ، httpstatus.ok) ؛ } catch (استثناء e) {logger.error ("فشل الاستعلام الجغرافي" ، e) ؛ إرجاع استجابة جديدة <> (استجابة جديدة (resultcode.exception ، "فشل الاستعلام الجيولوجي" ، null) ، httpstatus.internal_server_error) ؛ }استخدم Curl لإرسال الطلبات ، ملاحظة
1) -H -نوع المحتوى: طريقة التطبيق/JSON
2) -D - فيما يلي حزمة المعلمة بتنسيق JSON
Curl -H "Content -Type: Application/JSON" -xpost http: //. . . /Moonlight/Fence/Query -D '{"Name": "Test" ، "Group": "Test" ، "Type": 1 ، "StartTime": "2017-12-06 00:00:00" ، "Endtime": "2017-12-06 16:00" ، "Pagenum": 1 ، "Pageize: 8المطلوب ثلاث مرات ، يتم طباعة السجل على النحو التالي
كما ترون ، في المرة الأولى فقط تم تنفيذ استعلام قالب SQL ، وتم ضرب ذاكرة التخزين المؤقت.
في بيئة الاختبار الخاصة بنا ، نظرًا لكمية البيانات الصغيرة نسبيًا ، فإن تحسين ذاكرة التخزين المؤقت لسرعة الاستعلام غير واضح. لن أشرح الكثير هنا.