Spring DAO(6): 集成 MongoDB(spring-data-mongo)

版权声明:转载随意,附上转载信息即可 :) https://blog.csdn.net/Al_assad/article/details/79345021

MongoDB 入门专栏

http://blog.csdn.net/column/details/19681.html


Spring 集成 MongoDB


如果在 Java 项目中直接使用 MongoDB 提供的驱动,需要进行大量的 Document 对象和 POJO 之间的转换,其中很大部分需要手工编写代码,这个过程很繁琐,Spring 子项目 Spring Data MongoDB 提供了一种 Spring 风格的 MongoTemplate ,能够比较优雅地进行 Mongodb Document 和 POJO 之间的自动转换;
Spring Data Mongo 项目主页: https://projects.spring.io/spring-data-mongodb/

在项目中引入 Spring Data Mongo ,需要引入依赖包: org.springframework.data:spring-data-mongodb

关于 MongoTemplate 
MongoTemplate 成员方法 find(),update(),remove(),insert(),aggregate() 等分别对应 mongodb 的 CRUD,数据聚合方法,对于 mongodb 各种操作符(查询操作符,更新操作符),spring-data-mongo 提供了 Query 对象,Update 对象分别支持查询、更新对象,这些对象使用封装的链式函数方法来支持这些操作符,比如一下:
 
// mongodb 查询语句 db.blog.find({"author":"assad"})
// 使用 BasicQuery 支持支持原生 mongo query 语句
Query query = new BasicQuery("{author:'assad'}");
List<Blog> blogs = db.blog.find(query, Blog.class, "blog");
//使用 Query 提供的操作符封装
Query query = query(where("author").is("assad"));
List<Blog> blogs = db.blog.find(query, Blog.class, "blog");
这些封装的操作符函数和原生操作符之间的对应关系,详见:


简单示例

以下通过一个简单的 CRUD 项目,演示 spring data mongo 的基本使用,使用 2.0 版本,完整示例代码: https://gitee.com/assad/spring-data-mongo-sample

mongodb 中待操作的文档结构如下, testdb.user:
 
{
        "_id" : ObjectId("5a8d7536cc8d632363f514f7"),
        "name" : "assad",
        "password" : "2333",
        "city" : "guangzhou",
        "birthday" : ISODate("1994-12-31T00:00:00Z")
}
{
        "_id" : ObjectId("5a8d7556cc8d632363f514f8"),
        "name" : "tim",
        "password" : "212312",
        "city" : "guangzhou",
        "birthday" : ISODate("1994-08-03T00:00:00Z")
}
{
        "_id" : ObjectId("5a8d756fcc8d632363f514f9"),
        "name" : "vancy",
        "password" : "y3781",
        "city" : "shanghai",
        "birthday" : ISODate("1992-08-03T00:00:00Z")
}
....


演示项目使用 gradle 构建, build.gradle 脚本中依赖相关的部分如下:
 
dependencies {
    //spring core 依赖
    compile "org.springframework:spring-beans:4.3.11.RELEASE"
    compile "org.springframework:spring-core:4.3.11.RELEASE"
    compile "org.springframework:spring-context:4.3.11.RELEASE"
    compile "org.springframework:spring-context-support:4.3.11.RELEASE"
    //spring-data-mongodb 依赖
    compile 'org.springframework.data:spring-data-mongodb:2.0.4.RELEASE'
    //spring test 依赖
    compile "org.springframework:spring-test:4.3.11.RELEASE"
    testCompile "junit:junit:4.12"
    compile 'org.slf4j:slf4j-nop:1.7.25'
    compile "org.apache.logging.log4j:log4j-core:2.9.0"
    compile "org.apache.logging.log4j:log4j-api:2.9.0"
}


编写 POJO, site.assad.domain.User
 
package site.assad.domain;
public class User{
    private String id;
    private String name;
    private String password;
    private String city;
    private Date birthday;
    // getter & setter
}

编写 mongo jdbc 连接属性文件,jdbc.properties
 
# mongodb 连接配置
mongo.dbname=testdb
mongo.host=127.0.0.1
mongo.port=27017
mongo.user=assad
mongo.password=mongo1994
# 每个线程最大连接数
mongo.connectionsPerHost=10
# 线程队列数,与以上参数相乘得到线程对列最大值
mongo.threadsAllowToBlockForConnectionMultiplier=5
# 线程连接超时(单位:毫秒)
mongo.connectionTimeout=1500
# 阻塞线程最大等待时间(单位:毫秒)
mongo.maxWaitTime=2000
# socket 保持活动
mongo.socketKeepAlive=true
# socket 超时时间(单位:毫秒)
mongo.socketTimeout=2000

在 Spring 上下文配置文件中状态 MongoTemplate, applicationContext.xml
 
<?xml version="1.0" encoding="UTF-8"?>
<beans ....>
    <!--扫描 bean-->
    <context:component-scan base-package="site.assad.dao" />
    <!--配置属性占位符空间-->
    <context:property-placeholder location="classpath:jdbc.properties" />
    <!--配置 MongoClient-->
    <mongo:mongo-client id="mongoClient"
                        host="${mongo.host}"
                        port="${mongo.port}"
                        credentials="${mongo.user}:${mongo.password}@${mongo.dbname}">
        <mongo:client-options write-concern="SAFE"
                              connections-per-host="${mongo.connectionsPerHost}"
                              threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowToBlockForConnectionMultiplier}"
                              connect-timeout="${mongo.connectionTimeout}"
                              max-wait-time="${mongo.maxWaitTime}"
                              socket-keep-alive="${mongo.socketKeepAlive}"
                              socket-timeout="${mongo.socketTimeout}" />
    </mongo:mongo-client>
    <!--配置 MongoDbFactory -->
    <mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}" mongo-ref="mongoClient" />
    <!--配置 mongoTemplate -->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    </bean>
</beans>


编写 Dao 层 site.assad.dao.UserDao
 
package site.assad.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.data.mongodb.core.MongoTemplate;
import site.assad.domain.User;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import static org.springframework.data.mongodb.core.query.Update.update;
@Repository
public class UserDao {
    @Autowired
    private MongoTemplate mongoTemplate;
    /*演示 select 操作*/
    // db.user.findOne( {_id:ObjectId('${id}')} ):使用 BasicQuery
    public User getUserById (final String id){
        Query query = new BasicQuery(String.format("{ _id:ObjectId('%s') }",id));
        User user = mongoTemplate.findOne(query,User.class,"user");
        return user;
    }
    //db.user.findOne( {_id:ObjectId('${id}')} ) : 使用 Query.query()
    public User getUserById2(final String id){
        Query query = Query.query(where("id").is(id));
        User user = mongoTemplate.findOne(query,User.class,"user");
        // User user = mongoTemplate.findOne(query(where("id").is(id)),User.class);
        return user;
    }
    //db.user.find( {city:'${city}'} )
    public List<User> getUserByCity(final String city){
        Query query = query(where("city").is(city));
        List<User> users = mongoTemplate.find(query,User.class,"user");
        return users;
    }
    //db.user.find( {name:{$regex:/^'${beginPattern}'/i}} )
    public List<User> getUserByNameBeginWith(final String beginPattern){
        Query query = query(where("name").regex(String.format("^%s",beginPattern),"i"));
        List<User> users = mongoTemplate.find(query,User.class,"user");
        return users;
    }
    //db.user.find( {city:'${city}',birthday:{$lte:'$birthFloor'} } )
    public List<User> getUserByCityAndAge(final String city,final int age) throws ParseException {
        int yearFloor = Calendar.getInstance().get(Calendar.YEAR) - age;
        Date birthFloor = new SimpleDateFormat("yyyy").parse(yearFloor+"");
        Query query = query(where("city").is(city)
                .and("birthday").lte(birthFloor));
        List<User> users = mongoTemplate.find(query,User.class,"user");
        return users;
    }
    /*演示 insert 操作*/
    public void addUser(final User user){
        mongoTemplate.insert(user,"user");
    }
    /*演示 update 操作*/
    public long updateUserById(final User user){
        Query query = query(where("id").is(user.getId()));
        Update update = new Update();
        if(user.getName() != null )
            update.set("name",user.getName());
        if(user.getCity() != null)
            update.set("city",user.getCity());
        if(user.getPassword() != null)
            update.set("password",user.getPassword());
        if(user.getBirthday() != null)
            update.set("birthday",user.getBirthday());
        UpdateResult result = mongoTemplate.updateFirst(query,update,User.class,"user");
        return result.getModifiedCount();
    }
    /*演示 delete 操作*/
    public long removeUserById(final String id){
        DeleteResult result = mongoTemplate.remove(query(where("id").is(id)),"user");
        return result.getDeletedCount();
    }
}


部分 UserDao 的测试代码, site.assad.dao.UserDaoTest
 
package site.assad.dao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class UserDaoTest {
    @Autowired
    private UserDao userDao ;
    
    @Test
    public void testFindUserById(){
        User user1 = userDao.getUserById("5a8d756fcc8d632363f514f9");
        User user2 = userDao.getUserById2("5a8d756fcc8d632363f514f9");
        System.out.println(user1);
        System.out.println(user2);
    }
    @Test
    public void testFindUserByCity(){
        List<User> users = userDao.getUserByCity("guangzhou");
        users.forEach(System.out::println);
    }
    @Test
    public void testFindUserByNameBeginPattern(){
        List<User> users = userDao.getUserByNameBeginWith("a");
        users.forEach(System.out::println);
    }
    @Test
    public void testGetUserByCityAndAge() throws ParseException {
        List<User> users = userDao.getUserByCityAndAge("guangzhou",20);
        users.forEach(System.out::println);
    }
    @Test
    public void testAddUser() throws ParseException {
        User user = new User();
        user.setName("Oral");
        user.setPassword("21231");
        user.setCity("shanghai");
        user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1995-1-12"));
        userDao.addUser(user);
    }
    @Test
    public void testUpdateUserById(){
        User user = userDao.getUserById("5a8d756fcc8d632363f514f9");
        user.setPassword("63asu891");
        userDao.updateUserById(user);
    }
    @Test
    public void testRemoveUserById(){
        userDao.removeUserById("5a8d922e07c90847145df9af");
    }
}

猜你喜欢

转载自blog.csdn.net/Al_assad/article/details/79345021