美文网首页数据库
spring boot + spring data mongo

spring boot + spring data mongo

作者: 金刚_30bf | 来源:发表于2018-07-17 19:47 被阅读74次

    环境

    spring boot : 2.0.3
    spring data : 2.0.8

    配置

    1. 使用@EnableMongoRepositories 注解
      需要在一个@Configuration 类上, 且需要确定该类所在的包包含repository定义所在的包。
    
    @Configuration
    @EnableMongoRepositories
    public class WeaselWebMVCConfig  implements WebMvcConfigurer{
    
        @Bean
        public LogInterceptor getLogInterceptor() {
            return new LogInterceptor();
        }
        
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(getLogInterceptor());
            WebMvcConfigurer.super.addInterceptors(registry);
        }
    }
    

    注意: 当使用该注解时如何获取 MongoTemplate引用,
    注意到该注解包含一个 模板引用:

        /**
         * Configures the name of the {@link MongoTemplate} bean to be used with the repositories detected.
         * 
         * @return
         */
        String mongoTemplateRef() default "mongoTemplate";
    

    因此,可以在代码中直接装配使用之, 如下测试代码:

        @Autowired
        private MongoTemplate mongoTemplate;
        
        @Test
        public void test4MongoTemplategen() {
            System.out.println("获取 MongoTemplate 引用。");
            
            System.out.println(this.mongoTemplate.toString());
        }
    
    1. Application 类
    @SpringBootApplication
    public class WeaselApplication {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            SpringApplication.run(WeaselApplication.class, args);
        }
    }
    

    创建domain

    package com.dus.weasel.domain;
    
    import java.util.Arrays;
    import java.util.Date;
    import java.util.concurrent.atomic.AtomicLong;
    
    public class UserInfo {
    
        //客户id、 客户名称、客户昵称、邮件地址、密码、注册时间、头像、上次登录时间、登录次数
        
        private Long userId;
        private String userName;
        private String nickName;
        private String email;
        private String pwd;
        private Date regTime;
        private byte[] headImage;
        private Date lastLoginTime;
        private AtomicLong loginCount;
        
        
        
        
        @Override
        public String toString() {
            return "UserInfo [userId=" + userId + ", userName=" + userName + ", nickName=" + nickName + ", email=" + email
                    + ", pwd=" + pwd + ", regTime=" + regTime + ", headImage=" + Arrays.toString(headImage)
                    + ", lastLoginTime=" + lastLoginTime + ", loginCount=" + loginCount + "]";
        }
        
        public Long getUserId() {
            return userId;
        }
        public void setUserId(Long userId) {
            this.userId = userId;
        }
        public String getUserName() {
            return userName;
        }
        public void setUserName(String userName) {
            this.userName = userName;
        }
        public String getNickName() {
            return nickName;
        }
        public void setNickName(String nickName) {
            this.nickName = nickName;
        }
        public String getEmail() {
            return email;
        }
        public void setEmail(String email) {
            this.email = email;
        }
        public String getPwd() {
            return pwd;
        }
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
        public Date getRegTime() {
            return regTime;
        }
        public void setRegTime(Date regTime) {
            this.regTime = regTime;
        }
        public byte[] getHeadImage() {
            return headImage;
        }
        public void setHeadImage(byte[] headImage) {
            this.headImage = headImage;
        }
        public Date getLastLoginTime() {
            return lastLoginTime;
        }
        public void setLastLoginTime(Date lastLoginTime) {
            this.lastLoginTime = lastLoginTime;
        }
        public AtomicLong getLoginCount() {
            return loginCount;
        }
        public void setLoginCount(AtomicLong loginCount) {
            this.loginCount = loginCount;
        }
        
        
        
    }
    

    创建 repository

    package com.dus.weasel.repository;
    
    import org.springframework.data.mongodb.repository.MongoRepository;
    
    import com.dus.weasel.domain.UserInfo;
    
    public interface UserInfoRepository extends MongoRepository<UserInfo, Long>{
    
    }
    

    测试

    package com.dus.repository.test;
    
    import java.util.Date;
    import java.util.List;
    import java.util.Optional;
    import java.util.concurrent.atomic.AtomicLong;
    
    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.Example;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.dus.weasel.WeaselApplication;
    import com.dus.weasel.domain.UserInfo;
    import com.dus.weasel.repository.UserInfoRepository;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes=WeaselApplication.class)// 指定spring-boot的启动类
    public class UserInfoRepositoyTests {
    
        @Autowired
        private UserInfoRepository repo;
        
        @Test
        public void testsave() {
            UserInfo user = new UserInfo();
            user.setUserName("username");
            user.setUserId(1l);
            user.setEmail("www@163.com.cn");
            user.setLastLoginTime(new Date());
            user.setNickName("nick");
            user.setRegTime(new Date());
            user.setPwd("1234");
            user.setLoginCount(new AtomicLong(0));
            user.setHeadImage("This is an image for head show! ".getBytes());
            
            System.out.println(user.toString());
            
            UserInfo resuser =  repo.insert(user);
            
            System.out.println("after insert:");
            System.out.println(resuser.toString());
            
        }
        
        @Test
        public void testfind() {
            long count = repo.count();
            System.out.println("Current db userinfo counts=" + count);
            UserInfo q = new UserInfo();
            q.setNickName("Nick");
            Example<UserInfo> exa = Example.of(q);
            
            Optional<UserInfo> user = repo.findOne(exa);
            
            if (user.isPresent()) {
                System.out.println("get Result:" + user.get().toString());
            } else {
                System.out.println("Not Result");
            }
            
            Optional<UserInfo> ru = repo.findById(1l);
            
            if (ru.isPresent()) {
                System.out.println("findById get Result:" + ru.get().toString());
            } else {
                System.out.println("findById Not Result");
            }
            
            // 分页 
            Page<UserInfo> pu = repo.findAll(PageRequest.of(0, 1));
            System.out.println("分页查询!");
            System.out.println(pu.getTotalElements());
            System.out.println(pu.getTotalPages());
            System.out.println(pu.getSize());
            System.out.println(pu.getNumber());
            System.out.println(pu.getNumberOfElements());
            
            List<UserInfo> luser = pu.getContent();
            System.out.println("list size :" + luser.size());
            System.out.println(luser.get(0).toString());
        }
    }
    
    1. 注入 UserInfoRepository repo;
    2. 插入 使用 UserInfo resuser = repo.insert(user);
      插入后库里的数据:
    { "_id" : ObjectId("5b4da0882e0694540c89394e"), "userId" : NumberLong(1), "userName" : "username", "nickName" : "nick", "email" : "www@163.com.cn", "pwd" : "1234", "regTime" : ISODate("2018-07-17T07:53:44.661Z"), "headImage" : BinData(0,"VGhpcyBpcyBhbiBpbWFnZSBmb3IgaGVhZCBzaG93ISA="), "lastLoginTime" : ISODate("2018-07-17T07:53:44.661Z"), "loginCount" : NumberLong(0), "_class" : "com.dus.weasel.domain.UserInfo" }
    
    

    注意: 这里没有映射id , 而是使用了传入的id 。
    若用使用mongdb的id, 则需要:
    在domain的类上添加Id注解 :

        @Id
        private Long userId;
    

    插入数据库的数据中没有了userId , 而是_id . 但这个Id不会自动生成,输入传入。

    1. 查询
      使用Example的查询 。

    2. 根据id的查询

    3. 分页查询

    自定义repository 方法 (通过方法名)

    在 UserInfoRepository 添加如下方法:

    public interface UserInfoRepository extends MongoRepository<UserInfo, Long>{
    
        List<UserInfo> findByNickNameAndEmail(String nickname, String email);
        List<UserInfo> findByNickNameOrEmail(String nickname, String email);
            Optional<List<UserInfo>> findByLoginCount(Long count);
    }
    

    测试 :

        @Test
        public void test4CustomQueryMethodName() {
            List<UserInfo> lu  = repo.findByNickNameAndEmail("nick", "www@163.com.cn");
            if (lu == null || lu.isEmpty()) {
                System.out.println("查询结果为空!");
            } else {
                System.out.println(lu.size());
                for ( UserInfo u : lu) {
                    System.out.println(u.toString());
                }
            }
        }
    

    测试

        @Test
        public void test4CustomQueryMethodName2() {
            List<UserInfo> lu  = repo.findByNickNameOrEmail("nick", "www@163.com.2222cn");
            if (lu == null || lu.isEmpty()) {
                System.out.println("查询结果为空!");
            } else {
                System.out.println(lu.size());
                for ( UserInfo u : lu) {
                    System.out.println(u.toString());
                }
            }
        }
    

    测试

        @Test
        public void test4CustomQueryMethodNameOptinal() {
            Optional<List<UserInfo>> lu  = repo.findByLoginCount(3l);
            if (!lu.isPresent()) {
                System.out.println("查询结果为空!");
            } else {
                List<UserInfo> ll = lu.get();
                System.out.println("jieguo:" + ll.size());
                for ( UserInfo u : ll) {
                    System.out.println(u.toString());
                }
            }
        }
    

    从测试结果看 , 即时查询为空 , Optional<List<UserInfo>> lu = repo.findByLoginCount(3l); , 也会返回一个空list对象 , 因此使用Optional意义不大。

    自定义repository 方法 (自定义查询代码 )

    1. 创建接口

    特别注意: 接口和实现类的命名要完全一致,并且实现类以Impl为后缀,否则会异常, 框架会尝试按方法名解析推测查询条件。

    public interface UserInfoCustomRepo {
    
        List<UserInfo> customSelectAll(String name);
        void update(UserInfo user);
    }
    
    1. 实现接口
    public class UserInfoCustomRepoImpl implements UserInfoCustomRepo{
    
        @Autowired
        private MongoTemplate template;
        
        @Override
        public List<UserInfo> customSelectAll(String name) {
            System.out.println("In Custom UserInfo repo :customSelectAll ");
            return template.find(new Query(where("userName").is(name)), UserInfo.class);
        }
    
        @Override
        public void update(UserInfo user) {
            System.out.println("In Custom UserInfo repo :update ");
            template.save(user);
        }
    
    }
    

    注入MongoTemplate ;
    通过模板实现代码;

    1. 使用该自定义接口
    public interface UserInfoRepository extends MongoRepository<UserInfo, Long> , UserInfoCustomRepo {
    }
    
    1. 测试
        @Test
        public void test4CustomSelecAll() {
            List<UserInfo> lu = repo.customSelectAll("username");
            System.out.println(lu.size());
            for (UserInfo u : lu) {
                System.out.println(u.toString());
            }
        }
        
        @Test
        public void test4update() {
            UserInfo user = new UserInfo();
            user.setId("5b4db8092e069460b8cd4604");
            user.setEmail("new@123413.comc");
            user.setNickName("new nick");
            user.setLoginCount(new AtomicLong(33l));
            user.setLastLoginTime(new Date());
            
            repo.update(user);
            
        }
    

    spring data mongo 配置日志打印nosql

    在application.yml配置文件中添加:

    logging:
      level:
        org:
          springframework:
            data:
              mongodb:
                core: DEBUG
    

    索引

    domain类的字段上添加 :
    @Indexed(unique = true) 唯一索引。

    @Indexed 索引。

    类上添加:
    @CompoundIndexes({
    @CompoundIndex(name = "age_idx", def = "{'lastName': 1, 'age': -1}")
    })
    组合索引。

    相关文章

      网友评论

        本文标题:spring boot + spring data mongo

        本文链接:https://www.haomeiwen.com/subject/objgpftx.html