使用Spring Data操作mongoDB
有一些数据的最佳表现形式是文档(document).也就是说,不要把这些数据分散在数据到多个表、节点或者实体中,将这些信息收集到一个非规范化的结构当中会更有意义。尽管两个或者以上的文档会产生关联,但是通常来讲,文档是独立的实体。能够按照这种方式优化并处理文档的数据库,我们称之为文档数据库。
MongoDB是最为流行的开源文档型数据库之一。Spring Data MongoDB 提供了三种方式在Spring应用中使用MongoDB:
1>通过注解实现对象---文档映射
2>使用MongoTemplate实现基于模板的数据库访问
3>自动化的运行Repository生成功能
为了有效的使用Spring Data MongoDB,我们需要在Spring配置中添加几个必要的Bean。
首先,我们需要MongoClient,以便于访问MongoDB数据库。
同时,我们还需要一个MongoTemplate Bean,一实现基于模板的数据库访问。
此外,但不是必须**但是强烈的推荐启用Spring Data MongoDB自动化Repository生成功能**。
package orders.config;
import com.mongodb.Mongo;
import org.springframework.boot.autoconfigure.session.SessionProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoFactoryBean;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
/**
* Created by decky on 2016/11/28.
*/
@Configuration
@EnableMongoRepositories(basePackages = "orders.db")
public class MongoConfig {
@Bean
public MongoFactoryBean mongo(){
MongoFactoryBean mongoFactoryBean = new MongoFactoryBean();
mongoFactoryBean.setHost("localhost");
return mongoFactoryBean;
}
@Bean
public MongoOperations mongoTemplate(Mongo mongo){
return neersDB");
}
}
- 以上代码中注解@EnableMongoRepositories为MongoDB启用了自动化JPA repository功能。
除此之外,第一个带有@Bean注解的方法,使用MongoFactoryBean声明了一个mongo实例。尽管我们可以使用MongoClient直接创建Mongo实例,但是如果这样做的话,knownHostException异常。
必须要处理MongoClient构造器所抛出的Un knownHostException异常。
- 另外一个@Bean注解声明了MongoTemplate bean,在它构造时,使用了@Bean方法所创建的Mongo实例的引用以及数据库的名称。稍后你将可以使用MongoTemplate来查询数据库。即使不适用MongoTemplate,我们也会需要这个Bean,因为Repositorytory的自动化生成功能在底层使用了它。如果MongoDB服务器运行在生产配置上,我认为你可能还需要启用认证功能。在这种情况下,为了访问数据库,我们还需要提供应用的凭证。
package orders.config;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.session.SessionProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.core.MongoFactoryBean;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.util.Arrays;
/**
* Created by who on 2016/11/28.
*/
@Configuration
@EnableMongoRepositories(basePackages = "orders.db")
public class MongoConfig extends AbstractMongoConfiguration {
@Autowired
private Environment env;
@Override
protected String getDatabaseName() {
return "OrdersDB";
}
@Override
public Mongo mongo() throws Exception{
MongoCredential credential=
MongoCredential.createMongoCRCredential(
env.getProperty("mongo.username"),
"OrdersDB",
env.getProperty("mongo.password").toCharArray()
);
return new MongoClient(new ServerAddress("localhost",27017), Arrays.asList(credential);
}
接下来就是为模型添加注解,实现MongoDB 持久化
package orders;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import java.awt.event.ItemEvent;
import java.util.Collection;
import java.util.LinkedHashSet;
/**
* Created by decky on 2016/11/28.
*/
@Document//这是一个文档
public class Order {
@Id//指定id
private String id;
@Field("client")//覆盖默认的域名
private String customer;
private String type;
private Collection<Item> items = new LinkedHashSet<Item>();
//其他的属性没有添加注解 除非将属性设置为顺势态的(transient) 负责java对象中的
public String getId() {
return id;
}
public String getCustomer() {
return customer;
}
public String getType() {
return type;
}
public Collection<Item> getItems() {
return items;
}
public void setId(String id) {
this.id = id;
}
public void setCustomer(String customer) {
this.customer = customer;
}
public void setType(String type) {
this.type = type;
}
public void setItems(Collection<Item> items) {
this.items = items;
}
}
我们可以看到,Order类添加了@Document注解,这样它就能够借助MongoTemplate或自动生成的repository进行持久化,其Id属性加上了@Id注解,用来指定它作为文档的ID。除此之外,customer属性上使用了@Field注解,当文档持久化的时候customer属性将映射为名client的域。
这里需要注意的是,其他的属性并没有添加注解,除非将属性设置为瞬时态的(transient),否则java对象中的所有域都会持久化为文档中的域。并且如果我们不适用@Field注解进行设置的话,那么文档中的名字将会与对应的java属性相同。
如前所属,文档可以与其他的文档产生关联,但这并不是文档型数据库的所擅长的功能。在本例购买订单与行条目的之间的关联关系中,行条目只是订单文档里面嵌套的一部分。因此,没有必要为这种关联关系添加任何注解。
package orders;
/**
* Created by decky on 2016/11/28.
*/
public class Item {
private Long id;
private Order order;
private String product;
private double price;
private int quantity;
public Order getOrder() {
return order;
}
public String getProduct() {
return product;
}
public void setProduct(String product) {
this.product = product;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getQuantity() {
;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public Long getId() {
return id;
}
}
编写MongoDB Repository
我们已经通过@EnableMongorepositories注解启用了Spring Data MongoDB的Repository功能,接下来就是创建一个接口,Repository主要基于这个接口来生成。
package orders.db;
import orders.Order;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
/**
* Created by decky on 2016/11/28.
*/
public interface OrderRepository extends MongoRepository<Order,String> {
List<Order> findByCustomer(String Customer);
List<Order> findByCustomerLike(String c);
List<Order> findByCustomerAndType(String c, String t);
@Query("{customer:'Chuck Wagon'}")
List<Order> findChucksOrde
rs();
List<Order> findByCustomerLikeAndType(String c,String t);
}
指定查询
@Query注解可以为Repository方法指定自定义的查询,@Query能够像在JPA中那样在MongoDB上。唯一不同的是,在针对MongoDB时,@Query会接受一个JSON查询,而不是JPA查询。