2018-03-27
springboot-集成mongodb
springboot 评论:0 浏览:618

转载请注明出处:https://oldnoop.tech/c/180.html

添加依赖

配置mongodb连接信息

修改application.properties

#spring.data.mongodb.uri=mongodb://localhost:27017/data
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=data
#spring.data.mongodb.username=
#spring.data.mongodb.password=
#spring.data.mongodb.authentication-database=
#spring.data.mongodb.field-naming-strategy=
#spring.data.mongodb.grid-fs-database=
#spring.data.mongodb.repositories.enabled=true

配置日志输出

修改application.properties:
------------------------------------------------
logging.level.root=INFO
#开启mongodb日志,输出到控制台,便于开发调试
logging.level.org.springframework.data.mongodb=DEBUG

如果使用logback,配置如下:
-----------------------------------
logback.xml

编写mongodb客户端代码

spring提供2种方式操作mongodb数据库
    可以注入MongoTemplate,来完成增删改查操作,
    也可以继承MongoRepository接口,来完成增删改查操作,
    最终都是使用MongoTemplate来操作,只不过,继承MongoRepository比较方便

注入MongoTemplate

public class Product implements Serializable {

    private static final long serialVersionUID = -6933668793511803456L;
    
    private long id;
    private String name;
    private String code;
    private Double price;
    private Date date;
    //省略其他代码

}

@Repository
public class ProductMongoDao {

    //引入起步依赖spring-boot-starter-data-mongodb
    //会自动配置MongoTemplate的bean
    //这里是用@Autowired注入这个已经自动配置的bean
    @Autowired
    private MongoTemplate mongoTemplate;
    
    public void insert(Product product){
        mongoTemplate.insert(product);
    }
    
    public Product getById(Long id){
        Criteria cri = Criteria.where("id").is(id);
        Query query = new Query(cri);
        return mongoTemplate.findOne(query, Product.class);
    }
    
    public void update(Product product){
        Criteria cri = Criteria.where("id").is(product.getId());
        Query query = new Query(cri);
        Update update = new Update();
        if(product.getName()!=null){
            update.set("name", product.getName());
        }
        if(product.getCode()!=null){
            update.set("code", product.getCode());
        }
        if(product.getPrice()!=null){
            update.set("price", product.getPrice());
        }
        if(product.getDate()!=null){
            update.set("date", product.getDate());
        }
        mongoTemplate.updateMulti(query, update, Product.class);
    }
    
    public void deleteById(Long id){
        Criteria cri = Criteria.where("id").is(id);
        Query query = new Query(cri);
        mongoTemplate.remove(query, Product.class);
    }
}

 

继承MongoRepository

MongoRepository提供了很多有用的方法,不需要再编写其他的方法

public class ProductComment implements Serializable{

    private static final long serialVersionUID = -8159197603920689789L;
    private long id;
    private Long productId;
    private Long userId;
    private String content;
    private Date date;
    //省略其他代码
    
}

@Repository
public interface ProductCommentMongoDao extends MongoRepository<ProductComment, Long> {

}

 

自增id

mongodb没有自增长的功能
手动创建序列,保存主键的下一个值,
使用mongodb的原子性操作,在拿到序列值的时候,还要更新序列值使用,findAndModify的原子操作
可以在插入方法中,手动获取id,设置id
也可以使用spring框架实现AbstractMongoEventListener

手动获取自增id并设置id

编写序列类

public class Sequence {
    private String id;
    private Long value;
    //省略其他代码
}

编写获取自增id的代码

@Repository
public class SequenceMongoDao {
    
    @Autowired
    private MongoTemplate mongoTemplate;

    public Long nextId(String collName) {
        Query query = new Query(Criteria.where("_id").is(collName));
        Update update = new Update();
        update.inc("value", 1);
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.upsert(true);
        options.returnNew(true);
        Sequence sequence = mongoTemplate.findAndModify(query, update, options,Sequence.class );
        Long value = sequence.getValue();
        return value;
    }
}

public class ProductMongoDao {

    @Autowired
    private MongoTemplate mongoTemplate;
    
    @Autowired
    private SequenceMongoDao sequenceDao;
    
    public void insert(Product product){
        //手动的获取id,设置id
        Long nextId = sequenceDao.nextId("product");
        product.setId(nextId);
        //保存数据
        mongoTemplate.insert(product);
    }
    
}


使用spring框架实现AbstractMongoEventListener

编写序列类

@Document(collection = "sequence")
public class SequenceId {
    @Id
    private String id;
    @Field("seq_id")
    private Long seqId;
    @Field("coll_name")
    private String collName;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public Long getSeqId() {
        return seqId;
    }
    public void setSeqId(Long seqId) {
        this.seqId = seqId;
    }
    public String getCollName() {
        return collName;
    }
    public void setCollName(String collName) {
        this.collName = collName;
    }
    @Override
    public String toString() {
        return "SequenceId [id=" + id + ", seqId=" + seqId + ", collName=" + collName + "]";
    }
    
}

编写ID生成器的注解类

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface IdGenerator {
 
}

编写监听器类

在保存数据之前,获取自增的id,设置id

@Component
public class SequenceListener extends AbstractMongoEventListener<Object> {

    @Autowired
    private MongoTemplate mongoTemplate;
    
    @Override
    public void onBeforeConvert(BeforeConvertEvent<Object> event) {
        if (event == null || event.getSource() == null) {
            return;
        }
        // 获取目标对象(实体类对象)
        Object source = event.getSource();
        // 回调函数
        FieldCallback fieldCallback = new FieldCallback() {
            public void doWith(Field field) throws IllegalArgumentException,
                IllegalAccessException {
                // 设置字段可见性(防止private修饰)
                ReflectionUtils.makeAccessible(field);
                // 判断字段field是否有注解@IdGenerator,
                // 实体类中主键字段id加上了注解@IdGenerator
                if (field.isAnnotationPresent(IdGenerator.class)) {
                    //如果主键字段不为null,表示不是插入操作,而是修改操作
                    //不需要自增处理
                    if (field.get(source) != null) {
                        return;
                    }
                    // 获取自增ID
                    Long nextId = getNextId(source.getClass().getSimpleName());
                    // 设置自增ID
                    field.set(source, nextId);
                }
            }
        };
        ReflectionUtils.doWithFields(source.getClass(), fieldCallback);
    }

    private Long getNextId(String collName) {
        Query query = new Query(Criteria.where("collName").is(collName));
        Update update = new Update();
        update.inc("seqId", 1);
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.upsert(true);
        options.returnNew(true);
        SequenceId seqId = mongoTemplate.findAndModify(query,
            update, options, SequenceId.class);
        return seqId.getSeqId();
    }

}

实体类加注解

@Document
public class ProductComment implements Serializable{

    private static final long serialVersionUID = -8159197603920689789L;
    
    @IdGenerator
    @Id
    private long id;
    private Long productId;
    private Long userId;
    private String content;
    private Date date;
    //省略其他代码
}



  • 转载请注明出处:https://oldnoop.tech/c/180.html

Copyright © 2018 oldnoop.tech. All Rights Reserved

鄂ICP备2023022735号-1