mongodb是一款nosql,和elasticsearch相同点是他们都不擅长存储关系型数据,但是擅长存储大数据。与elasticsearch相比mongodb擅长插入,elasticsearch擅长查询。另外elasticsearch支持全文索引,mongodb虽然也有但是太弱了。可是elasticsearch的mapping不可变,但是mongodb的mapping是可变的。所以如果经费足的话。可以把他们做成读写分离的形式,mongodb用作写库,elasticsearch用作读库。
首先下载mongodb,地址:https://www.mongodb.com/download-center#atlas
安装方法很简单,一直点下一步,知道出现界面里面有complete和custom两个字母时,点击custom选择安装位置。然后继续点下一步,直至安装完成。
打开安装mongodb的文件夹
当然你是没有data和logs文件夹和mongo.conf文件的,
首先新建data文件夹用于mongodb存放数据,如果不指定,mongodb会报错。
然后新建logs文件夹,logs文件夹里新建mongo.log文件用于存放日志。
然后新建mongo.conf文件,内容为
# 数据库路径
dbpath=D:\mongodb\data
# 日志输出文件路径
logpath=D:\mongodb\logs\mongo.log
# 错误日志采用追加模式
logappend=true
# 启用日志文件,默认启用
journal=true
# 这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
quiet=true
# 端口号 默认为27017
port=27017
其中dapath和logpath是你自己刚才定义的data和mongo.log的路径
最后启动mongodb:
打开cmd,cd到mongodb安装路径的bin目录下,输入mongod --config "D:\Mongo\mongo.conf"。这里是你自己的mong.conf的路径。如果没有出现任何信息,那说明成功了。
接下来安装mongodb可视化工具mongodb compass,地址:https://www.mongodb.com/download-center?jmp=blog#compass,安装方法也很简单,一直下一步就行。接下来说一下使用方法。
安装好后,打开compass
其中hostnae和port分别表示你的mongodb的连接路径和端口,这里因为是本地安装而且没改啥配置文件,所以使用默认的就好,点击connect然后就看到mongodb的一些默认的库。
其中pantest是我自己建的库,点击create database新建一个库。
接下来就是如何使用java代码来操作mongodb。
首先是pom文件需要添加
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.7.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-log4j</artifactId>
<version>1.7.1.RELEASE</version>
</dependency>
config.properties文件新加入
mongo.dbname=pantest #数据库的名字
mongo.host=localhost #mongodb的连接路径
mongo.port=27017 #端口
mongo.connectionsPerHost=8
mongo.threadsAllowedToBlockForConnectionMultiplier=4
mongo.connectTimeout=1000
mongo.maxWaitTime=1500
mongo.autoConnectRetry=true
mongo.socketKeepAlive=true
mongo.socketTimeout=1500
mongo.slaveOk=true
mongo.writeNumber=1
mongo.writeTimeout=0
mongo.writeFsync=true
application.xml文件新加入关于mongodb的相关内容
<!-- MongoDB配置部分 1.mongo:连接配置 2.db-factory:相当于sessionFactory 3.mongoTemplate:与数据库接口交互的主要实现类 -->
<mongo:mongo host="${mongo.host}" port="${mongo.port}">
<mongo:options connections-per-host="${mongo.connectionsPerHost}"
threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
connect-timeout="${mongo.connectTimeout}" max-wait-time="${mongo.maxWaitTime}"
auto-connect-retry="${mongo.autoConnectRetry}" socket-keep-alive="${mongo.socketKeepAlive}"
socket-timeout="${mongo.socketTimeout}" slave-ok="${mongo.slaveOk}"
write-number="${mongo.writeNumber}" write-timeout="${mongo.writeTimeout}"
write-fsync="${mongo.writeFsync}" />
</mongo:mongo>
<mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}"
mongo-ref="mongo" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
新建存储pojo类,并且使用注解指定mapping
/**
* @description
* @auth panmingshuai
* @time 2018年3月22日上午12:19:50
*
*
* @Id - 用于字段级别,标记这个字段是一个主键,默认生成的名称是“_id”
* @Document - 用于类,以表示这个类需要映射到数据库,您也可以指定映射到数据库的集合名称
* @DBRef - 用于字段,以表示它将使用com.mongodb.DBRef进行存储。
* @Indexed - 用于字段,表示该字段需要如何创建索引
* @CompoundIndex - 用于类,以声明复合索引
* @GeoSpatialIndexed - 用于字段,进行地理位置索引
* @TextIndexed - 用于字段,标记该字段要包含在文本索引中
* @Language - 用于字段,以设置文本索引的语言覆盖属性。
* @Transient - 默认情况下,所有私有字段都映射到文档,此注解将会去除此字段的映射
* @PersistenceConstructor - 标记一个给定的构造函数,即使是一个protected修饰的,
* 在从数据库实例化对象时使用。构造函数参数通过名称映射到检索的DBObject中的键值。
* @Value - 这个注解是Spring框架的一部分。在映射框架内,它可以应用于构造函数参数。
* 这允许您使用Spring表达式语言语句来转换在数据库中检索的键值,然后再用它来构造一个域对象。
* 为了引用给定文档的属性,必须使用以下表达式:@Value("#root.myProperty"),root要指向给定文档的根。
* @Field - 用于字段,并描述字段的名称,因为它将在MongoDB BSON文档中表示,允许名称与该类的字段名不同。
* @Version - 用于字段锁定,保存操作时检查修改。初始值是0,每次更新时自动触发。
*
*/
@Document(collection = "panuser")
public class User implements Serializable {
/** serialVersionUID */
private static final long serialVersionUID = 1L;
// 主键使用此注解
@Id
private String id;
// 字段使用此注解
@Field
private String name;
// 字段还可以用自定义名称
@Field("myage")
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
接下来就是增删查改的方法,
首先获取mongoTemplate,使用它来完成增删查改。
// 使用spring整合的话, 就直接注入就可以了, 这是测试。
@Before
public void testBefore() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-servlet.xml");
mongoTemplate = (MongoTemplate) context.getBean("mongoTemplate");
}
插入一条数据:
@Test
public void testAddUser() {
User pan = new User();
pan.setId("3");
pan.setAge(19);
pan.setName("shuai");
// 插入数据
mongoTemplate.insert(pan);
}
可以通过compass查看是否增加了一条数据
更新数据:
@Test
public void testUpdateUser() {
// update(query,update,class)
// Query query:需要更新哪些用户,查询参数
// Update update:操作符,需要对数据做什么更新
// Class class:实体类
Query query = new Query();
query.addCriteria(Criteria.where("_id").is("2"));
Update update = new Update();
update.set("myage", 19);
update.set("name", "pan");
mongoTemplate.updateFirst(query, update, User.class);
// update.inc("age", 2); age值加2
// update.set("name", "zhangsan"); 直接赋值
// update.unset("name"); 删去字段
// update.push("interest", "java"); 把java追加到interest里面,interest一定得是数组
// update.pushAll("interest", new
// String[]{".net","mq"});用法同push,只是pushAll一定可以追加多个值到一个数组字段内
//
// update.pull("interest", "study"); 作用和push相反,从interest字段中删除一个等于value的值
// update.pullAll("interest", new String[]{"sing","dota"})作用和pushAll相反
// update.addToSet("interest", "study") 把一个值添加到数组字段中,而且只有当这个值不在数组内的时候才增加
// update.rename("oldName", "newName") 字段重命名
// 只更新第一条记录,age加2,name值更新为zhangsan
// mongoTemplate.updateFirst(query, new Update().inc("age",
// 2).set("name", "zhangsan"), User.class);
// 批量更新,更新所有查询到的数据
// mongoTemplate.updateMulti(query, update, User.class);
}
查询数据:
@Test
public void testQueryUser() {
// 查询主要用到Query和Criteria两个对象
Query query = new Query();
Criteria criteria = Criteria.where("myage").gt(18); // 大于
// criteria.and("name").is("ming");等于
// criteria.and("interest").in(interests); in查询
// criteria.and("home.address").is("henan"); 内嵌文档查询
// criteria.and("").exists(false); 列存在
// criteria.and("").lte(); 小于等于
// criteria.and("").regex(""); 正则表达式
// criteria.and("").ne(""); 不等于
// 或查询
// criteria.orOperator(Criteria.where("key1").is("0"),Criteria.where("key1").is(null));
query.addCriteria(criteria);
// 排序查询sort方法,按照age降序排列
query.with(new Sort(new Order(Direction.DESC, "myage")).and(new Sort(new Order(Direction.ASC, "name"))));
List<User> userList1 = mongoTemplate.find(query, User.class);
System.out.println(userList1);
// 指定字段查询,只查询age和name两个字段
// query.fields().include("age").include("name");
// List<User> userList3 = mongoTemplate.find(query, User.class);
// printList(userList3);
// 分页查询
// query.skip(2).limit(3);
// List<User> userList4 = mongoTemplate.find(query, User.class);
// printList(userList4);
// 查询所有
// printList(mongoTemplate.findAll(User.class));
// 统计数据量
// System.out.println(mongoTemplate.count(query, User.class));
}
删除数据:
@Test
public void testRemoveUser() {
Query query = new Query();
Criteria criteria = Criteria.where("age").gt(18);
// 删除年龄大于22岁的用户
query.addCriteria(criteria);
mongoTemplate.remove(query, User.class);
}
需要指出的是在更新、删除数据时可以使用查询数据时使用的方法,将满足某个条件的所有数据进行更新或删除。
demo地址:https://gitee.com/panmingshuai/mongodb-demo.git