[Day 04] - 用Spring Boot连接Mongo DB

今天一开始 先来新增spring boot的连线设定

Spring Boot的设定档
application.properties
在专案目录的src/main/resources底下,

预设是空白的
到这边新增以下设定

#因为我们在之前有设定Mongo DB认证机制,所以要在连线的host前面加上[帐号:密码@]否则接下来会无法存取DB
spring.data.mongodb.uri=mongodb://iron30:123456@localhost:27017/testDB
#自动建立INDEX
spring.data.mongodb.auto-index-creation=true

接下来就可以开始建Entity了
Entity与DB中document的值的对应,
先定义我们要储存进资料库的资料有哪些,

我初步想到几个要用做记录使用者帐号密码相关资讯所会用到的资料

import com.mongodb.lang.NonNull;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import lombok.Data;
@Data //lomobok 省去get/set
@Document  //标记这个class对映一个collection,在(user)这个collection里面操作document
public class User {
    @Id
    private String id;  //这个id物件是对映每个document在被新增时都会有的_id
    @Indexed(unique = true)
    @NonNull
    private String email;
    @Indexed(unique = true)
    @NonNull
    private String userAccount;
    @NonNull
    private String userPassword;
    @NonNull
    private Integer depositAccount;
    @NonNull
    private Integer status;
}

接着右键选择Source Action…
https://ithelp.ithome.com.tw/upload/images/20210919/201289732Gsuvo44lg.png
选择Generate Constructors…
https://ithelp.ithome.com.tw/upload/images/20210919/20128973wh9WjOOS8g.png
选择想要产生建构子的物件 按ok
https://ithelp.ithome.com.tw/upload/images/20210919/20128973YNIJPAt6sC.png
就能简单产生建构子罗
https://ithelp.ithome.com.tw/upload/images/20210919/20128973Vwc3YcbRqG.png

为什麽不选择id是因为在新增document时mongo db会自动产生_id,并不需要我们再去操作,因此省略

在Spring Data Mongo中,只要符合其中一个条件:

  1. object名称叫id
  2. 有下@Id这个annocation

它就会认定这个object对映到Mongo DB里的_id
如果两者都没有,也会自行产生_id,只是就没有对映的java物件了
详细可以看官方的说明文件

看起来似乎在entity直接省略掉id这个object也不是不行
如果站在未来方便迁移DB的角度来看,不要放id这个物件应该会比较好
不过目前我还是先留着

接着来实作Repository介面

我选择使用比较简单的MongoRepository
另一个选择是使用MongoTemplate
MongoRepository跟MongoTemplate两者的区别在於
MongoTemplate可以更灵活的使用MongoDB的原生SQL写法,如upsert、updatefirst...等
MongoRepository则是提供固定的方法让我们对DB做基本的CRUD,
如果没有要做到什麽复杂的操作,用MongoRepository就好了

新增一个UserRepo.java

import java.util.Optional;
import com.rei1997.vault.model.entity.User;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserRepo extends MongoRepository<User,String>{
    Optional<User>findUserByEmail(String email);
}

补充:
型别不是直接用User而是用Optional
是为了避免掉忘记在程序处理null的情形发生

这边我定义了一个findUserByEmail的方法,藉由输入email查询db是否有这笔资料,
等等来测测看有没有用

其原理是spring data jpa会根据方法名称的关键字去判读这个方法该怎麽运作,
findUserByEmail符合了关键字find...by...因此判读是要以Email来查询

顺便列出spring data jpa 常用的方法名关键字

Keyword Sample JPQL snippet
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is, Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1

详细可参见文件

我们的Spring boot专案都会预设有个xxxApplication.java,这只程序是整个专案的进入点,

在里面增加一个CommandLineRunner方法的Bean
让spring boot 初始化时建立相关实体,并执行一次以下动作

@SpringBootApplication
public class VaultApplication {
    public static void main(String[] args) {
            SpringApplication.run(VaultApplication.class, args);
    }
    @Bean
    CommandLineRunner runner(UserRepo userDao){
        return args -> {
            String email ="[email protected]";
            //建立一个user
            User user = new User(email,"test1","test1",0123456,1);
            //查这个email在db有没有重复
            userDao.findUserByEmail(email)
                .ifPresentOrElse(users ->{
                    //有的话就印出来
                    System.out.println("already exists");
                    System.out.println(users);
        
                }, ()->{
                    //没有的话就新增
                    userDao.insert(user);   
                    System.out.println("add user");
                });
        };
    }
    
}

接着再执行spring boot,就可以确认我们的spring boot能否与资料库成功接上了
https://ithelp.ithome.com.tw/upload/images/20210919/20128973TIBg7fwCEy.png

看来有成功接上资料库,今天就到此结束 谢谢~


<<:  今日爬山中

>>:  TCP/IP,网际网路的基础通讯架构

【後转前要多久】# Day03 HTML - BODY内的东西

早期网页大多都只有HTML骨架, 多数都是白底黑字、没有美美的编排,文字特效blink一闪一闪的,...

Day19 用python写UI-聊聊OptionMenu

OptionMenu就是下拉式选单的概念,可以有不同的设定方法,可以设成有预设选项的,也可以获得选好...

DAY2 序

第一页、第六页、第七页 序。 序放在第一页後面也是完全OKです! 因为第一天讲太多废话了,完全没有讲...

[Day 8] .Net Task 底层(1)

前言 昨天聊过 Task.WhenAll , 得知其底层就是等待多个 Task 完成的机制, 那 T...

[Day-24] - Spring Reactor Mono 一日初探就上手

Abstract 昨日已先行提过Flux,可方便处理一连串指定类型事件,所以说Flux就像瑞凡,被众...