美文网首页我爱编程
spring boot 整合spring-data-mongod

spring boot 整合spring-data-mongod

作者: 搁浅_Jay | 来源:发表于2018-07-25 17:39 被阅读479次

spring boot 整合spring-data-mongodb自定义接口扩展

  • 这里使用的依然是SpringBoot 1.5.9.RELEASE和JDK1.8

1、添加Maven依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

2、添加数据源配置

application.yml

spring:
  data:
    mongodb:
      host: localhost
      port: 27017
      database: test
      username: admin
      password: admin

3、创建公共Base接口

公共接口声明BaseMongoRepository.java

package com.lilian.base.mongo;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.NoRepositoryBean;

import java.io.Serializable;

/**
 * jpa-demo
 * 在此类中添加自定义的方法
 *
 * @Author 孙龙
 * @Date 2018/7/9
 */
@NoRepositoryBean
public interface BaseMongoRepository<T, ID extends Serializable>
        extends MongoRepository<T, ID> {

    /**
     * 自定义分页查询
     *
     * @param query
     * @param pageable
     * @return
     */
    Page<T> findPageByQuery(Query query, Pageable pageable);

    /**
     * 自定义分页查询
     *
     * @param criteria
     * @param pageable
     * @return
     */
    Page<T> findPageByCriteria(Criteria criteria, Pageable pageable);
}
  • 需要添加@NoRepositoryBean注解来说明此接口不是一个声明的Repository,否则Spring默认当做普通的Repository来处理;
  • 可以在此接口中生命一些自定义的接口公共方法;
    公共接口实现类SimpleBaseMongoRepository
package com.lilian.base.mongo;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;

import java.io.Serializable;
import java.util.List;

/**
 * jpa-demo
 * 自定义接口中方法的实现
 *
 * @Author 孙龙
 * @Date 2018/7/9
 */
public class SimpleBaseMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> implements BaseMongoRepository<T, ID> {

    private final MongoOperations mongoOperations;

    private final MongoEntityInformation<T, ID> entityInformation;

    public SimpleBaseMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) {
        super(metadata, mongoOperations);
        this.mongoOperations = mongoOperations;
        this.entityInformation = metadata;
    }

    protected Class<T> getEntityClass() {
        return entityInformation.getJavaType();
    }

    @Override
    public Page<T> findPageByQuery(Query query, Pageable pageable) {
        long total = mongoOperations.count(query, getEntityClass());
        List<T> list = mongoOperations.find(query.with(pageable), getEntityClass());

        return new PageImpl<T>(list, pageable, total);
    }

    @Override
    public Page<T> findPageByCriteria(Criteria criteria, Pageable pageable) {
        return findPageByQuery(new Query(criteria), pageable);
    }
}

4、重写MongoRepositoryFactoryBean中的方法

BaseMongoRepositoryFactoryBean.java

package com.lilian.base.mongo;

import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
import org.springframework.data.mongodb.repository.support.QueryDslMongoRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;

import java.io.Serializable;

import static org.springframework.data.querydsl.QueryDslUtils.QUERY_DSL_PRESENT;

/**
 * jpa-demo
 *
 * @Author 孙龙
 * @Date 2018/7/10
 */
public class BaseMongoRepositoryFactoryBean<T extends MongoRepository<S, ID>, S, ID extends Serializable>
        extends MongoRepositoryFactoryBean<T, S, ID> {

    public BaseMongoRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
        super(repositoryInterface);
    }

    @Override
    protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
        return super.getFactoryInstance(operations);
    }

    private static class LCRRepositoryFactory<S, ID extends Serializable> extends MongoRepositoryFactory {

        private final MongoOperations mongoOperations;

        public LCRRepositoryFactory(MongoOperations mongoOperations) {
            super(mongoOperations);
            this.mongoOperations = mongoOperations;
        }

        @Override
        protected Object getTargetRepository(RepositoryInformation information) {
            Class<?> repositoryInterface = information.getRepositoryInterface();
            MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType());
            if (isQueryDslRepository(repositoryInterface)) {
                return new QueryDslMongoRepository(entityInformation, mongoOperations);
            } else {
                return new SimpleBaseMongoRepository<S, ID>((MongoEntityInformation<S, ID>) entityInformation, this.mongoOperations);
            }
        }


        private static boolean isQueryDslRepository(Class<?> repositoryInterface) {
            return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
        }

        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
            return isQueryDslRepository(metadata.getRepositoryInterface()) ? QueryDslMongoRepository.class
                    : SimpleBaseMongoRepository.class;
        }
    }
}

5、覆盖SpringBoot提供的默认配置

MongoRepositoryConfig.java

package com.lilian.base;

import com.lilian.base.mongo.BaseMongoRepositoryFactoryBean;
import com.lilian.base.mongo.SimpleBaseMongoRepository;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

/**
 * jpa-demo
 * 自定义jpa配置类
 *
 * @Author 孙龙
 * @Date 2018/7/2
 */
@Configuration
@EnableMongoRepositories(repositoryBaseClass = SimpleBaseMongoRepository.class, basePackages = {"com.lilian.repository.mongo"}, repositoryFactoryBeanClass = BaseMongoRepositoryFactoryBean.class)
public class MongoRepositoryConfig {
}
  • basePackages参数指定的是普通Repository所在的路径,可以指定多个

6、使用Base接口开发

(1)创建实体类

Student.java

package com.lilian.entity.mongo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Id;
import java.util.Date;

/**
 * jpa-demo
 *
 * @Author 孙龙
 * @Date 2018/7/9
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student {

    @Id
    private String id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 地址
     */
    private String addr;
    /**
     * 邮箱
     */
    private String email;
    /**
     * 添加时间
     */
    private Date addTime;
    /**
     * 手机号
     */
    private String phoneNum;

}

(2)创建Repository

StudentRepository.java

package com.lilian.repository.mongo;

import com.lilian.base.mongo.BaseMongoRepository;
import com.lilian.entity.mongo.Student;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;

/**
* jpa-demo
*
* @Author 孙龙
* @Date 2018/7/9
*/
public interface StudentRepository extends BaseMongoRepository<Student, String> {
   /**
    * 根据地址查询所有
    *
    * @param addr
    * @return
    */
   List<Student> findAllByAddr(String addr);

   /**
    * 根据实体类中的属性进行模糊查询
    *
    * @param name
    * @return
    */
   List<Student> findByNameLike(String name);

   /**
    * 根据实体类中的属性进行模糊查询带分页
    * 带分页的模糊查询,其实是把模糊查询以及分页进行合并,
    * 定义方法名的规则和模糊查询的规则一致,只是参数不同而已。
    *
    * @param name
    * @param pageable
    * @return
    */
   Page<Student> findByNameLike(String name, Pageable pageable);

   /**
    * 查询年龄小于某值的所有数据
    *
    * @param maxAge
    * @return
    */
//    @Query("")
   List<Student> findAllByAgeLessThan(int maxAge);
}

(3)Service层

IStudentService.java

package com.lilian.service.mongo;

import com.lilian.entity.mongo.Student;
import org.springframework.data.domain.Page;

import java.util.List;

/**
 * jpa-demo
 *
 * @Author 孙龙
 * @Date 2018/7/9
 */
public interface IStudentService {
    /**
     * 查询全部(自带)
     *
     * @return
     */
    List<Student> queryAll();

    /**
     * 批量插入(自带)
     */
    void batchSave(List<Student> studentList);

    /**
     * 根据地址查询全部(名称拼接方式)
     *
     * @param address
     * @return
     */
    List<Student> queryAllByAddr(String address);

    /**
     * 根据实体类中的属性进行模糊查询
     *
     * @param name
     * @return
     */
    List<Student> queryByNameLike(String name);

    /**
     * 模糊查询加分页
     *
     * @param page
     * @param rows
     * @param name
     * @return
     */
    Page<Student> queryByNameAndPage(int page, int rows, String name);

    /**
     * 根据最大年龄查询所有学生
     *
     * @param age
     * @return
     */
    List<Student> queryAllByAgeLessThan(int age);

    /**
     * 根据年龄范围查询全部(Example查询方式)
     *
     * @param student
     * @return
     */
    List<Student> queryByVo(Student student);
}

StudentServiceImpl.java

package com.lilian.service.mongo.impl;

import com.lilian.entity.mongo.Student;
import com.lilian.repository.mongo.StudentRepository;
import com.lilian.service.mongo.IStudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * jpa-demo
 *
 * @Author 孙龙
 * @Date 2018/7/9
 */
@Service
public class StudentServiceImpl implements IStudentService {

    @Autowired
    private StudentRepository studentRepository;

    @Override
    public List<Student> queryAll() {

        return studentRepository.findAll();
    }

    @Override
    public void batchSave(List<Student> studentList) {
        studentRepository.insert(studentList);
    }

    @Override
    public List<Student> queryAllByAddr(String address) {
        return studentRepository.findAllByAddr(address);
    }

    @Override
    public List<Student> queryByNameLike(String name) {
        return studentRepository.findByNameLike(name);
    }

    @Override
    public Page<Student> queryByNameAndPage(int page, int rows, String name) {
        PageRequest pageRequest = new PageRequest(page, rows);
        return studentRepository.findByNameLike(name, pageRequest);
    }

    @Override
    public List<Student> queryAllByAgeLessThan(int age) {
        return studentRepository.findAllByAgeLessThan(age);
    }

    @Override
    public List<Student> queryByVo(Student student) {

        Example<Student> example = Example.of(student);

        return studentRepository.findAll(example);
    }
}

7、测试类

StudentServiceImplTest.java

package com.lilian.service.mongo.impl;

import com.lilian.entity.mongo.Student;
import com.lilian.service.mongo.IStudentService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * jpa-demo
 *
 * @Author 孙龙
 * @Date 2018/7/9
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class StudentServiceImplTest {

    @Autowired
    private IStudentService studentService;

    @Test
    public void queryAll() {

        List<Student> studentList = studentService.queryAll();
        for (Student student : studentList) {
            System.out.println(student);
        }
    }

    @Test
    public void batchSave() {
        List<Student> studentList = new ArrayList<Student>() {{
            add(new Student("dsrfj3frs", "马云", 35, "杭州", "master@alibaba.com", new Date(System.currentTimeMillis() - 10000L), "186666666"));
            add(new Student("gfrgtr54d", "周鸿祎", 25, "北京", "master@360.com", new Date(System.currentTimeMillis() - 20000L), "1822222222"));
            add(new Student("iuti7thty", "马化腾", 40, "深圳", "master@qq.com", new Date(System.currentTimeMillis() - 30000L), "183333333"));
            add(new Student("vchfgdher", "丁磊", 25, "杭州", "master@163.com", new Date(System.currentTimeMillis() - 40000L), "1844444444"));
        }};
        studentService.batchSave(studentList);
    }

    @Test
    public void queryAllByAddr() {
        String address = "杭州";
        List<Student> studentList = studentService.queryAllByAddr(address);
        for (Student student : studentList) {
            System.out.println(student);
        }

    }

    @Test
    public void queryByNameLike() {
        String name = "马";
        List<Student> studentList = studentService.queryByNameLike(name);
        for (Student student : studentList) {
            System.out.println(student);
        }
    }

    @Test
    public void queryByNameAndPage() {
        String name = "马";
        Page<Student> studentPage = studentService.queryByNameAndPage(0, 10, name);
        System.out.println("总条数" + studentPage.getTotalElements());
        System.out.println("总页数" + studentPage.getTotalPages());
        //数据列表
        List<Student> studentList = studentPage.getContent();
        for (Student student : studentList) {
            System.out.println(student);
        }
    }

    @Test
    public void queryAllByAgeLessThan() {
        int age = 35;
        List<Student> studentList = studentService.queryAllByAgeLessThan(age);
        for (Student student : studentList) {
            System.out.println(student);
        }

    }

    @Test
    public void queryByVo() {
        Student student = new Student(null, null, 25, "杭州", null, null, null);
        List<Student> studentList = studentService.queryByVo(student);
        for (Student student1 : studentList) {
            System.out.println(student1);
        }
    }
}

github代码示例
示例中包含Spring data jpa对Mysql数据库操作自定义接口的封装和使用

相关文章