Spring Data MongoDB
Spring Data MongoDB — это проект в рамках проекта
Spring Data, который предоставляет расширение
модели программирования Spring для написания приложений, использующих
MongoDB в качестве базы данных.
Spring Data, который предоставляет расширение
модели программирования Spring для написания приложений, использующих
MongoDB в качестве базы данных.
Для написания тестов с использованием
NoSQLUnit для приложений
Spring Data MongoDB вам не нужно ничего особенного, кроме того, что
Spring Data MongoDB использует специальное свойство, вызываемое
_class
для хранения информации о типе вместе с документом._class
Свойство хранит полное имя класса внутри документа для документа верхнего уровня, а также для каждого значения, если это сложный тип.Тип сопоставления
MappingMongoConverter используется в качестве реализации отображения типов по умолчанию, но вы можете настроить еще больше, используя@TypeAlias или реализуяTypeInformationMapper интерфейс. |
заявка
Звездный Флот попросил нас разработать приложение для хранения всех журналов членов экипажа корабля в их системах.
Для реализации этого требования мы будем использовать
базу данных MongoDB в качестве бэкэнд-системы и
Spring Data MongoDB на уровне персистентности.
Лог- документы имеют следующий
формат json :
формат json :
Пример документа журнала
{ "_class" : "com.lordofthejars.nosqlunit.springdata.mongodb.log.Log" , "_id" : 1 , "owner" : "Captain" , "stardate" : { "century" : 4 , "season" : 3 , "sequence" : 125 , "day" : 8 } , "messages" : [ "We have entered a spectacular binary star system in the Kavis Alpha sector on a most critical mission of astrophysical research. Our eminent guest, Dr. Paul Stubbs, will attempt to study the decay of neutronium expelled at relativistic speeds from a massive stellar explosion which will occur here in a matter of hours." , "Our computer core has clearly been tampered with and yet there is no sign of a breach of security on board. We have engines back and will attempt to complete our mission. But without a reliable computer, Dr. Stubbs' experiment is in serious jeopardy." ] }
Этот документ моделируется на два
Java- класса, один для всего документа, а другой для обычной части.
Звездный класс
@Document public class Stardate { private int century; private int season; private int sequence; private int day; public static final Stardate createStardate(int century, int season, int sequence, int day) { Stardate stardate = new Stardate(); stardate.setCentury(century); stardate.setSeason(season); stardate.setSequence(sequence); stardate.setDay(day); return stardate; } //Getters and Setters }
@Document public class Stardate { private int century; private int season; private int sequence; private int day; public static final Stardate createStardate(int century, int season, int sequence, int day) { Stardate stardate = new Stardate(); stardate.setCentury(century); stardate.setSeason(season); stardate.setSequence(sequence); stardate.setDay(day); return stardate; } //Getters and Setters } |
Лог класс
@Document public class Log { @Id private int logId; private String owner; private Stardate stardate; private List<String> messages = new ArrayList<String>(); //Getters and Setters }
Помимо классов моделей нам также необходим класс DAO для реализации операций CRUD и
файл контекста приложения Spring .
Класс MongoLogManager
@Repository public class MongoLogManager implements LogManager { private MongoTemplate mongoTemplate; public void create(Log log) { this.mongoTemplate.insert(log); } public List<Log> findAll() { return this.mongoTemplate.findAll(Log.class); } @Autowired public void setMongoTemplate(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } }
@Repository public class MongoLogManager implements LogManager { private MongoTemplate mongoTemplate; public void create(Log log) { this.mongoTemplate.insert(log); } public List<Log> findAll() { return this.mongoTemplate.findAll(Log.class); } @Autowired public void setMongoTemplate(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } } |
файл контекста приложения
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <context:component-scan base-package="com.lordofthejars.nosqlunit.springdata.mongodb"/> <context:annotation-config/> </beans>
В этом примере мы использовали MongoTemplate класс для доступа кMongoDB, чтобы не создавать слишком сложный пример, но в более крупном проекте я рекомендую использовать подход Spring Data Repository , реализуя CrudRepository интерфейс на классах менеджера. |
тестирование
Как было сказано ранее, вам не нужно делать ничего особенного, кроме
class
правильного использованиясвойства. Давайте посмотрим на набор данных, используемый для тестирования
findAll
метода, заполнив _log коллекциюбазы данных logs .
файл всех журналов
{ "log":[ { "_class" : "com.lordofthejars.nosqlunit.springdata.mongodb.log.Log" , "_id" : 1 , "owner" : "Captain" , "stardate" : { "century" : 4 , "season" : 3 , "sequence" : 125 , "day" : 8 } , "messages" : [ "We have entered a spectacular binary star system in the Kavis Alpha sector on a most critical mission of astrophysical research. Our eminent guest, Dr. Paul Stubbs, will attempt to study the decay of neutronium expelled at relativistic speeds from a massive stellar explosion which will occur here in a matter of hours." , "Our computer core has clearly been tampered with and yet there is no sign of a breach of security on board. We have engines back and will attempt to complete our mission. But without a reliable computer, Dr. Stubbs' experiment is in serious jeopardy." ] } , { "_class" : "com.lordofthejars.nosqlunit.springdata.mongodb.log.Log" , "_id" : 2 , "owner" : "Captain" , "stardate" : { "century" : 4 , "season" : 3 , "sequence" : 152 , "day" : 4 } , "messages" : [ "We are cautiously entering the Delta Rana star system three days after receiving a distress call from the Federation colony on its fourth planet. The garbled transmission reported the colony under attack from an unidentified spacecraft. Our mission is one of rescue and, if necessary, confrontation with a hostile force." ] } ... }
Смотрите, что для
_class
свойства установлено полное имяLog
класса.Следующим шагом является настройка
MongoTemplate
для выполнения теста.
LocalhostMongoAppConfig
@Configuration @Profile("test") public class LocalhostMongoAppConfig { private static final String DATABASE_NAME = "logs"; public @Bean Mongo mongo() throws UnknownHostException, MongoException { Mongo mongo = new Mongo("localhost"); return mongo; } public @Bean MongoTemplate mongoTemplate() throws UnknownHostException, MongoException { MongoTemplate mongoTemplate = new MongoTemplate(mongo(), DATABASE_NAME); return mongoTemplate; } }
Обратите внимание, что этот
MongoTemplate
объект будет создан только приактивном тестовом профиле.
И теперь мы можем написать
тестовый пример JUnit :
WhenAlmiralWantsToReadLogs
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:com/lordofthejars/nosqlunit/springdata/mongodb/log/application-context-test.xml") @ActiveProfiles("test") @UsingDataSet(locations = "all-logs.json", loadStrategy = LoadStrategyEnum.CLEAN_INSERT) public class WhenAlmiralWantsToReadLogs { @ClassRule public static ManagedMongoDb managedMongoDb = newManagedMongoDbRule() .mongodPath( "/Users/alexsotobueno/Applications/mongodb-osx-x86_64-2.0.5") .build(); @Rule public MongoDbRule mongoDbRule = newMongoDbRule().defaultManagedMongoDb("logs"); @Autowired private LogManager logManager; @Test public void all_entries_should_be_loaded() { List<Log> allLogs = logManager.findAll(); assertThat(allLogs, hasSize(3)); } }
В предыдущем классе есть несколько важных моментов, на которые стоит обратить внимание:
-
Поскольку
NoSQLUnit использует
правила JUnit, вы можете использовать их
@RunWith(SpringJUnit4ClassRunner)
свободно.
-
Используя
@ActiveProfiles
мы загружаем тестовую конфигурацию вместо производственных.
-
Вы можете использовать
Spring аннотации, как
@Autowired
без проблем.
Выводы
Не существует большой разницы между написанием тестов ни для одного
Spring Data MongoDB и для приложений, которые его используют. Только имейте в виду, чтобы правильно определить
_class
свойство.Мы продолжаем учиться,
Алекс.
Els astronautes volen baix, Els núvols passen com qui no di res. Amb les butxaques a les mans, Caminarem els passos d’altres peus. (Па ам Оли и Сал — Блаумут)