Porsche: Precision Crafted Performance

Porsche is known for its perfect balance between luxury and sportiness. The brand focuses on precision engineering and driving control.

Porsche vehicles are praised for exceptional handling and responsiveness. They perform equally well on everyday roads and race tracks.

This combination makes Porsche a symbol of refined performance and technical excellence.

Как вебкам может изменить вашу личную жизнь: эмоциональные и психологические аспекты интимного досуга

В современном мире, где технологии развиваются с неимоверной скоростью, меняется и облик интимного досуга. Вебкам-сервисы стали не просто дополнительным источником развлечения, а настоящей революцией в личной жизни. Многие люди открывают для себя новые грани общения и удовлетворения потребностей, что приводит к улучшению не только физического, но и эмоционального состояния. Задумывались ли вы когда-нибудь, как платные вебкам-модели могут стать ключом к вашей гармонии и полноценной личной жизни? В этой статье мы подробно разберем, как вебкам может улучшить вашу интимную жизнь, раскрывая множество аспектов от психологии до социума.

Новые границы общения и открытость

Первое, что следует отметить, это то, что вебкам-сервисы создают уникальную платформу для общения, позволяя людям открываться друг другу в атмосфере анонимности. Это особенно важно в нашем обществе, где разговоры о сексе и интимных потребностях часто табуированы. Вебкам-пространство может стать безопасной зоной для тех, кто стесняется или боится своей открытости.

Анонимность как способ снятия барьеров

Одним из ключевых аспектов вебкам-сервисов является анонимность. Она позволяет людям выражать свои желания и фантазии, не боясь осуждения со стороны окружающих. Например, если вы хотите обсудить специфические личные предпочтения, вебкам–модель может создать безопасное пространство, в котором вы сможете говорить на любые темы. Это позволяет клиентам исследовать свои желания и границы без страха быть непонятыми.

Формирование доверительных отношений

Клиенты вебкам-сервисов могут строить доверительные отношения с моделями. Эти отношения часто основаны на взаимопонимании и поддержке. Например, если у вас есть какие-то переживания или страхи, вы можете обсудить их со своей моделью, которая, как правило, обучена оказывать эмоциональную поддержку. Такой подход способствует укреплению самооценки и позволяет лучше понимать себя.

Разнообразие интимных сценариев и фантазий

Сфера вебкам позволяет пользователям не только удовлетворять свои физические потребности, но и легко исследовать различные сценарии, которые могут помочь в обогащении образа жизни. Возможность выбора и индивидуального подхода позволяет каждому клиенту найти то, что действительно отвечает его желаниям.

От традиционных до экзотических фантазий

С помощью вебкам-сервисов вы можете легко и быстро узнать о своих скрытых желаниях и предпочтениях. Независимо от того, интересует ли вас классическая ролевуха или что-то более экзотическое, вебкам позволяет эфирить любые сценарии, которые могут улучшить качество интимной жизни. Например, многие партнеры находят возможность улучшить свои отношения, свободно обсуждая и практикуя фантазии, о которых ранее не могли говорить.

Персонализированный подход и уникальные предложения

Главным преимуществом вебкам-сервисов является возможность получения индивидуального подхода. Каждая модель имеет свои особенности и предпочтения, что помогает создать уникальные сценарии общения. Это способствует развитию фантазии у клиента и позволит ему дорисовывать свои желания в более масштабные и интересные сценарии.

Эмоциональное благополучие и психология

Вебкам-сервисы могут иметь значительное влияние на эмоциональное и психологическое состояние клиентов. Практика показывает, что удовлетворение своих желаний может привести к снижению уровня стресса и улучшению психоэмоционального фона.

Сексуальное удовлетворение и его влияние на психоэмоциональное состояние

Научные исследования указывают на то, что сексуальное удовлетворение влияет на уровень счастья и общее самочувствие. Клиенты, использующие вебкам-сервисы, отмечают, что регулярное получение удовлетворения от общения и открытие своих фантазий способствует улучшению настроения и снижению тревожности.

Улучшение самооценки

Клиенты вебкам-сервисов часто сообщают о росте своей самооценки. Наличие поддержки от моделей, которые являются профессионалами в своем деле, помогает стать более уверенными в себе и своих сексуальных предпочтениях. Например, модель может похвалить клиента за его смелость в исследовании своего тела или уважать его предпочтения, что приводит к положительным изменениям во взгляде на себя.

Новый уровень близости в отношениях

Для многих пользователей вебкам-сервисы становятся не только источником удовлетворения, но и способом поддерживать близость с партнером. Особенно это актуально для пар, которые находятся на расстоянии или сталкиваются с трудностями в интимной сфере.

Вебкам как инструмент для пар на расстоянии

Для пар, находящихся в расстоянии, вебкам-сервисы могут стать идеальным решением для поддержания интимной близости. Онлайн-сессии с вебкам-моделью могут завести новые обсуждения и способствовать укреплению эмоционального подключения между партнерами. Совместные просмотры, обсуждения желаемых сценариев могут впитывать интерес и желание у обоих партнеров.

Обогащение интимной жизни в долгосрочных отношениях

Даже для пар, которые находятся вместе, вебкам может стать источником вдохновения и улучшения интимной жизни. Совместные просмотры вебкам-шоу могут привести к обсуждению фантазий, которые ранее не обсуждались. Это расширяет горизонты интимной жизни, открывая новые возможности.

Этические аспекты вебкам-индустрии

Нельзя забывать также об этических аспектах вебкам-индустрии. Важно понимать, что работа вебкам-моделей предполагает наличие строгих правил и границ. Это, в свою очередь, влияет на качество и безопасность услуг, которые они предоставляют клиентам.

Ответственность клиентов и моделей

Более того, клиенты также должны понимать свою ответственность в этом процессе. Уважение к модели, её границам и желанию – ключевой аспект успешного взаимодействия. Уведомленность о правилах поведения и ответственности сторон будет способствовать созданию безопасной среды для всех участников.

Новая реальность как форма самовыражения

Для некоторых моделей вебкам может быть не только источником заработка, но и формой самовыражения, позволяя исследовать свою индивидуальность и сексуальность. Новые технологии предлагают им уникальные возможности для демонстрации своей креативности, что также делает вебкам привлекательным как для клиентов, так и для исполнителей.

Обобщая все вышеизложенное, становится очевидным, что вебкам-сервисы могут значительно улучшить личную жизнь, совершенно по-разному влияя на физическое и эмоциональное состояние клиентов. Это уникальная возможность для самовыражения, обучения и подержания близких отношений – как с самим собой, https://novomoskovsk-we.top/verybig_pricetype/ так и с партнёром.

Искусство выбора: как найти идеальную девушку по вызову для незабываемой ночи в Питере

Проституция — тема, о которой стесняются говорить, но, тем не менее, она актуальна и требует осознанного подхода. Города, в которых эта сфера легализована, создают пространство для множества возможностей и индивидуальных предпочтений. Санкт-Петербург с его атмосферой романтики и культуры становится идеальным местом для такого вечернего досуга. Но как выбрать девушку по вызову, чтобы ночь оставила лишь положительные воспоминания? В этой статье мы разберёмся в ключевых аспектах, которые помогут вам сделать правильный выбор, оценить все плюсы и минусы, а также погрузиться в детали этой интересной и волнительной темы.

Вам важно не только найти девушку, но и обеспечить себе комфорт и безопасность. Мы поговорим о том, как правильно выбрать, какие нюансы учесть и как избежать потенциальных рисков. Откроем секреты, которые помогут вам сделать так, чтобы романтическая ночь в Питере стала не только незабываемой, но и безопасной.

Определите свои ожидания: какой опыт вы ищете?

Выбор девушки по вызову начинается с понимания собственных ожиданий и пожеланий. Определитесь, что вы ищете — легкий флирт, романтический ужин или более глубокую связь. Задайте себе несколько вопросов:

  • Какой тип взаимоотношений вам интересен?
  • Что вы хотите получить от этого опыта?
  • Есть ли у вас предпочтения по внешнему виду или характеру женщины?

Осознанное определение ваших ожиданий поможет вам сэкономить время и силы в процессе выбора. Например, если вы ищете компанию для романтического ужина, стоит обратить внимание на девушек, которые умеют поддерживать разговор и создавать атмосферу. В то время как для неформального общения подойдет более раскрепощенная личность.

Как найти надежный источник?

Важным этапом в выборе девушки по вызову в Санкт-Петербурге является поиск надежного источника. Существует множество способов найти такую услугу, и каждый из них имеет свои плюсы и минусы. Одним из самых распространенных является использование специализированных сайтов или приложений. Важно обращать внимание на:

  • Отзывы клиентов
  • Качество предоставляемых услуг
  • Безопасность и конфиденциальность

Профессиональные агентства часто предлагают гарантии на услуги, а также возможность возврата денег. Это может дать вам уверенность в том, что ваши ожидания будут оправданы. Также стоит обратить внимание на независимых девушек, которые рекламируют свои услуги через социальные сети. Но в этом случае стоит проявить осторожность и убедиться в их надежности.

Проверка информации

Обязательно проверьте информацию о девушке. Ищите через интернет: отклики от предыдущих клиентов на форумах или в социальных сетях могут оказаться полезными. Если вы не можете найти никаких упоминаний, стоит задать себе вопрос о надежности предоставляемых услуг.

Обсуждение деталей: как правильно вести беседу?

После того как вы нашли несколько подходящих кандидатур, наступает время для обсуждения деталей. Хорошая коммуникация — это ключ к получению желаемого опыта. Согласуйте перед встречей такие нюансы, как:

  • Стоимость услуг
  • Время и место встречи
  • Предпочтения в общении и проведении досуга

Четкое обсуждение условий поможет избежать недоразумений. Постарайтесь выразить свои ожидания, но и проявите интерес к личности девушки. Это поможет создать более доверительную атмосферу.

Будьте открыты для диалога

Не бойтесь задавать вопросы о ее услугах, опыте и предпочтениях. Чем больше вы узнаете, тем легче будет принимать решение. Хорошая девушка по вызову также будет заинтересована в том, чтобы вы были довольны и комфортно себя чувствовали.

Оценка безопасности: что важно учитывать?

Безопасность — это важный аспект любого интимного досуга. Обязательно учитывайте несколько ключевых рекомендаций, чтобы минимизировать риски:

  • Встречайтесь в общественных, хорошо освещенных местах.
  • Не показывайте документов и личной информации раньше времени.
  • Сообщите другу о своем местонахождении и планах.

Также полезно заранее подумать о том, какие меры предосторожности вы хотите принять. Например, вы можете использовать кондомы и обсудить свои ограничения и предпочтения.

Забота о безопасности девушки

Показывая уважение к безопасности своей партнерши, вы создаете более комфортную атмосферу для общения. Это может усилить доверие и добавить уверенности в ваше взаимодействие. Помните, что и ей тоже необходимо быть уверенной в том, что она в безопасности.

Атмосфера и место встречи: как создать уникальную обстановку?

Создание непринужденной атмосферы играет большую роль в том, чтобы вечер прошел на высшем уровне. Если вы решили провести время у себя дома, подготовьте пространство: уберите лишние вещи, создайте уютное освещение, возможно, включите спокойную музыку. Если встреча проходит в гостинице, выберите номер с комфортной обстановкой.

Креативные идеи для романтического вечера

Рассмотрите разные варианты: возможно, вы хотите не просто потолковать о жизни, а провести время в игривой атмосфере. Неплохим вариантом станут настольные игры, карточные игры или даже просмотр совместных фильмов. Важно заранее обсудить это с девушкой — какие развлечения были бы https://gat-go.top/olddd/ ей интересны. Каждый из вас может внести свою лепту в создание вечеринки.

Психологическая сторона: как справляться с стереотипами?

Существуют определенные стереотипы о девушках по вызову, которые могут мешать полному наслаждению моментом. Одна из основных трудностей заключается в том, что многие клиенты испытывают чувство вины или стыда. Нужно осознать, что вы имеете право на собственные потребности, и обращаться за ними нормально.

Преодоление барьеров

Попробуйте разобраться в своих чувствах и предрассудках. Занятие с девушкой по вызову может стать совершенно нормальной практикой, аммо важно понимать, что это — не единичный случай, а часть более широкого спектра отношений и взаимодействий. Главное — не забывать об уважении к партнеру, ценить его как личность.

Этика и уважение: важные аспекты взаимодействия

Этика — один из ключевых аспектов, который способствует положительному опыту. Уважение друг к другу является основой для качественного взаимодействия. Обсуждая свои предпочтения и границы, вы создаете атмосферу доверия.

Правила поведения

Соблюдайте определенные правила поведения, такие как:

  • Избегайте нецензурной лексики и оскорблений.
  • Не принуждайте к действиям, которые кажутся некомфортными.
  • Оплачивайте услуги вовремя и учите своих обязательств.

Это поможет построить более гармоничные отношения и сделает вечер более запоминающимся.

Приехав в Санкт-Петербург, вы получаете уникальную возможность погрузиться в атмосферу романтики и уюта. Нахождение подходящей девушки по вызову может стать простым, а главное, интересным занятием. Осознание своих ожиданий, безопасность и открытость в общении — все это залог успешного вечера. Не забывайте уважать себя и других, и ваш вечер будет наполнен только положительными эмоциями.

Как найти VIP-девушку без лишнего пафоса: интеллектуальный подход к интим-досугу

В мире интим-услуг, где пафос и высокие ставки зачастую воспринимаются за стандарт, на самом деле скрыто множество возможностей для тех, кто ищет более глубоких и аутентичных ощущений. Интересный факт: согласно исследованиям, проведенным в легализованных странах, более 60% клиентов предпочитают общение и взаимодействие на уровне личности, а не просто физическую близость. Эта статистика подчеркивает важность не только выбора партнерши, но и подхода к взаимодействию в целом.

Ознакомившись с этой статьей, вы получите ценные советы и инсайты, которые помогут вам найти VIP-девушку без лишних затрат на понты и фальшивую атмосферу. Мы постараемся гарантировать, что вы сможете делать выбор, исходя из действительных предпочтений, а не стереотипов, а также поговорим о том, как правильно наладить контакт и создать комфортную атмосферу.

Зачем искать VIP-девушку: преимущества и особенности

Поиск VIP-девушки — это не только вопрос статуса, но и потребности в высококачественном досуге. В отличие от обычных услуг, VIP-предложения часто фокусируются на уровне комфорта, личного подхода и качественного общения. Но какие преимущества это дает?

Качество над количеством

Один из самых убедительных аргументов в пользу выбора VIP-девушки — это высокое качество услуг. VIP-девушки проходят строгий отбор и обучение, что позволяет им не только предоставлять интимные услуги, но и создавать атмосферу доверия и взаимопонимания. Вместо того, чтобы просто удовлетворить физические потребности, они знают, как создать настоящую связь с клиентом.

Индивидуальный подход

VIP-девушки часто работают в более узком круге клиентов, что позволяет им уделять больше внимания каждому. Индивидуальный подход включает в себя не только изучение предпочтений, но и умение адаптироваться к желаниям партнера, создавая уникальный опыт для каждого.

Репутация и безопасность

В сфере легализованной проституции безопасность клиентов и самих работниц выходит на первый план. VIP-девушки чаще всего сотрудничают с проверенными агентствами, что гарантирует как хорошую репутацию, так и уровень соблюдения норм и правил безопасности. Таким образом, ваш опыт будет без лишних переживаний.

Где искать VIP-девушек: реальные места и способы

Найти VIP-девушку без лишнего пафоса можно в самых разных местах и через различные каналы. Давайте рассмотрим основные из них.

Агентства с хорошим рейтингом

Обращение в агентство — это часто самый простой и безопасный способ. Однако важно выбрать репутационное агентство, которое имеет положительные отзывы и проверенные профили. Не спешите, изучите все доступные варианты. Обратите внимание на:

    • Цена услуг и точное описание сервиса.
    • Наличие фотографий и моделей, которые вас интересуют.
    • Отзывы клиентов и рейтинг.

Посетив сайт, убедитесь, что он выглядит профессионально и предоставляет конкурентоспособные цены.

Социальные сети и специализированные платформы

В последние годы социальные сети стали одним из самых популярных мест для поиска VIP-девушек. Многие из них создают профили на платформах, таких как Instagram и Telegram, где делятся постами и контактной информацией.

Важно выбирать профиль с активной политикой комьюнити — это может быть признаком хорошей репутации. Здесь вы можете увидеть реальные отзывы, что поможет вам сделать более осознанный выбор.

Форумы и сообщества

Существуют форумы и сообщества, посвященные интим-досугу, где участники могут делиться опытом и находить друг друга. Эти площадки более анонимны и позволяют вам задать вопросы, получить реальную информацию и рекомендации от других пользователей.

Обратите внимание на участие в обсуждениях, так как активные пользователи чаще всего имеют реальный опыт и могут предоставить полезные советы.

Как установить контакт с VIP-девушкой

Установление контакта — это важный аспект взаимодействия, и для того, чтобы создать комфортную атмосферу, следует придерживаться определенных принципов.

Настрой на разговор

Когда вы встречаете VIP-девушку, настройтесь на открытый и честный разговор. Постарайтесь сначала узнать о ее предпочтениях и интересах, дайте ей понять, что вы заинтересованы в ней как в личности, а не только как в объекте желаний.

Уважение и границы

Соблюдение границ — это важный момент. Чтобы избежать неловкости или неприятных ситуаций, всегда спрашивайте согласие и следите за ее реакцией на ваши слова и действия. Каждая девушка индивидуальна, и важно учитывать ее комфорт.

Индивидуальность

Не бойтесь делиться своей индивидуальностью. Вспомните, что VIP-девушки ценят клиентов, которые могут быть интересными и необычными. Это не только сделает встречу более динамичной, но и создаст более глубокую атмосферу общения.

Правильное время и место для встречи

Успех встречи часто зависит от выбора времени и места, где пройдет ваше взаимодействие.

Комфортные локации

Вместо стандартных отелей или мотелей, рассмотрите более изысканные и уютные варианты, такие как дорогие рестораны или гостиницы. Подумайте о том, где вам будет удобно общаться и чувствовать себя расслаблено.

Сезонные особенности

Время года также может влиять на атмосферу. Летнее время — это не только возможность для прогулок на свежем воздухе, но и масса событий, где можно встретиться. Осень и зима могут подразумевать более уютные встречи в комнатных условиях.

Общие советы по улучшению опыта

Для того чтобы взаимодействие было максимально приятным и запоминающимся, соблюдайте некоторые рекомендации.

Будьте терпеливы

Спешка часто приводит к неловкости. Позвольте себе и партнерше насладиться моментом, прежде чем переходить к более интимным vor-go.top/takeout-only моментам.

Создайте расслабляющую атмосферу

Небольшие детали могут значительно улучшить впечатление. Например, музыка, свечи, или даже простая хорошая беседа могут сделать встречу гораздо более приятной.

Открытость к новому опыту

Не бойтесь экспериментировать. Иногда открытость к новым ощущениям может привести к неожиданным и приятным сюрпризам.

И, конечно, не забывайте, что это должна быть взаимовыгодная встреча, где оба партнера чувствуют себя комфортно и ценят друг друга.

Принимая во внимание эти советы и рекомендации, вы сможете найти VIP-девушку, которая не только удовлетворит ваши физические потребности, но и станет настоящим компаньоном для вашего досуга, освежив отношения и подарив новые эмоции.

Куртизанки Санкт-Петербурга: Как выбрать лучшие анкеты для незабываемых встреч?

Санкт-Петербург – это не только культурная столица России, но и город с уникальной историей интимных отношений. Куртизанки, или "девушки для удовольствия", играли значительную роль в жизни этого города на протяжении веков, от эпохи романтизма и до наших дней. Зачем же стоит углубляться в эту тему? Ответ прост: понимание особенностей и разнообразия предложений в сфере интим-досуга не только обеспечит вам лучшее времяпровождение, но и поможет избежать неловких ситуаций и недоразумений. В этой статье мы поговорим о том, как выбрать лучшие анкеты куртизанок для встреч в Санкт-Петербурге, чтобы ваша ночь превратилась в волшебное приключение.

Исторический аспект: куртизанки в Санкт-Петербурге

Куртизанки в Санкт-Петербурге прошли через многообширную историю, начиная от эр после Петра I и до современных реалий. Город, пропитанный атмосферой культуры и искусства, стал идеальной арендной площадкой для многочисленных куртизанок, которые зачастую становились муза для художников и поэтов. Это создало обширную сеть знакомств и знакомств, что привело к значительному разнообразию услуг от простых встреч до эксклюзивных впечатлений.

Обратите внимание, что важно знать не только исторический контекст, но и, как эти исторические моменты влияют на современную практику. Например, в Петербурге развиты не только услуги сопровождения, но и тематические мероприятия, где куртизанки становятся частью культурной среды. Книги, картины и фильмы о куртизанках сделали их символами свободы, страсти и независимости.

Как выбрать анкету: ключевые критерии

Выбор анкеты куртизанки – процесс, требующий внимательности и осознанности. Важно учитывать несколько ключевых критериев, чтобы сделать правильный выбор.

1. Информация о модели

При выборе анкеты обратите внимание на следующие аспекты:

  • Фотографии:качественные и актуальные изображения несомненно играют важную роль. Если картинки выглядят профессионально и естественно, это хороший знак.
  • Возраст и параметры:порой анкеты могут указывать неточные данные. Сравните указанную информацию с внешностью и общими данными.
  • Услуги, предлагаемые моделью:четко прописанные услуги помогают избежать недоразумений. Спросите о том, что включено в стоимость и какие дополнительные услуги доступны.

2. Отзывы и репутация

Перед тем как договориться о встрече, стоит ознакомиться с отзывами других клиентов:

  • Форумы и сообщества:участники часто делятся своим опытом и могут порекомендовать хорошие анкеты.
  • Рейтинг модель:рейтинговые сайты также могут дать представление о популярности и качестве услуг куртизанки.

Психологический аспект выбора

При выборе куртизанки важно учитывать не только физические параметры, но и психологический аспект. Встреча должна быть комфортной и приятной для обеих сторон.

1. Ожидания и предпочтения

Определите, какие именно впечатления вы хотите получить от встречи. Вам нужна разговорчивая собеседница, девушка для отдыха или же интенсивных приключений? Понимание собственных желаний поможет вам не только быстрее сделать выбор, но и повысит качество взаимодействия.

2. Эмоциональный контакт

Часто эмоциональная связь может быть важнее физических характеристик. Профессиональные куртизанки умеют подстраиваться под клиентов, создавая дружелюбную и непринужденную атмосферу. Не стесняйтесь заранее пообщаться с моделью через чат или звонок, если это возможно. Это даст возможность оценить её уровень дружелюбия и открытости.

Важные аспекты безопасности

Безопасность – ещё один важный аспект, о котором не стоит забывать. Важно знать, как действовать в различных ситуациях, чтобы избежать неприятностей.

1. Личная безопасность

Перед каждой встречей следует позаботиться о своей безопасности:

  • Проверяйте информацию о куртизанке, чтобы убедиться в её подлинности.
  • Не делитесь с моделью слишком личной информацией, такой как ваше имя, адрес или
    Куртизанки Санкт-Петербурга: Как выбрать лучшие анкеты для незабываемых встреч?

    номер телефона.

  • Согласовывайте место встречи заранее и выбирайте безопасные и закрытые локации.

2. Финансовые аспекты

Помните, что оплата за услуги куртизанки обычно осуществляется наличными. Лучше заранее уточнить, каким образом проходит расчет, чтобы избежать недоразумений в процессе.

Как подготовиться к встрече

Желая сделать встречу незабываемой, подготовьтесь заранее. Вот несколько советов:

1. Создайте атмосферу

Если встреча проходит в вашем доме или квартире, подумайте о создании приятной атмосферы:

  • Подготовьте освещение и музыку, которые помогут вам расслабиться.
  • Имейте под рукой напитки и закуски для создания непринужденной обстановки.

2. Соблюдайте правила этикета

Не забывайте о правилах хорошего тона и этикета. Уважайте личность куртизанки, будьте вежливыми и учтивыми. Взаимное уважение поможет создать непринужденную и комфортную атмосферу для общения.

Лучшие места для интим-досуга в Санкт-Петербурге

Сама обстановка имеет большое значение для вашего удовольствия. Санкт-Петербург предлагает множество мест, в которых можно провести незабываемые встречи.

1. Отели

Романтические отели часто предлагают специальные тарифы для пар, что делает их идеальным местом для встреч. Не стесняйтесь выбирать красивые и атмосферные заведения.

2. Аренда квартир

Арендовать квартиру на сутки через популярные сервисы может быть удобным решением, если вы хотите уединения и возможности полностью контролировать ситуацию.

3. Тематические бары и клубы

Некоторые заведения создают уникальную атмосферу для встреч. Это может быть что-то в стиле "лорда" или "таинственного клуба", где куртизанки могут быть частью общей концепции.

Темы знаний о куртизанках и выборе анкеты не следует недооценивать. Понимание всех аспектов, связанных с интим-досугом, позволяет получить максимальное удовольствие и избежать неудобств. Правильный выбор анкеты, понимание собственных ожиданий и создание комфортной атмосферы – залог успешной встречи. Не забывайте о безопасности, уважении и качествах, которые вы ищете в своем союзе. Будьте открыты к новым знакомствам и встречам, и Петербург откроет для вас множество новых горизонтов в мире интимного досуга!

Красивые девушки на час: как распознать настоящую звезду

Интимный досуг – это не просто развлечение, это целая культура, которой знали и изучали на протяжении веков. Как выбрать идеальную спутницу на одну ночь среди множества предложений? Как распознать настоящую «звезду» в мире платных услуг? Это вопрос, который тревожит многих. Ведь не все «красивые девушки на час» обладают теми качествами, которые делают встречу поистине незабываемой. В этой статье вы получите советы и рекомендации по распознаванию настоящих профессионалов в области интимного досуга, поймете, на что обращать внимание и какие аспекты стоит оценивать при выборе партнёрши.

Понятие "настоящей звезды": что это значит?

Неподдельная привлекательность и charisma – это лишь половина дела. Настоящая звезда в интимной сфере — это не просто красивая внешность, но и широкий спектр качеств, которые делают её уникальной. Секрет тонкостей заключается в умении понимать и чувствовать клиента, обладая при этом определёнными навыками.

  • Эмоциональный интеллект:настоящий профессионал должен уметь чувствовать настроения и желания клиента. Умение слушать, взаимодействовать и проявлять искренний интерес создаёт атмосферу доверия и комфорта.
  • Коммуникационные навыки:важно стать хорошим собеседником, а не просто исполнителем задачи. Это добавит глубины общению, поможет создать нужное настроение и сделает встречу более интересной.
  • Гибкость:лучшая спутница на одну ночь умеет адаптироваться к различным ситуациям и желаниям, находя компромиссы и без труда поддерживая беседу на любую тему.

Если вы ищете чего-то большего, чем просто физическую привлекательность, приобретите навыки распознавания этих качеств. Кроме того, есть множество нюансов, о которых стоит позаботиться, принимая решение.

Пути к осознанию своих желаний

Перед тем как отправиться на встречу с «девушкой на час», важно определить свои собственные желания и ожидания. Подумайте, какие именно эмоции и впечатления вы хотите получить от этой встречи.

Определите тип досуга

Существует множество форм интимного досуга, и каждый тип пред собой различные ожидания и потребности. Вы можете искать:

  • Романтическое настроение с элементами флирта и лёгкого ухаживания.
  • Интимный опыт округлённого характера без лишней эмоциональной нагрузки.
  • Тематическую встречу с элементами ролевой игры или особенного сценария.

Составьте список качеств

Запишите, какие именно качества и характеристики вам важны. Возможно, для вас важна не только внешность, но и интеллект, чувство юмора или опыт в определённых сценариях. Этот небольшой «путеводитель» поможет избежать разочарований.

Не бойтесь экспериментировать

Не стоит зацикливаться на одном типе девушек. Каждое «свидание» — это возможность открыть для себя что-то новое. Вы можете неожиданно обнаружить, что вам нравится что-то, о чём вы раньше не могли и подумать.

Как распознать профессионала в большом количестве предложений?

Когда приходит время выбора, как определиться с выбором моря предложений? Есть несколько индикаторов, которые указывают на профессионализм и уровень девушки на час.

Качество и разнообразие профиля

Первое впечатление о девушке зачастую складывается из её профиля. Если мы говорим об онлайн-платформах, грамотное оформление профиля — это первый знак профессионализма.

  • Фотографии: качественные, актуальные фото, показывающие девушку в разных ракурсах. Слишком идеализированные или обработанные изображения часто могут скрывать действительность.
  • Описание: обширное но лаконичное описание – это показатель заинтересованности. Девушка, которая умеет составлять тексты, скорее всего, обладает хорошими навыками общения.

Отзывы и рекомендации

Не стоит пренебрегать отзывами от других клиентов. Читайте отзывы, смотрите рейтинги, запоминайте имена тех, кто оставил положительные впечатления. Чем больше реальных отзывов – тем больше шансов, что вы попадёте на качественного специалиста.

Важность безопасности и горизонтов общения

Интимный досуг, как и любая другая сфера, требует разумного подхода к вопросам безопасности. Здесь важны как ваша безопасность, так и безопасность выбранной вами спутницы.

Открытость в общении

Во время общения заранее уточняйте все нюансы. Это не только создаст атмосферу доверия, но и поможет избежать недопонимания. Квалифицированный партнер всегда откровенен в вопросах о своих границах, ценах и предоставляемых услугах.

Распознавание сигналов

Обратите внимание на невербальные сигналы. Если девушка замкнута, избегает вопросов или выглядит некомфортно — возможно, это не то что вам нужно. Чувство комфорта и безопасности должно быть взаимным.

Секреты «девушек на час»: что вам нужно знать

Настоящие профессионалы всегда обладают теми качествами и навыками, которые делают каждый момент уникальным. Всё дело в детях, на которые стоит обратить внимание.

Следите за языком тела

Язык тела может рассказать больше, чем слова. Главное — уметь читать знаки. Если девушка открыта, её тело расслаблено, а движения уверенные, вероятнее всего, она опытна и уверена в себе.

Навыки создания атмосферы

Настоящая звезда умеет создавать атмосферу. Комфортное и спокойное окружение — это важный аспект. Если она умеет предложить что-то особенное во разберёмся откровенно время общения, ищите глубину и информативность ее слов.

Успех в интимной встрече — это ваша ответственность

Не стоит забывать, что ваш собственный настрой также играет огромную роль. Откройтесь для новых впечатлений и создавайте свой идеальный опыт взаимодействия. Помните, что каждый момент — это шанс построить уникальную историю.

Ваша встреча с девушкой на час может стать увлекательным и оригинальным событием, если вы подойдете к выбору с должным вниманием и настойчивостью. Используя приведенные советы и рекомендации, вы сможете выбрать ту, которая станет настоящей звездой в вашем интимном досуге.

Pin Up Casino – Официальный сайт казино Пин Ап: способы входа через альтернативные зеркала (2025)

▶️ ИГРАТЬ

В сфере онлайн-гемблинга, где постоянно возникают новые площадки, подбор действительно защищенного и стабильного клуба может представлять сложность. Pin Up Casino — один из таких удачных вариантов. Это обладающий лицензией оператор, предоставляющий своим пользователям широкую коллекцию азартных продуктов: автоматы, карточные игры, рулетку и многое другое.

Pin Up Casino — международная игровая платформа, созданная в 2016 году. За время существования она смогла заработать доверие игроков по всему миру за счет продвинутых систем защиты, гарантирующих сохранность личных данных.

Официальный ресурс казино дает гостям полный набор функций: авторизацию в учетной записи, получение поощрений и участие в турнирах. В распоряжении пользователей — свыше 3000 развлечений, включая слоты, игры с живыми дилерами и рулетку. Дополнительные эмоции обеспечивают акционные предложения и состязания.

Pin Up Casino также славится высоким уровнем безопасности. Площадка применяет современные алгоритмы шифрования для предотвращения недобросовестных действий. Наличие международной лицензии доказывает её надежность и устойчивость.

Если вы в поисках проверенного онлайн-казино для игры на реальные деньги с возможностью вывода выигрышей — Pin Up Casino окажется прекрасным выбором. Официальный сайт обеспечивает все условия для захватывающего и удобного отдыха.

Внимание! Для перехода на зеркало Pin Up Casino применяйте исключительно проверенные источники, чтобы не оказаться жертвой злоумышленников. Не переходите по ссылкам на сомнительные сайты.

Pin Up Casino – ваш надежный партнер на пути к успеху!

Pin Up Casino – Официальный портал Пин Ап.

Pin Up Casino – это известная игровая площадка, предлагающая пользователям многообразные развлекательные и финансовые опции. Официальный сайт служит центральным узлом для безопасного и комфортного досуга.

На платформе доступен широкий выбор игр: автоматы, настольные игры, рулетка, бинго и прочие. Все они разработаны с использованием современных технологий, что обеспечивает качественную графику и стабильную работу.

Помимо этого, казино поощряет активность пользователей бонусами и наградами за привлечение друзей. Это повышает шансы на победу и делает игровой процесс ещё увлекательнее.

Таким образом, официальный сайт Pin Up Casino предоставляет всё нужное для качественного отдыха и игры.

Доступ через альтернативные адреса (2025)

В условиях серьезной конкуренции в области азартных развлечений Pin Up Casino удалось выделиться и занять лидирующие места. Этому поспособствовало не только разнообразие контента, но и разные способы доступа к платформе.

Один из таких способов – вход через зеркало сайта. Зеркало является альтернативным адресом, дающим возможность получить доступ к казино при блокировке или неработоспособности главного сайта. Это особенно значимо для игроков, которые сталкиваются с ограничениями.

Вход через зеркало Pin Up Casino – это легкий и оперативный способ подключиться к играм. Достаточно ввести адрес зеркала в браузере и авторизоваться привычным методом – через социальные сети или логин с паролем.

Через зеркало предоставляется полный доступ ко всем играм казино: слотам, рулетке, бинго и другим. Это дает возможность играть когда угодно и где угодно при наличии интернета.

В целом, вход через зеркало Pin Up Casino – это удобный и надежный способ обхода блокировок для продолжения игры.

Сильные стороны и функционал Pin Up Casino.

Pin Up Casino – это известная игровая площадка, предлагающая пользователям обширный каталог автоматов, азартных игр и развлекательных программ. Вот главные достоинства и функции, которые позволяют ему быть одним из лучших в России.

Уникальные возможности.

Большой выбор игровых автоматов и азартных игр Высокие ставки и выплаты Мобильная версия сайта для пользователей смартфонов и планшетов Многоязычный интерфейс Квалифицированная служба поддержки.

Преимущества.

Pin Up Casino – это место, где вы можете насладиться игрой и получать выигрыши. Сайт предлагает широкий набор функций и преимуществ, которые делают его одним из лучших онлайн-казино в России.

Как начать играть в Pin Up Casino.

Чтобы начать играть в Pin Up Casino, необходимо зарегистрироваться на официальном сайте pinup.casino. Процесс создания учётной записи отнимет всего несколько минут.

Нужно выбрать тип аккаунта: игрок или дилер. Для игры выбирайте опцию «игрок».

Шаг 1: регистрация.

Для регистрации потребуется указать личные данные: имя, фамилию, дату рождения, e-mail и номер мобильного телефона. Также необходимо придумать пароль.

После заполнения формы на электронную почту придет письмо с подтверждением. Нужно перейти по ссылке для активации аккаунта.

Шаг 2: пополнение счета.

После регистрации требуется внести депозит. Доступные методы пополнения: кредитная карта, электронный кошелек, банковский перевод.

Выберите подходящий способ, укажите сумму пополнения и предпочтительную валюту.

После пополнения баланса откроется доступ ко всем игровым автоматам и столам.

Начните играть, выбрав понравившийся слот или игру. Доступны слоты, рулетка, бинго и другие развлечения.

Также игрокам доступны различные бонусы и акции, которые помогут начать игру и повысить шансы на выигрыш.

Наслаждайтесь игрой в Pin Up Casino!

Elasticsearch Query DsL查询


Query DsL查询

一 Elasticsearch简介

Elasticsearch 是一个开源的搜索引擎,Elasticsearch 使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。

  • 一个分布式的实时文档存储,每个字段 可以被索引与搜索
  • 一个分布式实时分析搜索引擎
  • 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据

 

二 安装并运行

已经在其他文档中详细介绍,此次仅做简单步骤介绍

# 安装:
$   wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.13.3-linux-x86_64.tar.gz
$   tar -xzf elasticsearch-7.13.3-linux-x86_64.tar.gz 
$   cd elasticsearch-7.13.3/
# 运行
sh bin/elasticsearch

# 访问
$ curl http://192.168.3.14:9200/ 
{
  "name" : "87DNZWU",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "e3A3l85MSZuZlRhxj6IB2w",
  "version" : {
    "number" : "6.7.0",
    "build_flavor" : "default",
    "build_type" : "zip",
    "build_hash" : "8453f77",
    "build_date" : "2019-03-21T15:32:29.844721Z",
    "build_snapshot" : false,
    "lucene_version" : "7.7.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

 

三 Query DSL 基本结构

查询表达式(Query DSL)是一种非常灵活又富有表现力的查询语言, Elasticsearch 使用它可以以简单的 JSON 接口来展现 Lucene 功能的绝大部分

// 查询
GET /_search  // 查找整个ES中所有索引的内容
{
  "query": {}, //具体的查询语句对象
  "from": 0,   //从第几条数据开始返回
  "size": 100, //返回的条数 默认ES最多返回10000条
  "highlight": { //高亮
    "pre_tags": {}, //高亮内容的前面标签 一般都是html比如<b> <p>这种
    "post_tags": {},//高亮内容的后面标签 一般都是html比如</b> </p>这种
    "fields": { //需要高亮的字段
    }
  },
  "sort": [{ //排序
    "FIELD": { //排序的字段(需要填上具体的字段名)
      "order": "desc"
    }
  }],
  "_source": "{field}" //指定返回的字段
}

// 结果
{
    "took": 350,  // 整个搜索请求消耗了多少毫秒
    "timed_out": false, // 表示本次查询是否超时,如果为true也会返回结果,只是数据可能不完整
    "_shards": { //  显示查询中参与的分片信息,成功多少分片失败多少分片等
        "total": 5, 
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 5, // 匹配到的文档总数
        "max_score": 1, // 为文档中所有_score的最大值
        "hits": [
            {
                "_index": "mysql-shop_trades-order_item_label_binds",
                "_type": "doc",
                "_id": "591935",
                "_score": 1,
                "_source": {
                    "id": 591935,
                    "updated_at": "2021-05-20T06:26:09.000Z",
                    "@version": "1",
                    "bind_item_label_id": 729,
                    "label_type": "brand",
                    "created_at": "2021-05-20T06:26:09.000Z",
                    "@timestamp": "2021-07-07T07:31:36.262Z",
                    "is_deleted": 0,
                    "table_name": "order_item_label_binds",
                    "bar_code": "6907925004486"
                }
            }
        ]
    }
}

 

四 指定索引搜索

 

上述查询会搜索ES中的所有索引,但通常只需要去固定一个或几个索引中搜索,搜索全部无疑会造成资源的浪费,在ES中可以通过以下几种方法来指定索引

  1. 指定一个固定的索引,ops-coffee-nginx-2019.05.15为索引名字
GET /mysql-shop_trades-order_statics/_search

以上表示在mysql-shop_trades-order_statics索引下查找数据

  1. 指定多个固定索引,多个索引名字用逗号分割
GET /mysql-shop_trades-order_statics,mysql-shop_trades-order_item_labels/_search

  1. 用*号匹配,在匹配到的所有索引下查找数据
GET /mysql-shop_trades-*/_search

这里也可以用逗号分割多个匹配索引

五 DSL查询

1、筛选字段

// 筛选_source的数据,单个字段
GET /_search
{
  "_source": "bar_code",  
  "query": {}
}

// 筛选_source的数据,多个字段
{
  "_source": {
    "includes": ["store_id", "sku_id"]
  },
  "query": {}
}

// 对字段进行转换
{
  "docvalue_fields": [
    {
      "field": "updated_at",
      "format": "yyyy-MM-dd HH:mm:ss"
    },
    {
      "field": "num",
      "format": "long" // 没有作用,懵逼...
    }
  ], 
  "query": {}
}

 

2、多条件查询 (where)

  1. constant_score:装另一个查询的查询,固定分数查询,支持filter查询,不支持match查询:
    {
        "constant_score": {
            "filter": {
                "match": {
                    "name": "小米"
                }
            },
            "boost": 10
        }
    }
    

     

  2. bool:主要与其他关键字组合使用,多条件的查询必须要用bool包在外层,然后再根据具体的业务来拼接。

{
  "query": {
    "bool": {
      "should": [{}], //满足其中一个对象查询条件就行 像sql里的or
      "must": [{}],   //必须满足所有对象的查询条件 就像sql里的and
      "must_not": [{}] //必须不满足所有对象的查询条件 就像sql里的and !=
    }
  }
}

 

  1. must: 类似于SQL中的AND,必须包含
  2. must_not: 类似于SQL中的NOT,必须不包含
  3. should: 满足这些条件中的任何条件都会增加评分_score,不满足也不影响,should只会影响查询结果的_score值,并不会影响结果的内容
  4. filter: 与must相似,但不会对结果进行相关性评分_score,大多数情况下我们对于日志的需求都无相关性的要求,所以建议查询的过程中多用filter

3、group by:

ES本身没有group关键词搜索,但支持聚合查询,,需要使用关键字aggs

// 单个字段 group by
{
  "query":{},//这里省略你的查询条件
  "aggs": {
    "age_group": {//这个是指你要返回字段名
      "terms": { //这里还可以用其它关键词 这里terms才能实现group by效果
        "field": "age",//groupby的字段
        "size":1 //返回的条数 相当于group by limit
      }
    }
  }
}

// 多字段group by (如 group by sku_id,store_id)
// 方法一:script
{
  "query":{},
  "aggs": {
    "age_group": {
      "terms": {
        "script":{
          "source": """ 's' + doc['store_id'] + '_s' + doc['sku_id'] """,
          "lang": "painless"
        },
        "size": 10
      }
    }
  }
}

// 方法二:copy to
1. 设置mapping中的多个字段,copy_to 为同一个字段(skuId_storeId)
2. 搜索新字段
{
  "query":{},
  "aggs": {
    "list": {
      "terms": { 
        "field": "skuId_storeId
        "size":1
      }
    }
  }
}

// 方法三:multi_terms (使用高版本,目前6.7不支持)
{
  "aggs": {
    "genres_and_products": {
      "multi_terms": {
        "terms": [{
          "field": "genre" 
        }, {
          "field": "product"
        }]
      }
    }
  }
}

4、order by

order by:注意日期格式和数值格式才支持排序;文本不支持,如果要排序, 需把字段设置为not analysis

// 单排序
{
    "query": {
        "sort": {
            "id": "desc"
        }
    }
}

// avg按照平均值排序
{
    "query": {
        "sort": [
            {
                "id": "desc"
            },
            {
                "price": {
                    "order": "asc",
                    "mode": "avg"
                }
            }
        ]
    }
}

5、count(distinct)

{
  "query":{},
  "aggs": {
    "total_sku_id": {
      "cardinality":{ "field": "sku_id"}
    },
     "total_entity_store_id": { // 非数字类型,无法使用field排序,可以对field增加fieldData = true,或者对field.keyword排序,建议使用后者,高效内存消耗低
      "cardinality":{ "field": "entity_store_id.keyword"}
    }
  }
}

 

6、SUM

{
  "query":{},
  "aggs": {
    "total_pay_num": {
      "sum": {"field": "num"}
    },
     "total_cost_fee": {
      "sum": {"field": "cost_fee"}
    }
  }
}

 

7、distinct :

select distinct(id) from table

{
  "query":{},
  "collapse": {
      "field": "id" //你需要distinct的字段
   }, 
}

 

8、limit

1. 分页:
    1. form:从第几个开始查询,最开始是0
    2. size:即limit
    3. 使用size,size最大可获取数量是xx个
2. 获取所有数据的三种方式
    1. scroll深度滚动需要根据scroll_id和循环取,取完后,需删除scroll,减小内存开销(深度滚动高效,用于处理大量数据,不适合实时获取)
    2.调整索引index.max_result_window的大小,默认10000 (大小与堆内存成正比,这个限制内存)
    3.search_after:请求需增加前一个结果的排序,(实时游标,可根据索引更新和删除而改变 )
    4。 如果是group by查询获取所有数据, 获取需要使用到cardinality查询预估总数,再使用partition、num_partitions分区依次获取数据

9、搜索关键字

  1. match:自定字段,根据字段关键字进行搜索,会分割关键词,匹配到含有一个多多个词的匹配
  2. query_string:全文搜索
  3. match_phrase:不分割关键词 {"match_phrase": {"name":"婴幼儿奶粉"}}
  4. term: 类似SQL where field = x,主要用于数字匹配;如果要匹配文本,会自动分词,不能精准查询,需把字段设置成not analysis
    {
      "query": {
        "term": {"bind_item_label_id": 729}
      }
    }
    

     

  5. terms: 类似SQL where field in (x,x),主要用于数字匹配,
    {
      "query": {
        "terms": {"bind_item_label_id": [703,729]}
      }
    }
    

     

  6. range:: 查询价格在1000-2000的商品
{
    "query": {
        "range": {
            "price": {
                "gte": 1000,
                "lte": 2000
            }
        }
    }
}

 

  1. filter:判断文档是否满足条件
{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "price": 1999
                }
            }
        }
    }
}

Elasticsearch:Aggregation

  1. metric:度量聚合,主要针对number类型的数据,需要es做较多的计算工作(类似SQL的SUM、MAX、AVG、MIN、Cardinality、stats<属于多值分析>等)
  2. bucket:桶聚合,划分不同步的桶,将数据分配到不同的桶,(类似SQL中的group by)
  3. Pipeline Aggregation:管道分析类型,对其他聚合结果进行二次聚合
  4. Matrix Aggregation:矩阵分析类型,支持对多个字段的操作并提供一个结果矩阵

term aggregation

  • size 可以通过size返回top size的文档,该术语聚合针对顶层术语(不包含嵌套词根),其搜索过程是将请求向所有分点发送请求,每个分片节点返回size条数据,然后聚合所有分片的结果(会对各分片返回的同样词根的数数值进行相加),最终从中挑选size条记录返回给客户端。从这个过程也可以看出,其结果并不是准确的,而是一个近似值。
  • Shard Size 为了提高该聚合的精确度,可以通过shard_size参数设置协调节点向各个分片请求的词根个数,然后在协调节点进行聚合,最后只返回size个词根给到客户端,shard_size >= size,如果shard_size设置小于size,ES会自动将其设置为size,默认情况下shard_size建议设置为(1.5 * size + 10)。
// 单个字段 group by
{
  "query":{},//这里省略你的查询条件
  "aggs": {
    "age_group": {//这个是指你要返回字段名
      "terms": { //这里还可以用其它关键词 这里terms才能实现group by效果
        "field": "age",//groupby的字段
        "size":1 //返回的条数 相当于group by limit
      }
    }
  }
}

// 返回结果格式
{
  ...
  "aggregations" : {
      "list" : {
        "doc_count_error_upper_bound" : 0, // 该值表示未进入最终术语列表的术语的最大潜在文档计数
        "sum_other_doc_count" : 90 // 该值表示未进入最终术语列表的术语的最大潜在文档计数
        "buckets" : [ // 返回doc_count排名最前的10个,受size参数的影响
          {
            "key" : "1",
            "doc_count" : 24,
            "total_refund_fee" : {
              "value" : 0.0
            },
            "total_cost_fee" : {
              "value" : -14976.0
            },
          }
        ]
      }
    }
    }
}

 

 

match_phrase :查询分析文本,创建词组查询

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html#query-dsl-match-query-phrase

 

 

举例子

GET mysql-shop_trades-order_item_label_binds/_search/?scroll=1m
{
  "docvalue_fields": [
    {
      "field": "updated_at",
      "format": "yyyy-MM-dd HH:mm:ss"
    }
  ], 
  "size": 1000,
  "sort": {"id":"desc"},
  "query": {
    "bool": {
      "must": [
        {"match": {"is_deleted": 0}},
        {"match": {"label_type": "brand"}},
        {
          "constant_score": {
            "filter": {
              "terms": {
                "bind_item_label_id": [703, 2, 729]
                }
              }
            }
        }
      ]
    }
    }
}




GET mysql-shop_trades-order_item_label_binds/_search/?scroll=1m
{
  "_source": "bar_code", 
  "query": {
    "bool": {
      "filter": [
        {"match": {"is_deleted": 0}},
        {"match_phrase": {"label_type": "brand"}},
        {"terms": {"bind_item_label_id": [703, 2, 729]}}
      ]
    }
  },
  "aggs": {
    "bar_code_group": {
      "terms": {
        "field": "bar_code.keyword",
        "size": 10 
      }
    }
  }
}


GET mysql-shop_trades-order_item_label_binds,mysql-shop_trades-order_statics/_search
{
  "query": {
    "bool": {
      "filter": [
        {"match_phrase": {"sys_name": "yiqigou"}},
        {"range": {"num": {"lte": 2000}}},
        {"range": {"return_num": {"gte": -1000}}},
        {"range": {"total_price": {"lte": 1000000}}},
          {"match": {"id": 60}},
        {"term": {"order_type": 0}},
        {"term": {"item_type": 0}},
        {"range": {"date": {
          "gte": "2020-01-21 00:00:00",
          "lte": "2021-07-22 00:00:00",
          "format": "yyyy-MM-dd HH:mm:ss",
          "time_zone": "+08:00"
        }}}
      ],
      "must_not": [
        {"terms": {"store_id": [165]}}
      ]
    }
  }
}

 

 

设置fieldData

// 第一步,创建索引 (如果已经有索引,直接看第二步)
PUT mysql-shop_trades-order_statics2
{
  "mappings": {
    "_doc": {
      "properties": {
        "entity_store_id": { 
          "type": "text",
          "fields": {
            "keyword": { 
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}

// 第二步 设置fieldData为true
PUT mysql-shop_trades-order_statics/_mapping/_doc
{
  "properties": {
    "entity_store_id": {
      "type":     "text",
      "fielddata": true
    }
  }
}

// 第三步 可以查看该索引的Mapping结构,fieldData是否加上去
{
  "mapping": {
    "doc": {
      "properties": {
        "entity_store_id": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "fielddata": true
        }
      }
    }
  }
}

延伸

 

 

设置 max_result_window

PUT /mysql-shop_trades-order_statics/_settings
{
  "index": {
    "max_result_window": 100000
  }
}

 

Spring Boot 入门

一、开发基础

  • Java基础(两到三小时过一遍)
  • Java开发环境配置必须使用JDK1.8
  • IDE安装(优先使用IntelliJ IDEA)

二、名词解释

  • Spring:JAVA开发应用框架
  • Spring Boot:用来简化Spring应用的初始搭建以及开发过程的配置框架
  • Maven:Java项目构建工具,成熟的项目
  • Gradle:更简洁的Java项目构建工具,吸收了旧构建工具的优点。
  • JPA:是Sun官方提出的Java持久化规范,即数据库操作规范。
  • Hibernate:Hibernate是一个ORM框架,是JPA的默认实现方式,一般说JPA都是指Hibernate。
  • Mybatis:Mybatis是一个轻便的ORM框架。
  • Spring data jpa:是Spring基于ORM框架、JPA规范的基础上封装的一套JPA应用框架

三、新项目流程

  1. 新建gradle项目
    • File->new->Prroject->Spring Initializr

    • 填写Group、Artifact选择Gradle Project项目生成

    • 可以直接在生成项目的时候选择对应需要安装的插件,如:web、jpa、mybatis等,也可以在项目初始化完成之后在build.gradle中添加/配置

  2. 配置build.gradle(位于根目录)

    plugins {
        id 'org.springframework.boot' version '2.1.3.RELEASE'
        id 'java'
    }
    
    apply plugin: 'io.spring.dependency-management'
    
    group = 'com.duomai'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = '1.8' // JDK最大兼容版本
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        // Spring Boot JPA 组件
        implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
        // Spring Boot Web组件
        implementation 'org.springframework.boot:spring-boot-starter-web'
        // Mybatis插件,注意暂时使用**1.1.1**版本,高版本的运行好像有问题
        implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.1.1'
        // Mybatis分页插件
        implementation group: 'com.github.pagehelper', name: 'pagehelper-spring-boot-starter', version: '1.2.10'
        runtimeOnly 'org.springframework.boot:spring-boot-devtools'
        runtimeOnly 'mysql:mysql-connector-java'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }
    
    

    修改了build.gradle后,idea会自动安装/更新依赖包。
    参考:gradle官网Spring Boot Web服务搭建Spring Boot Mysql使用Spring Boot JPA使用

  3. 项目基础配置(位于src/resources/application.properties

    #运行配置
    server.port=9000
    #数据格式配置
    spring.jackson.time-zone=GMT+8 // 设置接口返回时区为东八区
    spring.jackson.date-format=yyyy-MM-dd HH:mm:ss // 自动将接口返回中的日期格式转换为标准格式
    #数据库连接配置
    spring.datasource.url=jdbc:mysql://192.168.0.235:3355/shop_balances?serverTimezone=Asia/Shanghai&tinyInt1isBit=false // serverTimezone选择Mysql东八区,tinyInt1isBit禁止Mysql自动将tinyint(1)类型数据映射为boolean类型
    spring.datasource.username=cishop
    spring.datasource.password=fuyuan1906
    #log配置
    logging.path=E:/java/demo/balance_card/log
    logging.level.com.favorites=DEBUG
    #logging.level.org.springframework.web=INFO
    logging.level.org.hibernate=ERROR
    #mybatis设置
    mybatis.type-aliases-package=com.duomai.balance_card.Model.Mapper
    mybatis.configuration.map-underscore-to-camel-case=true
    logging.level.com.duomai.balance_card.Model.Mapper=DEBUG
    #pagehelper插件设置
    pagehelper.helperDialect=mysql
    pagehelper.reasonable=false
    pagehelper.supportMethodsArguments=true
    pagehelper.params=pageNum=page;pageSize=limit
    #jpa 设置
    spring.jpa.properties.hibernate.hbm2ddl.auto=update
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
    spring.jpa.show-sql= true
    
  4. 项目启动
    • IDEA启动,运行[Prefix]Application.java文件即可

    • 命令行启动

      • Maven项目
        在springboot的应用的根目录下运行 mvn spring-boot:run

      • Grdale项目
        在springboot的应用的根目录下运行 gradle bootRungradlew bootRun
        (前者是使用本地的gradle版本运行,后者是使用代码仓库中的gradle运行)

    • 打包构建可执行文件运行

  5. 开发环境热更新设置
    热更新不是很好用,有一定的延迟时间

四、项目文件分层解析

// 业务代码 src/main
java 
    com
        duomai
            balance_card
                [Prefix]Application.java // 项目启动文件,可以做一些全局设置,如时区设置、Mapper扫描等
                Config // 配置类,用于注册一些全局配置,如拦截器注册等
                Middleware // 中间件,实现AOP功能
                Controller // 控制器,主要做路由功能
                    xxxController.java
                    BaseErrorController.java // 路由匹配失败时使用的控制器
                Service // 业务代码
                Model // 目录主要用于实体与数据访问层
                    Entity // 数据表实体类
                    Repository // JPA数据仓库
                    Mapper // Mybatis映射文件
                    Provider // Mapper的Sql生成器
                Library // 库类,存放公共类文件/纯定义文件等
                    ApiReturnDefines.java // 接口返回定义
                    ExceptionErrprDefines.java // 异常监听层定义
                Helper // 辅助函数类文件
                OutPut // 接口输出层
                    ApiResult.java // 最终的接口输出格式
                    AiReturn.java // 快速生成ApiResult类,供外部调用
                Exception // 统一的异常处理
                    ControllerHandler // 路由层异常监听
                    SqlHandler // 数据库层异常监听
// 配置项
resources
    appliaction.properties // 项目配置文件

五、控制器中间件

  1. 一般使用Spring过滤器或拦截器实现AOP切面编程

  2. 过滤器和拦截器的对比

    • 作用域不同
      过滤器依赖于servlet容器,只能在 servlet容器,web环境下使用。
      拦截器依赖于spring容器,可以在spring容器中调用,不管此时Spring处于什么环境。
    • 细粒度的不同
      过滤器的控制比较粗,只能在请求进来时进行处理,对请求和响应进行包装。
      拦截器提供更精细的控制,可以分为controller对请求处理之前、渲染视图之后、请求处理之后三个切面。
    • 中断链执行的难易程度不同
      拦截器可以 preHandle方法内返回 false 进行中断。
      过滤器就比较复杂,需要处理请求和响应对象来引发中断,需要额外的动作,比如将用户重定向到错误页面。
  3. 拦截器的使用
    • 编写自定义拦截器(Middleware/ControllerInterceptor.java
    public class ControllerInterceptor implements HandlerInterceptor {
        private Logger logger = LoggerFactory.getLogger(ControllerInterceptor.class);
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            logger.info("preHandle....");
            // token校验等
            String token = request.getHeader("token");
            //     Common.sendJson(response, ApiReturn.fail(1001, "token验证失败"));
            //      return false;
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            logger.info("postHandle...");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            // 接口日志记录等
            logger.info("afterCompletion...");
        }
     ```
    
    **说明**:
    preHandle:对客户端发过来的请求进行前置处理,如果方法返回true,继续执行后续操作,如果返回false,执行中断请求处理,请求不会发送到Controller。可以在这里校验一些权限信息,如token等,校验失败直接以JSON格式返回请求。
    
    postHandler:在请求进行处理后执行,也就是在Controller方法调用之后处理,前提是preHandle方法返回true。具体来说,postHandler方法会在DispatcherServlet进行视图返回渲染前被调用。
    
    afterCompletion: 该方法在整个请求结束之后执行,前提依然是preHandle方法的返回值为true。
    
    • 注册拦截器(Config/InterceptorConfig.java
    @Configuration
    public class InterceptorConfig implements WebMvcConfigurer {
        @Override
        // 核心方法
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(ControllerInterceptor())
                    //配置拦截规则
                    .addPathPatterns("/**")
                    .order(1);
    
            // 多个拦截器按上述方法持续注册即可,同时也可以设置order值,从小到大执行。
        }
    
        @Bean
        public HandlerInterceptor ControllerInterceptor() {
            return new ControllerInterceptor();
        }
    }
    

六、Controller层

  1. 定义控制器文件
    @RestController
    在类文件头部定义,标明为控制器文件,且输出格式为JSON
    
  2. 路由和参数
    1. 定义路由名称,接收方法
      例:@RequestMapping(value = "/get", method = {RequestMethod.GET, RequestMethod.POST})
      
        可选参数:
      
        value:路由名称
      
        method:指定请求的method类型, GET、POST、PUT、DELETE、PATCH等,可多选
      
        consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html
      
        produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
      
        params: 指定request中必须包含某些参数值
      
        headers: 指定request中必须包含某些指定的header值
      
    2. 参数接收
      例:@RequestParam(value = "fields", required = false, defaultValue = "*") String fields
      
          value:参数名称
      
          defaultValue:默认值
      
          required:是否是必要参数
      
    3. 自定义错误路由
      1. 在Controller层中添加BaseErrorController.java文件,用于监听路由匹配失败的情况
        @Controller
        public class BaseErrorController implements ErrorController {
            @Override
            public String getErrorPath() {
                System.out.print("错误页面");
                return "error/error";
        }
        
            @RequestMapping(value = "/error")
            public void error() throws Exception {
                throw new Exception("路由匹配失败");
            }
        }
        
      2. 在Exception文件夹中添加ControllerHandler.java,用于捕获路由报错并输出。
        @RestControllerAdvice
        public class ControllerHandler {
            // 缺少必选参数
            @ExceptionHandler({MissingServletRequestParameterException.class})
            @ResponseBody
            public ApiResult requestMissingServletRequest(MissingServletRequestParameterException e){
                return ApiReturn.fail(ExceptionErrorDefines.RequestMissingServletRequest, e.getMessage());
            }
        }
        未解决:抛出异常后访问404页面运行环境会报错,但是页面正常  
        

        参考:https://www.jianshu.com/p/393f70b55b1b

  3. Service层调用

    1. Service类成员注入
      • 使用@Autowired修饰符进行依赖注入
        @Autowired
        private final CardService cardService;
        
      • 用构造函数来做注入类成员(推荐使用)
        private StoreBalanceCardsRepository cardsRepository;
        public CardController(StoreBalanceCardsRepository cardsRepository) {
            this.cardsRepository = cardsRepository;
        }
        **注**:
        IntelliJ IDEA使用依赖注入会有IDE报错,但不影响实际编译运行,如需去除报错提示,需要在Dao层(Respository/Mapper)类开头添加注解 `@Repository`
        
    2. 调用
      cardService.get(id, fields);
      

七、Service层

  1. 定义Service文件
    @Service
    在类文件头部定义,标明为Service文件
    
  2. 注入Model层操作文件
    private final StoreBalanceCardsRepository storeBalanceCardsRepository;
    private final StoreBalanceCardsMapper storeBalanceCardsMapper;
    
        CardService(StoreBalanceCardsRepository storeBalanceCardsRepository, StoreBalanceCardsMapper storeBalanceCardsMapper) {
            this.storeBalanceCardsRepository = storeBalanceCardsRepository;
            this.storeBalanceCardsMapper = storeBalanceCardsMapper;
        }
    
  3. 调用Model层文件

八、Model层

  1. Repository

    • Spring中概念,概念类似于数据仓库,是Spring data jpa的实现。居于业务层和数据层之间,将两者隔离开来,在它的内部封装了数据查询和存储的逻辑。

    • Repository和传统意义上的DAO的区别:
      Repository蕴含着真正的OO概念,即一个数据仓库角色,负责所有对象的持久化管理。DAO则没有摆脱数据的影子,仍然停留在数据操作的层面上。Repository是相对对象而言,DAO则是相对数据库而言,虽然可能是同一个东西,但侧重点完全不同。

  2. Mapper

    存放Mybatis数据库关系映射方法

  3. Provider
    为Mapper层提供的SQL生成器,即将SQL的生成与映射解耦。

  4. Entity

    • 根据表结构自动生成实体类
      **注意**:
      i、多次自动生成不会覆盖,如需更新需要把旧的实体类文件删除
      
      ii、有需要的话可以在实体类文件右击generate一键生成构造函数、set get方法、@Autowired等
      
      iii、自动生成的实体类中datetime类型的字段会被转为Java的timestamp类型数据,存储的时候也使用timestamp类型即可
      
      iv、生成出来的实体类catalog = "" 报错,是IDE的报错,不影响使用
      

      参考文档:https://blog.csdn.net/chenju05244554/article/details/1009142081

  5. Hibernate 和 Mybatis 的对比

    • Hibernate优势:
      i、DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
      
      ii、对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
      
      iii、数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
      
      iv、有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。
      
    • Mybatis优势:
      i、MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
      
      ii、MyBatis容易掌握,而Hibernate门槛较高。
      
    • 选用Mybatis的原因
      i、Hibernate无法满足动态获取部分字段的需求,即使是使用Hibernate提供的原始SQL也无法实现
      
      ii、Hibernate的JPA查询只适用于一些简单的情况,如遇到复杂的SQL,Repository中的方法名会很长。这时候又将回到Hibernate的自定义SQL查询,即原生SQL。
      
      iii、Hibernate的维护成本比MyBatis高很多,MyBatis的SQL生成完全取决于开发者,所以SQL修改、维护、优化会比较便利。
      

九、MyBatis使用

  1. 引入MyBatis以及pagehelper分页插件
    dependencies {
        implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.1.1'
        implementation group: 'com.github.pagehelper', name: 'pagehelper-spring-boot-starter', version: '1.2.10'
    }
    
  2. application.properties 添加相关配置
    #mybatis设置
    mybatis.type-aliases-package=com.duomai.balance_card.Model.Mapper // 项目中Mapper存放的包
    mybatis.configuration.map-underscore-to-camel-case=true // 自动将sql字段下划线转为驼峰,可以保证取出的数据格式就是数据库中存储的格式
    logging.level.com.duomai.balance_card.Model.Mapper=DEBUG // 开启DEBUG模式,用于开发环境,记录执行的SQL。
    #pagehelper插件设置
    pagehelper.helperDialect=mysql // 指定分页插件使用哪种数据库
    pagehelper.reasonable=false // 分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
    pagehelper.supportMethodsArguments=true // 支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页,设置后无需手动启用分页插件。
    pagehelper.params=pageNum=page;pageSize=limit //  自定义Mapper 接口参数来传递分页参数的参数名
    
  3. 添加Mapper类扫描的两种方式
    • 在启动类中添加对mapper包扫描@MapperScan(推荐使用)
      @SpringBootApplication
      @MapperScan("com.duomai.balance_card.Model.Mapper")
      
    • 在具体的Mapper类上面添加注解 @Mapper

  4. Mapper类SQL用例

    public interface StoreBalanceCardsMapper {
        // select用例
        @SelectProvider(type = StoreBalanceCardsSqlBuilder.class, method = "getById")
        List<Map> getById(@Param("id") int id, @Param("fields") String fields, @Param("page") int page, @Param("limit") int limit);
    
        // 列表
        @SelectProvider(type = StoreBalanceCardsSqlBuilder.class, method = "list")
        Page<Map> list(@Param("fields") String fields, @Param("page") int page, @Param("limit") int limit);
    
        // insert用例
        @InsertProvider(type = StoreBalanceCardsSqlBuilder.class, method = "add")
        @Options(useGeneratedKeys=true, keyProperty="storeBalanceCard.id", keyColumn="id")
        int add(@Param("storeBalanceCard") StoreBalanceCards storeBalanceCard);
    
        // update用例
        @UpdateProvider(type = StoreBalanceCardsSqlBuilder.class, method = "updateName")
        @Options(useGeneratedKeys=true, keyProperty="storeBalanceCard.id", keyColumn="id")
        int updateName(@Param("storeBalanceCard") StoreBalanceCards storeBalanceCard, @Param("limit") int limit);
    
        // delete用例
        @DeleteProvider(type = StoreBalanceCardsSqlBuilder.class, method = "deleteById")
        int delete(@Param("id") int id, @Param("limit") int limit);
    }
    
    • 通过Provider的方式动态获取SQL

    • 需要分页时在具体的方法后多加page、limit参数,自动实现分页

      // Service层调用
      List storeBalanceCard = storeBalanceCardsMapper.list(fields, page, limit);
      // Mapper层实现
      Page<Map> list(@Param("fields") String fields, @Param("page") int page, @Param("limit") int limit);
      
    • 分页组件仅可用于查询,不可用于更新/删除,更新/删除需要另外实现

  5. Providerle类SQL用例

    public class StoreBalanceCardsSqlBuilder {
        private static final String STORE_BALANCE_CARDS = "store_balance_cards";
        public static String getById(int id, String fields) {
            return new SQL(){ { 
                SELECT(fields);
                FROM(STORE_BALANCE_CARDS);
                WHERE("store_balance_cards.id = #{id}");
            } }.toString();
        }
    
        public static String list(String fields) {
            return new SQL(){ {
                SELECT(fields);
                FROM(STORE_BALANCE_CARDS);
            } }.toString();
        }
    
        public static String add(@Param("storeBalanceCard") StoreBalanceCards storeBalanceCard) {
            return new SQL(){ {
                INSERT_INTO(STORE_BALANCE_CARDS);
                VALUES("sys_name", "#{storeBalanceCard.sysName}");
                VALUES("store_id", "#{storeBalanceCard.storeId}");
                VALUES("entity_store_id", "#{storeBalanceCard.entityStoreId}");
                VALUES("name", "#{storeBalanceCard.name}");
                VALUES("type", "#{storeBalanceCard.type}");
                VALUES("item_id", "#{storeBalanceCard.itemId}");
                VALUES("photo", "#{storeBalanceCard.photo}");
                VALUES("state", "#{storeBalanceCard.state}");
                VALUES("upgrade", "#{storeBalanceCard.upgrade}");
                VALUES("recharge_discount", "#{storeBalanceCard.rechargeDiscount}");
                VALUES("updated_at", "#{storeBalanceCard.updatedAt}");
                VALUES("created_at", "#{storeBalanceCard.createdAt}");
            } }.toString();
        }
    
        public static String updateName(@Param("storeBalanceCard") StoreBalanceCards storeBalanceCard, @Param("limit") int limit) {
            return new SQL(){ {
                UPDATE(STORE_BALANCE_CARDS);
                SET("name=#{storeBalanceCard.name}");
                if (storeBalanceCard.getUpdatedAt() != null) {
                    SET("updated_at=#{storeBalanceCard.updatedAt}");
                }
                WHERE("store_id = #{storeBalanceCard.storeId}");
            } }.toString() + " limit " + limit;
        }
    
        public static String deleteById(int id, int limit) {
            return new SQL(){ {
                DELETE_FROM(STORE_BALANCE_CARDS);
                WHERE("store_balance_cards.id = #{id}");
            } }.toString() + " limit " + limit;
        }
    }
    
  6. 分页组件详解

十、接口输出

  1. 接口统一输出格式

    state: // 状态位
    msg: // 接口输出提示信息
    data: { // 总的接口输出数据,可以为空
        data: // 接口数据
        other: // 其他返回数据,如total/page_total等
        ...:
    }
    
  2. 正常接口输出/异常监听输出统一使用OutPut/ApiReturn方法

十一、异常处理

  1. 项目运行异常统一监听
    现有:ControllrHandler 路由异常监听、SqlHandler 数据库操作异常监听
    需要持续添加
  2. 统一使用接口输出类进行返回,杜绝直接返回报错信息。

十二、单元测试

  1. 添加单元测试类

    src\test\java\com\duomai\balance_card\BalanceCardApplicationTests.java

  2. demo

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class BalanceCardApplicationTests {
    
        @Autowired
        private MockMvc mockMvc;
    
        @Test
        @SuppressWarnings("unchecked")
        public void getCard() throws Exception {
            String card_id = "1";
            String fields = "store_id,item_id,recharge_discount,photo,type,name";
            String res = this.mockMvc.perform(get("/card/get")
                    .param("id", card_id).param("fields", fields)
                    )
                    .andDo(print())
                    .andExpect(status().isOk())
                    .andReturn()
                    .getResponse()
                    .getContentAsString();
           // 接口返回不为空
           assertThat(res).isNotNull();
           // 校验接口返回格式是否完整
           Map<String, Object> api_res = Common.jsonToMap(res);
           assertThat(api_res).isNotNull();
           assertThat(api_res).hasSize(3);
           assertThat(api_res).containsKeys("state", "msg", "data");
           // 校验接口返回state是否正确
           int state = (int) api_res.get("state");
           Map<String, Object> api_data = (HashMap<String, Object>) api_res.get("data");
           assertThat(state).isEqualTo(ApiReturnDefines.SUCCESS);
           // 校验data数据是否正确
           assertThat(api_data).containsOnlyKeys("data");
           ArrayList<Map> data = (ArrayList) api_data.get("data");
           String[] fieldsAll = fields.split(",");
           assertThat(data).hasSize(1);
           assertThat(data.get(0)).containsKeys((Object[]) fieldsAll);
        }
    }
    
  3. 详解
    • 使用 @RunWith(SpringRunner.class)@SpringBootTest 定义测试类
    • 添加注解 @AutoConfigureMockMvc ,使用 Spring MockMvc 模拟Spring的HTTP请求并将其交给控制器,实际上并没有真正地启动服务器,仅仅是Mock,节省了启动服务器的开销。
    • 使用 AssertJ 库类来验证接口返回内容
      在demo中,使用断言验证了接口返回格式、state状态、data数据格式等基本内容。

    参考文档:https://spring.io/guides/gs/testing-web/

十三、项目打包

  1. 不同的构建文件
  • 普通 jar 包 : 会将源码编译后以工具包(即将class打成jar包)的形式对外提供,此时,你的 jar 包不一定要是可执行的,只要能通过编译,可以被别的项目以 import 的方式调用。
  • 可执行 jar 包 : 能通过 java -jar 的命令运行。
  • 普通 war 包 : war 是一个 web 模块,其中包括 WEB-INF,是可以直接运行的 WEB 模块。做好一个 web 应用后,打成包部署到容器中。
    • 可执行 war 包 : 普通 war 包 + 内嵌容器 。
  1. 构建可执行 jar 包

    • IDE打包
      右侧Gradle -> Tasks -> build -> build
    • 命令行打包
      进入项目根目录,执行gradle build
  2. 运行可执行 jar 包
    java -jar build/libs/balance_card-0.0.1.jar
    运行时可带参数,同application.properties中的参数名
    例:

    java -Djava.security.egd=file:/dev/./urandom -jar /opt/ci123/www/html/java/balance_card/build/libs/${jarName}.jar --server.port=80
    

十四、容器化部署

  1. 创建docker镜像
  • Dockfile 编写

    FROM java:8
    MAINTAINER duomai
    # 设置镜像源
    COPY sources.list /etc/apt/sources.list
    # 安装扩展
    RUN apt-get update && apt-get install -y \
    wget \
    curl \
    vim \
    git \
    less
    # 配置系统时间
    RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo 'Asia/Shanghai' > /etc/timezone
    VOLUME /tmp
    # 设置工作目录
    ADD . /opt/ci123/www/html/java
    WORKDIR /opt/ci123/www/html/java
    # 指定输出端口
    EXPOSE 80

    • 快速构建镜像

      sh docker/build.sh [version]

  1. 环境变量配置
  • 配置

    #数据库连接配置 application.properties
    spring.datasource.url=jdbc:mysql://${APP_DB_HOST:192.168.0.235}:${APP_DB_PORT:3355}/${APP_DB_DATABASE:shop_balances}
    spring.datasource.username=${APP_DB_USER:cishop}
    spring.datasource.password=${APP_DB_PASSWORD:fuyuan1906}

    1. 启动容器( docker/run.sh )
  • 启动参数

    -p // 宿主机运行端口
    -d // 宿主机项目地址,缺省为执行run.sh的上一级目录
    -n // 容器名称
    -v // 镜像版本号
    -j // jar包版本,缺省为1.0

  • 环境变量

    # 运行配置
    APP_SERVER_PORT // 容器运行jar包的端口
    # 数据库配置
    APP_DB_HOST
    APP_DB_PORT
    APP_DB_DATABASE
    APP_DB_USER
    APP_DB_PASSWORD
    # 日志配置
    APP_LOG_PATH // 日志输出地址
    APP_LOG_SPRING_WEB_LEVEL // 对应logging.level.org.springframework.web,指org.springframework.web这个包下的日志输出等级,默认为ERROR,开发环境可配置为DEBUG
    APP_LOG_MYBATIS_LEVEL // 对应logging.level.com.duomai.balance_card.Model.Mapper,指balance_card.Model.Mapper包下的日志输出等级,默认为ERROR,开发环境可配置为DEBUG,开启DEBUG之后可在日志中查看DB操作

  • 启动容器

    docker run -d \
    -e APP_SERVER_PORT=8080 \
    -e APP_DB_HOST=192.168.0.235 \
    -e APP_DB_PORT=3355 \
    -e APP_DB_DATABASE=shop_balances \
    -e APP_DB_USER=cishop \
    -e APP_DB_PASSWORD=fuyuan1906 \
    -e APP_LOG_PATH=/opt/ci123/www/html/java/balance_card/log \
    -e APP_LOG_SPRING_WEB_LEVEL=DEBUG \
    -e APP_LOG_MYBATIS_LEVEL=DEBUG \
    -p $port:80 \
    -v $dir:/opt/ci123/www/html/java/balance_card \
    --restart=always \
    --name $name \
    harbor.oneitfarm.com/duomai/java-balance_card:$version \
    sh /opt/ci123/www/html/java/balance_card/docker/start.sh -j $jarName