文章目录
SpringBoot与持久层
本节内容
- 使用JDBC存储数据
- 使用JPA存储数据
- 使用MongoDB存储数据
SQL数据库
在Spring Boot中使用JDBC
预设条件:
-
项目案例仍然使用第一节的Spring Boot note。
-
数据库使用内存数据库h2
-
建立一个非web项目
-
使用Spring boot cli初始化项目结构
spring init -d=jdbc,h2 -g=com.train.springboot -a=springboot-jdbc-app --package-name=com.train.springboot -name=springboot-jdbc-app -x
初始项目文件夹:
pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.train.springboot</groupId>
<artifactId>springboot-jdbc-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-jdbc-app</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 在Eclipse STS中已maven项目形式导入初始化项目
导入后:
3. 在domain建立Note类
package com.train.springboot.domain;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Note {
private Long id;
private String title;
private Date created;
private String summary;
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
public Note(Long id, String title, String summary, Date created) {
this.id = id;
this.title = title;
this.created = created;
this.summary = summary;
}
public Note() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public SimpleDateFormat getFormat() {
return format;
}
public void setFormat(SimpleDateFormat format) {
this.format = format;
}
public String getCreateAsShort() {
return format.format(created);
}
@Override
public String toString() {
return "Note [id=" + id + ", title=" + title + ", created=" + created + ", summary=" + summary + ", format="
+ format + "]";
}
}
- 建立服务层(NoteService),用于插入及查询数据
package com.train.springboot.service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import com.train.springboot.domain.Note;
@Service
public class NoteService {
private static final Logger log = LoggerFactory.getLogger(NoteService.class);
@Autowired
JdbcTemplate jdbcTemplate;
public void initData() {
log.info("> create Table");
jdbcTemplate.execute("drop table note if exists");
jdbcTemplate.execute("create table note(id serial,title varchar(255),summary varchar(255),created timestamp)");
log.info(">inserting init data...");
jdbcTemplate.execute("insert into note(title,summary,created) values('深圳没有冬天','深圳冬天的第一场雪','2018-11-27 00:00:00.00')");
jdbcTemplate.execute("insert into note(title,summary,created) values('东莞没有冬天','东莞下过雪','2018-11-28 00:00:00.00')");
jdbcTemplate.execute("insert into note(title,summary,created) values('Spring Boot是什么东西','Spring Boot不是东西','2018-11-29 00:00:00.00')");
jdbcTemplate.execute("insert into note(title,summary,created) values('你习惯使用JDBC吗','JDBC是啥?','2018-11-30 00:00:00.00')");
jdbcTemplate.execute("insert into note(title,summary,created) values('数据要保存到云盘上','云盘有哪些:百度,360','2018-11-29 00:00:00.00')");
jdbcTemplate.execute("insert into note(title,summary,created) values('开源框架有哪些?','Spring,mybatis,hibernate,Struts','2018-11-30 00:00:00.00')");
log.info(">done!");
}
public List<Note> findAll(){
List<Note> notes = new ArrayList<>();
jdbcTemplate.query("select * from note",
new Object[]{},
(rs,row) -> new Note(rs.getLong("id"), rs.getString("title"), rs.getString("summary"),new Date(rs.getTimestamp("created").getTime())))
.forEach(entry -> notes.add(entry));
return notes;
}
}
代码说明
- JdbcTemplate是框架中的一个类,用于执行一些数据库任务,比如插入,删除等,该类基于模版设计模式
- insertData方法,调用jdbcTemplate实例的execute方法,该方法接受SQL语句
- 使用h2建表时,id为serial类型,相当于自增长
-
编写main类:SimpleJdbcAppApplication.java
package com.train.springboot; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import com.train.springboot.service.NoteService; @SpringBootApplication public class SpringbootJdbcAppApplication implements CommandLineRunner{ private static final Logger log = LoggerFactory.getLogger(SpringbootJdbcAppApplication.class); @Autowired NoteService noteService; public static void main(String[] args) { SpringApplication.run(SpringbootJdbcAppApplication.class, args); } @Override public void run(String... args) throws Exception { log.info("@@ now init data ...."); noteService.initData(); log.info("@@ find all notes>"); noteService.findAll().forEach(entry->log.info(entry.toString())); } }
代码说明
- 自动注入NoteService,以便执行数据库操作
- 实现CommandLineRunner接口,并且实现其run方法。该run方法会在SpringBoot启动后执行
- 在该run方法中调用NoteService方法执行数据库操作
- 运行应用程序
$mvnw spring-boot:run
或者:
mvn spring-boot:run
注意
在使用mvnw(Maven wrapper)命令时,如果报错Error: Could not find or load main class org.apache.maven.wrapper.MavenWrapperMain
,可能是由于.mvn文件夹缺失,注意检查该文件夹是否存在。
或者在Eclipse STS中,在项目上单击右键运行:
运行结果:
H2内存数据库
上例中使用了H2内存数据库
由于使用@SpringBootApplication注解启用了自动配置特性,该特性探查到H2依赖,就会使用org.h2.Driver驱动类
如何查看H2控制台
H2仅提供了web控制台
1)需要在pom.xml中引入依赖spring-boot-starter-web
<!-- 启动h2 web控制台,需要导入web依赖 begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 启动h2 web控制台,需要导入web依赖 end -->
2)同时需要修改src/main/resources/application.properties文件加入如下内容
spring.h2.console.enabled=true
3)通过浏览器访问http://localhost:8080/h2-console
数据库连接信息:
**数据库JDBC url:dbc:h2:mem:testdb **
登陆信息:username为 sa,password为空
注意修改jdbc url,默认为jdbc:h2:~/test,Spring boot使用的是私有内存数据库testdb,因此jdbc url是jdbc:h2:mem:testdb
4)点击连接按钮后:
5)可以在该页面执行sql语句
在Spring Boot中使用JPA
JPA概述
JPA:Java Persistence API,J2EE规范,轻量级持久层规范,Hibernate和Eclipse TopLink是JPA的主要实现
Spring boot note JPA实现案例
-
使用Spring boot cli初始化项目
spring init -d=data-jpa,h2 -g=com.train.springboot -a=springboot-jpa-app --package-name=com.train.springboot -name=springboot-jpa-app -x
需要依赖spring-boot-starterdata-jpa,其pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.train.springboot</groupId>
<artifactId>springboot-jpa-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-jpa-app</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 编写Note.java类
package com.train.springboot.domain;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Transient;
@Entity
public class Note {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String title;
private String summary;
private Date created;
@Transient
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
public Note(String title, String summary,String date) throws ParseException {
this.title = title;
this.summary = summary;
this.created = format.parse(date);
}
public Note(){
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getCreatedAsShort() {
return format.format(created);
}
@Override
public String toString() {
return "Note [id=" + id + ", title=" + title + ", summary=" + summary + ", created=" + created + "]";
}
}
代码说明
- @Entity注解,用于标识一个实体,并将其映射到与类同名的表,该类下所有具有getter和setter方法的私有属性都映射到表中字段
- @Transient:用于排除属性,不做持久存储。
- @Id和@GeneratedValue用于定义表的主键
- 编写持久化接口NoteRepository
package com.train.springboot.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.train.springboot.domain.Note;
public interface NoteRepository extends JpaRepository<Note, Long>{
}
代码说明
- NoteRepository接口继承自JpaRepository接口
- JpaRepository接口,需要使用一个序列化(java.io.Serializable)对象,这里是Note,该对象使用@Entity注解,并且ID为Long类型
JpaRepository接口源代码如下
<spring-data-jpa>/org/springframework/data/jpa/repository/JpaRepository.java
public interface JpaRepository<T, ID extends Serializable> extends
PagingAndSortingRepository<T, ID> {
List<T> findAll();
List<T> findAll(Sort sort);
List<T> findAll(Iterable<ID> ids);
<S extends T> List<S> save(Iterable<S> entities);
void flush();
<S extends T> S saveAndFlush(S entity);
void deleteInBatch(Iterable<T> entities);
void deleteAllInBatch();
T getOne(ID id);
}
代码说明
- JpaRepository接口位于spring-data-jpa jar包中
- 你只需要继承该接口,不需实现任何方法
- 该接口有继承自PagingAndSortingRepository,提供了分页和排序功能
- 编写服务层NoteService.java
package com.train.springboot.service;
import java.text.ParseException;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.train.springboot.domain.Note;
import com.train.springboot.repository.NoteRepository;
@Service
public class NoteService {
private static final Logger log = LoggerFactory.getLogger(NoteService.class);
@Autowired
NoteRepository noteRepo;
public void initData() throws ParseException {
log.info(">init data ....");
noteRepo.save(new Note("Spring Boot JPA test","Spring Boot JAP function Test","2018-11-28"));
noteRepo.save(new Note("2018年还剩下一个月了","光阴似箭日月如梭","2018-11-18"));
noteRepo.save(new Note("没有比脚再远的路","没有比脚再远的路,没有比人更高的峰","2018-11-27"));
noteRepo.save(new Note("请问今天星期几","好像是周三","2018-11-28"));
log.info("> Data ok");
}
public List<Note> findAll(){
return noteRepo.findAll();
}
}
代码说明
- @Service会被容器识别为服务组件,以便自动注入到其他组件中
- NoteRepository实例负责对数据库持久化操作
- 编写main应用程序SpringbootJpaAppApplication.java
package com.train.springboot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.train.springboot.service.NoteService;
@SpringBootApplication
public class SpringbootJpaAppApplication {
private static final Logger log = LoggerFactory.getLogger(SpringbootJpaAppApplication.class);
public static void main(String[] args) {
SpringApplication.run(SpringbootJpaAppApplication.class, args);
}
@Bean
CommandLineRunner start(NoteService noteService) {
return args ->{
log.info("@@ init Data begin....");
noteService.initData();
log.info("@@ find all Notes");
noteService.findAll().forEach(entry ->{log.info(entry.toString());});
};
}
}
代码说明
- @SpringBootApplication会自动配置spring-boot-starter-data-jpa和H2依赖,并使用testdb数据库默认授权进行连接
- start方法要想在Spring boot启动后运行,必须返回CommandLineRunner接口,并且标记@Bean注解
- @Bean注解是方法级注解,将方法返回值定义为一个bean,并且使用方法名作为bean的id
-
功能扩展
前例并没有编写任何数据库代码便完成了插入,更新,删除等通用任务。
实际开发中需要定制的查询,比如按日期查找,使用连接定制查询,执行存储过程等,此时需要扩展JpaRepository接口。
扩展JpaRepository接口,建立查询方法时,注意正确的命名规范。
比如:
1)查询标题中含有Spring的记录
Note类中包含title属性,如果查询title中包含Spring的记录,需要像如下编写方法:
public List<Note> findByTitleContaining(String word);
此时会翻译成的SQL查询是:
select * from note where title like %?1%
?1参数会是Spring,将执行类似如下的SQL
select * from note where title like %Spring%
2)查询特定日期之后的记录
public List<Note> findByCreatedAfter(Date date);
该方法翻译后sql为:
select * from Note where created > ?1
3)定制sql
@Query("select n from Note n where n.summary like %?1%")
List<Note> findByCustomQuery(String word);
NoteRepository.java 修改后的版本:
package com.train.springboot.repository;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.train.springboot.domain.Note;
public interface NoteRepository extends JpaRepository<Note, Long>{
//功能扩展部分
//JPQL为select * from note where title like %?1%
//实际执行:select * from note where title like %Spring%
public List<Note> findByTitleContaining(String word);
//JPQL:select * from Note where created > ?1
public List<Note> findByCreatedAfter(Date date);
//定制查询,需使用JPQL语法
@Query("select n from Note n where n.summary like %?1%")
public List<Note> findByCustomQuery(String word);
}
代码说明
- 第一个方法遵循命名规范,按属性查找
- 第二个方法,可以任意起名定制,这时需要使用@Query注解,并且接受的SQL需按JPQL语句
更多jpa查询扩展,请参考:http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
同时需修改NoteService,添加调用NoteRepository接口的内容:
...
//功能扩展,按标题like查询,指定日期查询,定制查询...
//like 查询
public List<Note> findByTitleContaining(String keyWord){
return noteRepo.findByTitleContaining(keyWord);
}
//查询指定日期之后的记录
public List<Note> findByCreatedAfter(Date date){
return noteRepo.findByCreatedAfter(date);
}
//笔记内容like的定制查询
public List<Note> findByCustomQuery(String keyWord){
return noteRepo.findByCustomQuery(keyWord);
}
修改主程序并进行测试:
@Bean
CommandLineRunner start(NoteService noteService) {
return args ->{
...
//查询功能扩展部分测试
log.info("@@查找标题含有2018的记录");
noteService.findByTitleContaining("2018").forEach(entry ->{log.info(entry.toString());});
//查询指定日期之后的记录
log.info("@@查询指定日期之后的记录");
noteService.findByCreatedAfter(new Date()).forEach(entry ->{log.info(entry.toString());});
//查询内容中含有Spring的记录
log.info("@@查询内容中含有Spring的记录");
noteService.findByCustomQuery("Spring").forEach(entry ->{log.info(entry.toString());});
};
运行效果:
- 建库脚本及数据库初始化
Spring-data允许你在类路径根目录下使用schema.sql和data.sql,建立数据库以及插入数据。
src/main/resources/data.sql
INSERT INTO note(id,title,summary,created) VALUES(1,'Spring boot学习指导','Spring Boot是下一代Spring应用程序','2018-11-02 00:00:00.00');
INSERT INTO note(id,title,summary,created) VALUES(2,'重庆永川标准班','为期5个月,坐标重庆永川','2018-05-21 00:00:00.00');
INSERT INTO note(id,title,summary,created) VALUES(3,'树莓派实现温度监控系统','使用DHT22温度传感器实现室内外温度监控','2018-11-25 00:00:00.00');
INSERT INTO note(id,title,summary,created) VALUES(4,'深圳有哪些区','南山,宝安,龙华,光明,罗湖,福田,盐田,坪山','2018-11-05 00:00:00.00');
这时可以移除SpringbootJpaAppApplication.java中的调用插入数据的方法
//在resource根目录存在data.sql文件,因此不必在此处调用插入初始数据的方法
//noteService.initData();
*如果想查看JPA/Hibernate引擎执行的sql,可以在src/main/resources/application.properties文件中设置:spring.jpa.show-sql=true
注意:
- data.sql在插入数据时要插入主键ID
- 不用建表,系统每次重启后自动建表
JPA方法名中支持的关键字
注意
Like和Containing区别
-
Like不会将参数包围在通配符中,需要在传递参数时,添加通配符,否则还是相当于精确查找
-
Containing会将参数包含在%%通配符中,传递参数时不必在参数中带有通配符
具体案例如下:
JpaRepository接口
public interface NoteRepository extends JpaRepository<Note, Long>{ //功能扩展部分 //JPQL为select * from note where title like %?1% //实际执行:select * from note where title like '%Spring%' public List<Note> findByTitleContaining(String word); //不会自动带通配符,需自己在传参时包含 //实际执行:select * from note where title like 'Spring' public List<Note> findByTitleLike(String word); ... }
方法调用:
log.info("@@查找标题含有boot的记录"); //Containing结尾的方法将参数包围在%%中,相当于原始的like查询,参数中不必带通配符 repo.findByTitleContaining("boot").forEach(entry ->{log.info(entry.toString());}); //Like结尾的方法,需要在传递参数时,传递通配符,否则相当于精确查找 repo.findByTitleLike("%boot%").forEach(entry ->{log.info(entry.toString());});
NoSQL数据库
NoSQL数据库提供了另外一种数据存储方案,不同于传统的关系型数据库
NoSQL通常基于如下数据模型:
- 列 (Cassandra, HBase, etc.)
- 文档 (CouchDB, MongoDB, etc.)
- 键-值(Redis, Riak, etc.)
- 图 (Neo4J, Virtuoso, etc.)
- 混合模式(OrientDB, ArangoDB, etc.)
MongoDB实现方案
MongoDB安装过程
- 下载和安装MongoDB
网站:https://www.mongodb.org/downloads#production
-
mongoDB安装过程
1)启动安装程序
2)同意协议并继续
3)选择完整安装
4)保持默认值不变
5)基于网络原因不要选择install MongoDB Compass(此步比较重要,否则导致无法安装,卡在网络下载上)
6)选择继续安装
7)完成安装
8)在服务中检查mongoDB服务是否已启动
9)配置path路径
在windows环境下,配置path路径,加入mongo.exe命令所在目录,以便在任何位置均能运行命令行程序
C:\Program Files\MongoDB\Server\4.0\bin
在任何位置打开dos窗口,输入mongo命令进行测试
在spring boot中使用mongoDB
- 初始化项目:
spring init -d=data-mongodb -g=com.train.springboot -a=springboot-mongodb-app --package-name=com.train.springboot -name=springboot-mongodb-app -x
pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.train.springboot</groupId>
<artifactId>springboot-mongodb-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-mongodb-app</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
代码说明
pom中依赖了spring-boot-starter-data-mongodb
- Note类
package com.train.springboot.domain;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
public class Note {
@Id
private String id;
private String title;
private Date created;
private String summary;
@Transient
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
public Note(String title, String summary, String date) throws ParseException {
this.title = title;
this.created = format.parse(date);
this.summary = summary;
}
public Note() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getCreatedAsShort() {
return format.format(created);
}
@Override
public String toString() {
return "Note [id=" + id + ", title=" + title + ", created=" + created + ", summary=" + summary + "]";
}
}
代码说明
-
这里使用了org.springframework.data.annotation.Id和org.
springframework.data.annotation.Transient注解注意他们不是来自以前的javax.persistence包(原来使用的是JPA规范) -
另外一个区别是ID不再是Long类型,而是String类型,这是MongoDB的需求
-
持久层接口
package com.train.springboot.repository; import java.util.List; import org.springframework.data.mongodb.repository.MongoRepository; import com.train.springboot.domain.Note; public interface NoteRepository extends MongoRepository<Note, String>{ public List<Note> findByTitleLike(String word); }
代码说明
- 需要继承自MongoRepository接口,该接口针对MongoDB完成通用操作
- 查询方法:findByTitleLike,会被翻译成MongoDB语法,类似
db.note.find({"title": /.*?1*/})
- 主应用程序
package com.train.springboot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.train.springboot.domain.Note;
import com.train.springboot.repository.NoteRepository;
@SpringBootApplication
public class SpringbootMongodbAppApplication {
private static final Logger log = LoggerFactory.getLogger(SpringbootMongodbAppApplication.class);
public static void main(String[] args) {
SpringApplication.run(SpringbootMongodbAppApplication.class, args);
}
@Bean
CommandLineRunner start(NoteRepository noteRepo) {
return args ->{
log.info("@@ delete all note data");
noteRepo.deleteAll();
log.info("@@ insert new data...");
noteRepo.save(new Note("mongo db test with Spring boot","mongoDB Test !!!!!","2018-11-11"));
noteRepo.save(new Note("今天星期四","今天星期四,所以明天星期五","2018-11-29"));
noteRepo.save(new Note("腾讯课堂","腾讯课堂入驻登记","2018-11-19"));
noteRepo.save(new Note("2018年Spring发展情况","Spring Boot学习摘要","2018-11-20"));
log.info("@@ data insert ok");
log.info("@@find all notes data now....");
noteRepo.findAll().forEach(entry ->{log.info(entry.toString());});
log.info("@@test like query by Spring");
noteRepo.findByTitleLike("Spring").forEach(entry ->{log.info(entry.toString());});
};
}
}
-
运行程序
$ mvnw spring-boot:run
输出结果:
-
在mongoDB中查看数据
在系统中配置path路径指向mongo.exe文件所在目录后,可以在任何文件夹下打开dos窗口,运行mongo命令,此时会连接默认数据库:test。
输入如下命令查看数据:
> show collections
note
> db.note.find()
{ "_id" : ObjectId("5bffb07eee47b611dc3a367c"), "title" : "mongo db test with Spring boot", "created" : ISODate("2018-11-10T16:00:00Z"), "summary" : "mongoDB Test !!!!!", "_class" : "com.train.springboot.domain.Note" }
{ "_id" : ObjectId("5bffb07eee47b611dc3a367d"), "title" : "今天星期四", "created" : ISODate("2018-11-28T16:00:00Z"), "summary" : "今天星期四,所以明天星期五", "_class" : "com.train.springboot.domain.Note" }
{ "_id" : ObjectId("5bffb07eee47b611dc3a367e"), "title" : "腾讯课堂", "created": ISODate("2018-11-18T16:00:00Z"), "summary" : "腾讯课堂入驻登记", "_class" : "com.train.springboot.domain.Note" }
{ "_id" : ObjectId("5bffb07eee47b611dc3a367f"), "title" : "2018年Spring发展情况", "created" : ISODate("2018-11-19T16:00:00Z"), "summary" : "Spring Boot学习摘要", "_class" : "com.train.springboot.domain.Note" }
>
代码说明
-
使用mongo客户端,会默认连接到test数据库
-
Java类是note,需要使用db.note.find()获取所有数据
-
如果不想使用默认数据库,需要修改rc/main/resources/application.properties文件,加入如下内容:
spring.data.mongodb.database=mynotes
修改完成后,重新运行程序,并连接mongoDB查看变化:
更多关于application.properties的内容,请参考:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html