转载请注明出处: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;
//省略其他代码
}