一、 SpringData介绍
**SpringData****是为了提供一个常见的、一致的数据访问模型,也就是说,它的目标就是为了能为所有数据库(包括关系型和非关系型)提供一致的数据操作接口,并且这些接口名非常通俗易懂,让人一看便知。**它也是基于Spring框架的,即可以直接使用Spring的IoC和AOP等特性。
它的一致性接口是怎么做到的呢?
我们知道,Java对于数据库(关系和非关系型)的操作,最原始的API都是数据库厂商在驱动里提供的,然后java对这些API进行直接使用或者进行封装,形成相应的Java层面的API,例如对于各个关系型数据库,Java将驱动API,封装成JDBC(使得对各个数据库的操作保持统一),对于MongoDB和Redis,Java是直接用驱动里的API,等等。对于每一种数据库,Java层面的API都是不一样的,开发人员使用一种数据库就要记住一套Api,SpringData就是想消除这种不一致性,使得对各种数据库的操作用同一套Api即可。具体来说,它是使用Repository接口来实现的,每一种类型的数据库,都对应一种Repository,这样接口就一致了。例如,JDBC对应SimpleJdbcRepository,MongoDB对应MongoRepository,等等。SpringData的架构如下图:
二、 SpringData操作MongoDB的两种方式及实战
1. MongoTemplate
1.1 Mongodb Driver Api操作MongoDB
mongoTemplate是对mongodb java driver api的封装,我们先了解一下使用mongodb driver api操作mongodb。
1.1.2 基本CRUD
- 引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mongodb</artifactId>
<groupId>mongodb</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springdata-mongodb</artifactId>
<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.8.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
- 实体类
package cs.entity;
import java.util.List;
public class User {
private String id;
private String name;
private int age;
private String gender;
private List<String> address;
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public List<String> getAddress() {
return address;
}
public void setAddress(List<String> address) {
this.address = address;
}
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;
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public User(String id, String name, int age, String gender, List<String> address) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.address = address;
}
public User(){}
@Override
public String toString() {
return "[id:" + this.id + "; name:" + this.name + "; age:"+ this.age +"; gender:" + this.gender +
"; address:" + this.address + "]";
}
}
- 连接配置信息
在mongodb3.7以后,MongoClient做了一次升级,由原来的com.mongodb.MongoClient升级为com.mongodb.client.MongoClient,它们的区别可以查阅官网,这里不作讨论,推荐直接用新版的,下面例子中新旧版都有,仅作参考,后续只以新版为例讲解。
package cs.connection;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.WriteConcern;
import com.mongodb.client.MongoClients;
public class ConnectionManager {
public static MongoClient connect(){
// 1. 方式1
MongoCredential credential = MongoCredential.createCredential(USERNAME,
AUTH_DB, PWD.toCharArray());
com.mongodb.MongoClient mongoClient = new com.mongodb.MongoClient(new ServerAddress(HOST, PORT),
credential, MongoClientOptions.builder().sslEnabled(false).writeConcern(WriteConcern.ACKNOWLEDGED).build());
// // 2. 方式2
// String uri = String.format("mongodb://%s:%s@%s:%d/?authSource=%s", USERNAME, PWD, HOST, PORT, AUTH_DB);
// MongoClient mongoClient = new MongoClient(new MongoClientURI(uri));
return mongoClient;
}
public static com.mongodb.client.MongoClient connect2(){
// 3. 方式3
com.mongodb.client.MongoClient mongoClient = MongoClients.create(String.format(
"mongodb://%s:%s@%s:%d/?authSource=%s", USERNAME, PWD, HOST, PORT,
AUTH_DB));
return mongoClient;
}
/**
* 服务器
*/
public static final String HOST = "localhost";
/**
* 端口
*/
public static final int PORT = 26501;
/**
* 验证数据库
*/
public static final String AUTH_DB = "admin";
/**
* 用户名
*/
public static final String USERNAME = "admin";
/**
* 密码
*/
public static final String PWD = "fiberhome";
}
- Crud
-
增加
@Test public void testInsert(){ /** * 连接数据库 */ MongoClient mongoClient = ConnectionManager.connect(); MongoDatabase user = mongoClient.getDatabase("user"); MongoCollection<Document> userCollection = user.getCollection("user"); /** * 1. 插入单个 */ Document doc1 = new Document("name", "bbb").append("age", 35); userCollection.insertOne(doc1); System.out.println("单个插入成功!"); // /** // * 2. 批量插入 // */ // Document doc2 = new Document("name", "aaa").append("age", 51); // Document doc3 = new Document("name", "bb").append("age", 52); // Document doc4 = new Document("name", "ccc").append("age", 60); // Document doc5 = new Document("name", "dddd").append("age", 73); // Document doc6 = new Document("name", "eeee").append("age", 82); // Document doc7 = new Document("name", "eeee").append("age", 23); // Document doc8 = new Document("name", "eeee").append("age", 32); // Document doc9 = new Document("name", "eeee").append("age", 46); // userCollection.insertMany(Arrays.asList(doc2, doc3, doc4, doc5, doc6, doc7, doc8, doc9)); // System.out.println("批量插入成功!"); }
-
查询
@Test public void testQuery(){ /** * 连接数据库 */ MongoClient mongoClient = ConnectionManager.connect(); // com.mongodb.client.MongoClient mongoClient = ConnectionManager.connect2(); /** * 1. 查询 * 1.1 查询所有 */ // 获取数据库 MongoDatabase user = mongoClient.getDatabase("user"); for (String collectionName : user.listCollectionNames()) { System.out.println(collectionName); } // 获取user集合 MongoCollection<Document> users = user.getCollection("user"); // 几种遍历方式 // 1. 使用for遍历 System.out.println("--------------------方式1--------------------"); for (Document document : users.find()) { // 这里可以将document封装成业务对象 // 对于自生成的id,必须用get().toString, 不能用getString() String id = document.get("_id").toString(); String name = document.getString("name"); int age = document.getInteger("age"); String gender = document.getString("gender"); List<Strin