在本文中,我们的目标是启动并运行能够与MongoDB进行交互的基本Java应用程序。 就其本身而言,这并不是一项艰巨的任务,也许您可以在10分钟内完成。 单击此处或单击此处或单击此处 ,以获得一些出色的材料。 但是,我想进一步推动它。
我想添加ORM支持。 我已为本文选择了Morphia 。 我还想添加DAO模式,单元测试和日志记录。 简而言之,我想感觉到,“几乎就像”我们大多数人使用Java,Hibernate和Oracle为企业应用程序编写的那种代码。 并且,我们将尝试在30分钟内完成所有这些操作。
我的意图是让Java + RDBMS开发人员放心,Java + NoSQL并不是很陌生。 这是相似的代码,易于尝试。 在这一点上可能需要补充一点,即我与NoSQL没有亲和力,RDBMS也没有问题。 我相信它们都有自己的用途( 单击此处以获取一些出色的材料)。 作为技术专家,我只是喜欢更好地了解自己的工具,以便为自己的职业伸张正义。 本文仅旨在帮助志趣相投的人们在NoSQL中投入脚步。
好的,足够说话了。 让我们开始吧。 在遵循本文之前,您将需要一些软件/工具。 下载并安装 MongoDB服务器(如果尚未安装) 。 我假设您有Java,一些Java IDE以及构建和发布工具。 我在本文中使用jdk 7,Eclipse(STS)和Maven 3。
我首先使用Maven创建一个香草标准Java应用程序。 我喜欢为此使用批处理文件。
文件:codeRepo \ MavenCommands.bat
ECHO OFFREM =============================
REM Set the env. variables.
REM =============================
SET PATH=%PATH%;C:\ProgramFiles\apache-maven-3.0.3\bin;
SET JAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0REM =============================
REM Create a simple java application.
REM =============================
call mvn archetype:create ^-DarchetypeGroupId=org.apache.maven.archetypes ^-DgroupId=org.academy ^-DartifactId=dbLayer002pause
将其导入Eclipse。 确保可以使用Maven进行编译和运行。
mvn -e clean install.
这应该编译代码并运行默认测试。 一旦克服了这一障碍,现在让我们开始一些编码。 让我们创建一个Entity对象作为开始。 我认为使用fname的Person类可以达到我们的目的。 我承认这很简单,但是可以完成教程。
文件:/dbLayer002/src/main/java/org/academy/entity/Person.java
package org.academy.entity;public class Person {private String fname;[...]
}
为了简洁起见,我没有提到吸气剂和吸气剂。
现在,让我们获取MongoDB Java驱动程序并将其附加到应用程序。 我喜欢让Maven为我做这件事。 您显然也可以手动执行此操作。 你的选择。 我很懒。
文件:/dbLayer002/pom.xml
[...]
<!-- MongDB java driver to hook up to MongoDB server -->
<dependency><groupId>org.mongodb</groupId><artifactId>mongo-java-driver</artifactId><version>2.7.3</version>
</dependency>
[...]
这将使我们能够编写一个util类来连接到MongoDB服务器实例。 我假设您已经使用默认设置在服务器中启动并运行了服务器。
文件:/dbLayer002/src/main/java/org/academy/util/MongoUtil.java
public class MongoUtil {private final static Logger logger = LoggerFactory.getLogger(MongoUtil.class);private static final int port = 27017;private static final String host = "localhost";private static Mongo mongo = null;public static Mongo getMongo() {if (mongo == null) {try {mongo = new Mongo(host, port);logger.debug("New Mongo created with [" + host + "] and ["+ port + "]");} catch (UnknownHostException | MongoException e) {logger.error(e.getMessage());}}return mongo;}
}
我们需要在我们的应用程序中设置记录器,以便此类编译。 单击此处获取有关日志记录的文章。 我们需要做的就是用正确的依赖关系连接Maven。
文件:/dbLayer002/pom.xml
[...]
<slf4j.version>1.6.1</slf4j.version>
[...]
<!-- Logging -->
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version>
</dependency>
<dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>${slf4j.version}</version><scope>runtime</scope>
</dependency>
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version><scope>runtime</scope>
</dependency>
而且,我们将需要确切指定要记录的内容。
文件:/dbLayer002/src/java/resources/log4j.properties
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1# configure A1 to spit out data in console
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
至此,您已经具有一个Entity类和一个实用程序类来连接数据库。 理想情况下,我将去编写DAO,然后以某种方式使用ORM将DAO与数据库连接起来。 但是,Morphia具有一些出色的DAO支持。 它还具有一些注释,可以将实体与数据库元素绑定在一起。 因此,尽管我希望Entity和DAO完全不了解ORM和数据库,但在这里情况并非如此。 我从表面上知道,这听起来像Morphia或MongoDB迫使我偏离良好的代码结构,让我赶紧补充一点,这并不比其他ORM差,例如带有注释的Hibernate也会迫使我做同样的妥协。
因此,让我们在图片中引入Morphia。 进入阶段,我们永远有用的工具Maven。 这里有点可避免的障碍。 在编写此文档时,无法在中央Maven存储库中获得所需的Morphia版本。 因此,我必须将Maven配置为也使用Morphia存储库。 希望这只是暂时的情况。
文件:/dbLayer002/pom.xml
[...]
<!-- Required for Morphia -->
<repositories><repository><id>Morphia repository</id><url>http://morphia.googlecode.com/svn/mavenrepo/</url></repository>
</repositories>
[...]
<!-- Morphia - ORM for MongoDB -->
<dependency><groupId>com.google.code.morphia</groupId><artifactId>morphia</artifactId><version>0.98</version>
</dependency>
如前所述,Morphia允许我们注释Entity类(非常类似于Hibernate注释)。 因此,这是更新后的Entity类的外观。
文件:/dbLayer002/src/main/java/org/academy/entity/Person.java
[...]
@Entity
public class Person {@Id private ObjectId id;[...]
现在,我们还可以添加一个DAO层,并依靠Morphia提供的BasicDAO。
文件:/dbLayer002/src/main/java/org/academy/dao/PersonDAO.java
public class PersonDAO extends BasicDAO<Person, ObjectId> {public PersonDAO(Mongo mongo, Morphia morphia, String dbName) {super(mongo, morphia, dbName);}[...]
BasicDAO的优点在于,尽管我刚刚添加了一个构造函数,但通过扩展它,我自己的DAO类已经具有足够的功能来执行基本的CRUD操作。 不相信吗? 好吧,让我们为此做一个测试。
文件:/dbLayer002/src/test/java/org/academy/dao/PersonDAOTest.java
public class PersonDAOTest {private final static Logger logger = LoggerFactory.getLogger(PersonDAOTest.class);private Mongo mongo;private Morphia morphia;private PersonDAO personDao;private final String dbname = "peopledb";@Beforepublic void initiate() {mongo = MongoUtil.getMongo();morphia = new Morphia();morphia.map(Person.class);personDao = new PersonDAO(mongo, morphia, dbname);}@Testpublic void test() {long counter = personDao.count();logger.debug("The count is [" + counter + "]");Person p = new Person();p.setFname("Partha");personDao.save(p);long newCounter = personDao.count();logger.debug("The new count is [" + newCounter + "]");assertTrue((counter + 1) == newCounter);[...]
您可能已经注意到了。 我已经使用过JUnit4。如果您一直在关注此文章,那么您的项目中将拥有JUnit的早期版本。 为了确保使用JUnit 4,只需通过在pom.xml中添加正确的依赖关系来配置Maven以使用它。
文件:/dbLayer002/pom.xml
<!-- Unit test. -->
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><scope>test</scope>
</dependency>
你已准备好出发。 如果您运行测试,则它们应该通过。 当然,您可以/应该进入数据库并检查数据是否确实已保存。 我将向您推荐我认为相当不错的MongoDB文档 。
最后但并非最不重要的一点,让我向您保证,BasicDAO在任何方面都不是限制性的。 我敢肯定,清教徒会指出,如果我的DAO类需要扩展BasicDAO,那无论如何还是对源代码结构的限制。 理想情况下,不需要。 我同意这一点。 但是,我也想表明,对于DAO的所有实际目的,您都具有足够的灵活性。 让我们继续,向我们的DAO添加一个自定义的find方法,该方法特定于该Entity即Person。 假设我们希望能够基于名字进行搜索,并且我们希望为此使用正则表达式。 这是代码的样子。
文件:/dbLayer002/src/main/java/org/academy/dao/PersonDAO.java
public class PersonDAO extends BasicDAO<Person, ObjectId> {[...]public Iterator<Person> findByFname(String fname){Pattern regExp = Pattern.compile(fname + ".*", Pattern.CASE_INSENSITIVE);return ds.find(entityClazz).filter("fname", regExp).iterator();}[...]
}
在这里需要再次强调的是,我刚刚在DAO中添加了一个自定义搜索功能,方法是精确添加三行代码(如果添加最后一个括号,则为四行)。 在我的书中,这很灵活。 忠实于我对自动化测试的坚定信念,因此在我们总结之前,请添加一个快速测试以检查此功能。
文件:/dbLayer002/src/test/java/org/academy/dao/PersonDAOTest.java
[...]
Iterator<Person> iteratorPerson = personDao.findByFname("Pa");
int personCounter = 0 ;
while(iteratorPerson.hasNext()){personCounter ++;logger.debug("["+personCounter+"]" + iteratorPerson.next().getFname());
}
[...]
在指出之前,是的,这里没有assert(),所以这不是真正的测试。 让我向您保证,我的测试课程确实已经完成。 只是这里的代码片段没有assert函数。
就是这样了。 您已经使用Java通过ORA通过DAO层连接到NoSQL数据库(在这里您已使用ORM的功能并做了一些添加)。 您还完成了正确的日志记录和单元测试。 半个小时可以用,不是吗? 快乐的编码。
进一步阅读
- 也可以通过Javalobby的此链接获得本文的一个版本-稍作编辑。
参考: 在我们的JCG合作伙伴 Partho的30分钟内,从Tech for Enterprise博客获得了MongoDB 。
翻译自: https://www.javacodegeeks.com/2012/07/mongodb-in-30-minutes.html