في أول المادتين ، قمنا بتنفيذ رسائل SMS متزامنة/غير متزامنة والحد من تواتر إرسال رسائل الرسائل القصيرة. في هذه المقالة ، نقدم الحد من عدد المرات التي نرسل فيها رسائل الرسائل القصيرة إلى نفس المستخدم (بالحكم بناءً على رقم الهاتف المحمول و IP) كل يوم.
1. بنية جدول البيانات
نظرًا لأننا بحاجة إلى تسجيل السجلات المرسلة طوال اليوم ، فإننا نقوم بحفظ البيانات في قاعدة البيانات هنا. بنية جدول البيانات هي كما يلي:
النوع هو نوع رمز التحقق ، مثل التسجيل ، إعادة تعيين كلمة المرور ، إلخ.
القيمة الافتراضية لـ SendTime هي الوقت الحالي.
2. الحد من عدد أوقات الإرسال اليومية
نحتاج إلى استخدام فئات الواجهة والكيان المذكورة في المقالة السابقة هنا.
DailyCountFilter.java
الطبقة العامة DailyCountFilter تنفذ smsfilter {private int ipdailymaxSendCount ؛ خاص int mobiledailymaxsendcount ؛ SMSDAO الخاص SMSDAO ؛ // تم حذف بعض الكود غير المجدي على مرشح Override العام المنطقي (smsentity smsentity) {if (smsdao.getMobileCount (smsentity.getMobile ())> = mobiledailymaxsendcount) {return false ؛ } if (smsdao.getipCount (smsentity.getip ())> = ipdailymaxSendCount) {return false ؛ } smsdao.saveentity (smsentity) ؛ العودة صحيح. }}الرمز الرئيسي بسيط للغاية. أولاً ، حدد ما إذا كان عدد المرات المرسلة إلى رقم الهاتف المحمول المحدد قد وصل إلى الحد الأقصى لعدد الأوقات الإرسال ، ثم حدد ما إذا كان عدد المرات المرسلة بواسطة طلب IP المحدد قد وصل إلى الحد الأقصى. إذا لم يكن أي منهم ، احفظ رقم الهاتف المحمول و IP وغيرها من المعلومات المرسلة هذه المرة إلى قاعدة البيانات.
بالطبع ، هناك بعض المشكلات في هذه الفئة: قد تكون مؤشرات الترابط الأخرى قد حفظت بيانات جديدة بين الحكم على ما إذا كان الحد الأقصى للرقم يتجاوز الحد الأقصى للرقم وبيانات الكيان التي يتم حفظها. ينتج عن هذا الحكمين أعلاه غير دقيقين تمامًا.
يمكننا استخدام معاملات مستوى التسلسل لضمان عدم وجود أخطاء ، ولكن التكلفة مرتفعة للغاية. لذلك ، لن نفعل المعالجة هنا. لأننا قمنا بتنفيذ الحد من تردد الإرسال من قبل. إذا استخدمنا الترددات لتصفية مرة واحدة وحد من تردد الإرسال ، فإن المشكلة المذكورة أعلاه مستحيلة بشكل أساسي.
هناك مشكلة أخرى: مع مرور الوقت ، سيصبح هذا الجدول أكبر وأكبر ، مما يؤدي إلى أداء استعلام ضعيف إلى حد ما. يمكننا حذف بيانات عديمة الفائدة كل مرة كل فترة كما فعلنا في المقالة السابقة ؛ يمكننا أيضًا إنشاء جداول ديناميكية ثم إدراج البيانات في الجدول الجديد.
3. استخدم الجداول الديناميكية
هنا نعتمد الحل الثاني: اسم جدول البيانات هو "SMS_FOUR-DIGIT YEAR_TWO-DIGIT MONTER" ، مثل "SMS_2016_02". عند إدخال البيانات ، احصل على اسم الجدول بناءً على الوقت الحالي ، ثم أدخله. بالإضافة إلى ذلك ، استخدم الكوارتز لإنشاء جدول البيانات للشهر القادم والشهر المقبل في الساعة الثانية في 20 من كل شهر:
نقوم أولاً بتعديل فئة DailyCountFilter ، ونضيف خطة مهمة إلى هذه الفئة ، وإنشاء جداول البيانات بانتظام:
DailyCountFilter.java
// بناءً على الكود أعلاه ، أضف الكود العام التالي DailyCountFilter الذي ينفذ smsfilter {Private Scheduler Sched ؛ Override public void init () يلقي Schedulerexception {smsdao.createTable (0) ؛ // إنشاء جدول بيانات هذا الشهر smsdao.createTable (1) ؛ // إنشاء جدول بيانات الشهر المقبل SchedulerFactory SF = جديد StdScheDulerFactory () ؛ Sched = sf.getScheduler () ؛ // إنشاء Quartz Container JobDatamap JobDatamap = جديد JobDatamap () ؛ JobDatamap.put ("smsdao" ، smsdao) ؛ // قم بإنشاء خريطة بيانات يجب استخدامها عند تشغيل Task // إنشاء كائن JOB ، والذي ينفذ المهمة الفعلية JobDetail Job = Jobbuilder.newjob (createSmstableJob.class) .usingjobdata (JobDatamap). withidentity ("Create SMS Table Job"). // قم بإنشاء كائن Trigger ، والذي يستخدم لوصف القواعد الزمنية لإثارة تنفيذ الوظيفة // على سبيل المثال ، trigger crontrigger = triggerbuilder.newtrigger (). كل شهر. build () ؛ Sched.ScheduleJob (Job ، Trigger) ؛ // قم بتسجيل المهمة وتشغيل قواعد Sched.Start () ؛ // ابدأ الجدولة} Override public void Dride () {try {sched.shutdown () ؛ } catch (Schedulerexception e) {}} CreateSmStableJob تنفذ Job {Override public void execute (JobexecutionContext context) remows jobexecutionexception {JobDatamap datamap = context.getjobdetail (). getjobdatamap () ؛ smsdao smsdao = (smsdao) datamap.get ("smsdao") ؛ // احصل على كائن SMSDAO المرتفع smsdao.createTable (1) ؛ // إنشاء جدول بيانات الشهر التالي smsdao.createTable (2) ؛ // إنشاء جدول بيانات الشهر التالي}}}بعد ذلك ، دعونا نلقي نظرة على بعض رموز SMSDAO:
smsdao.java
الفئة العامة smsdao { / *** قم بإنشاء جدول سجل جديد** param monthexcursion عدد أشهر الإزاحة* / public void createTable (int monthexcursion) {String sql = "Create table إذا لم يكن موجودًا" + getTablename (mondexcursion) + "مثل SMS" ؛ // تنفيذ عبارة SQL}/ *** حفظ كائن كيان SMSENTITY*/ وداع الفراغ العام (SMSENTITY SMSENTITY) {String sql = "insert في" + getNowTablename () + "(mobile ، ip ، type) القيم (؟ ،؟ ،؟)" ؛ // تنفيذ عبارة SQL}/ *** احصل على رقم الهاتف المحمول المحدد واطلب الرسائل القصيرة اليوم** param رقم الهاتف المحمول للهاتف المحمول* @عدد المرات التي تطلب فيها الرسائل النصية القصيرة اليوم*/ public long getMobileCount (String mobile) {String sql = "count count (id) من" + getNowtablename () + "where mobile =؟ // تنفيذ عبارة SQL وإرجاع نتيجة الاستعلام} // تم حذف طريقة getIpCount/ *** احصل على اسم الجدول المستخدم الآن*/ سلسلة خاصة getNowTablename () {return getTablename (0) ؛ } dateFormat dateFormat = جديد SimplEdateFormat ("yyyy_mm") ؛ / *** احصل على اسم الجدول لشهر الإزاحة الشهر** param monthexcursion عدد أشهر الإزاحة* @RETURN اسم الشهر المقابل*/ السلسلة الخاصة getTablename (int monthcursion) {calendar calendar = calendar.getInstance () ؛ Calendar.Add (Calendar.month ، MonthExcursion) ؛ تاريخ التاريخ = calendar.getTime () ؛ إرجاع "sms_" + dateformat.format (التاريخ) ؛ }}هناك شرط أساسي للتشغيل الناجح لأسلوب الإبداع في SMSDAO ، وهو أن هناك جدول بيانات SMS. ستقوم طريقة Createable بنسخ بنية جدول الرسائل القصيرة لإنشاء جدول بيانات جديد.
نحتفظ بالبيانات لإرسال الرسائل النصية (رقم الهاتف المحمول ، IP ، الوقت ، إلخ) بدلاً من حذفها مباشرة ، لأننا قد نحتاج إلى تحليل هذه البيانات في المستقبل للحصول على المعلومات التي نريدها ، مثل الحكم على معدل وصول الرسائل القصيرة لمزود الخدمة ، سواء تم إرسال رسائل نصية ضارة ، إلخ. قد نحصل على "مفاجأة" غير متوقعة.
ما سبق هو كل شيء عن هذا المقال ، آمل أن تتمكن من الاستمرار في الانتباه.