В первых двух статьях мы реализовали синхронную/асинхронную отправку SMS -сообщения и ограничивая частоту отправки SMS -сообщений. В этой статье мы вводим ограничение количества раз, когда мы отправляем SMS -сообщения одному пользователю (судя по номеру мобильного телефона и IP) каждый день.
1. Структура таблицы данных
Поскольку нам нужно записывать записи отправки в течение дня, мы сохраняем данные в базе данных здесь. Структура таблицы данных выглядит следующим образом:
Тип - это тип кода проверки, такой как регистрация, сброс пароля и т. Д.
Значение по умолчанию времени отправки - текущее время.
2. Ограничьте количество ежедневных времен отправки
Нам нужно использовать классы интерфейса и сущности, упомянутые в предыдущей статье здесь.
DailyCountfilter.java
открытый класс DailyCountFilter реализует SMSFilter {private int iPdailyMaxSendCount; private int mobiledailymaxsendcount; Частный SMSDAO SMSDAO; // какой -то бесполезный код пропущен @Override Public Boolean Filter (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-CIGIT МЕСЯЦА», например, «SMS_2016_02». При вставке данных получите имя таблицы на основе текущего времени, а затем вставьте его. Кроме того, используйте Quartz для создания таблицы данных в течение следующего месяца и следующего месяца в 2 часа 20 -го числа каждого месяца:
Сначала мы изменяем класс DailyCountFilter, добавляем план задачи в этот класс и регулярно генерируем таблицы данных:
DailyCountfilter.java
// На основе приведенного выше кода добавьте следующий код открытый класс DailyCountFilter реализует SMSFilter {Private Scheduler SHAD; @Override public void init () throws pradeleRexception {smsdao.createTable (0); // Создать таблицу данных этого месяца smsdao.createTable (1); // Создать таблицу данных в следующем месяце SchearnulerFactory SF = новый StdSchedulerFactory (); ched = sf.getscheduler (); // Создать Quartz Container JobDatamap JobDatamap = new JobDatamap (); jobdatamap.put ("smsdao", smsdao); // Создать карту данных, которую необходимо использовать при выполнении задачи // Создать объект задания, который выполняет фактическую задачу jobdetail job = jobbuilder.newjob (createsmstablejob.class) .usingjobdata (jobdatamap). Withidentity («Создание задания таблицы SMS»). Build (); // Создать триггерный объект, который используется для описания правил времени для запуска выполнения задания // Например, Crontrigger Trigger = TriggerBuilder.newTrigger (). WithIdentity («Создать триггер таблицы SMS»). С помощью Cronschedulebuilder.cronschedule («0 2 20 *? месяц.build (); ched.schedulejob (job, trigger); // зарегистрировать задачу и запустить правила chard.start (); // запуск планирования} @Override public void destress () {try {ched.shutdown (); } catch (shareuleRexception e) {}} public static class createSmstablejob реализует job {@Override public void execute (jobExecutycontext context) throws jobexecuteexception {jobdatamap dataMap = context.getJobdetail (). getJobDatamap (); Smsdao smsdao = (smsdao) datamap.get ("smsdao"); // Получить пройденную Smsdao Object Smsdao.createTable (1); // Создать таблицу данных следующего месяца smsdao.createTable (2); // Создать таблицу данных следующего месяца}}}Далее, давайте посмотрим на некоторые коды SMSDAO:
Smsdao.java
открытый класс smsdao { / *** Создать новую таблицу журналов** @param monthcursion Число месяцев смещение* / public void createable (int monthovcursion) {string sql = "Создать таблицу, если не существует" + getTablename (MonthExcursion) + "как sms"; // Выполнить оператор SQL}/ *** Сохранить объект объекта SMSENTITY*/ public void Saidity (Smsentity Smsentity) {String SQL = "INSERT в" + getNowTableName () + "(Mobile, IP, тип) значения (?,?,?)"; // Выполните оператор SQL}/ *** Получить указанный номер мобильного телефона и запросить SMS сегодня** @param Mobile User Mobile Number* @return Номер раз запроса SMS сегодня*/ public getMobileCount (String Mobile) {String SQL = "SELECT COUNT (ID) из" + getNowTablEname () + "где Mobile =? // Выполнить оператор SQL и вернуть результат запроса} // Метод GetipCount пропущен/ *** Получить имя используемой сейчас таблицы*/ private string getNowTableName () {return getTableName (0); } private DateFormat DateFormat = new SimpleDateFormat ("yyyy_mm"); / *** Получите имя таблицы месяца месяца месяца** @param monthcursion Номер месяца смещение* @return Table Имя соответствующего месяца*/ private String getTableName (int MonthAxcursion) {Calendar Calendar = calendar.getInstance (); Calendar.Add (Calendar.Month, MonthExcursion); Дата даты = календарь.gettime (); вернуть "sms_" + dateformat.format (date); }}Существует предпосылка для успешной работы создамого метода в SMSDAO, который состоит в том, что существует таблица данных SMS. Метод Createletable скопирует структуру таблицы SMS для создания новой таблицы данных.
Мы сохраняем данные для отправки текстовых сообщений (номер мобильного телефона, IP, время и т. Д.) Вместо того, чтобы напрямую удалять их, потому что нам, возможно, потребуется проанализировать эти данные в будущем, чтобы получить нужную информацию, такую как оценка уровня прибытия SMS -поставщика услуг, независимо от того, отправляется ли кто -то злобно отправленным текстовыми сообщениями и т. Д. Мы даже не получаем неожиданного «сюрприза».
Выше приведено в этой статье, я надеюсь, что вы сможете продолжать обращать внимание.