Springboot学习笔记(七)——MongoDB

Redis是一个能极大的提高互联网系统的性能,但是他有一些缺陷,其中一个就是计算功能十分有限,虽然可以通过Lua脚本去完善,但是这样对于开发者的工作量就大大增加了。对于需要缓存而且经常需要统计、分析和查询的数据,对于Redis这样简单的NoSQL就不是那么便捷了。而MongoDB对于那些需要统计、按条件查询和分析的数据,他提供了支持,它可以说是一个最接近关系数据库的NoSQL。
MongoDB是有C++语言编写的一种NoSQL,是一个基于分布式文件存储的开源数据库系统。在负载高时可以添加更多的节点,以保证服务器性能,MongoDB的目的是为web应用提供可扩展的高性能数据存储解决方案。MongoDB将数据存储为一个文档,数据结构由键值对组成,这里的MongoDB文档类似于JSON数据集,所以很容易转化为Java POJO对象或者JS对象,这些字段值还可以包含其他文档、数组以及文档数组
与Redis一样,Spring Boot的配置文件也提供了许多关于MongoDB的配置,首先引入SpringBoot关于MongoDB的starter以及fastjson的开发包

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-mongodb</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.39</version>
		</dependency>

配置MongoDB

springboot关于MongoDB的默认配置:

spring.data.mongodb.authentication-database=		#用于签名的MongoDB数据库
spring.data.mongodb.database=						#数据库名称
spring.data.mongodb.field-naming-strategy=			#使用字段名策略
spring.data.mongodb.grid-fs-database=				#GridFs(网格文件)数据库名称
spring.data.mongodb.host=							#MongoDB服务器,不能设置为uri
spring.data.mongodb.password=						#MongoDB服务器密码,不能设置为URI
spring.data.mongodb.port=							#MongoDB服务器端口,不能设置为URI
spring.data.mongodb.repositories.type=				#是否启用MongoDB关于JPA规范的编程
spring.data.mongodb.uri=							#MongoDB默认URI
spring.data.mongodb.username=						#MongoDB服务器用户名,不能设置为URI

本人在测试时使用的配置:

spring.data.mongodb.host=192.168.1.103
spring.data.mongodb.port=27017
spring.data.mongodb.username=springboot
spring.data.mongodb.password=springboot
spring.data.mongodb.database=springboot

为了能够进行开发,还需要了解一些关于MongoDB的Bean(springboot会自动创建):

  • MongoProperties:springboot关于MongoDB的自动配置属性
  • MongoTemplate:MongoDB的操作模板,在spring中主要通过它对MongoDB进行操作

使用MongoTemplate实例

spring data MongoDB主要是通过mongoTemplate进行操作数据的。springboot会根据配置自动生成这个对象,我们只需拿来就行。
下面通过MongoTemplate来操作数据。

  1. 搭建开发环境
    创建一个用户pojo:
package com.springboot.chapter08.pojo;
/**
 * 用户
 * @author Administrator
 */
@Document//标识MongoDB文档
public class User implements Serializable {
	private static final long serialVersionUID = 1L;
	@Id		//MongoDB文档编号,主键
	private Integer id;
	@Field("user_name")		//在MongoDB中使用user_name保存属性
	private String userName;
	private String note;
	private List<Role> roles;		//角色列表
	//get和set方法
	@Override
	public String toString() {
		return "User [id=" + id + ", userName=" + userName + ", note=" + note + ", roles=" + roles + "]";
	}
}

@Document标识为MongoDB文档存在,@id将对应的字段设置为主键,@Filed将属性与数据库字段对应起来。

package com.springboot.chapter08.pojo;
/**
 * 角色
 * @author Administrator
 */
@Document
public class Role implements Serializable {
	private static final long serialVersionUID = 1L;
	private Integer id;
	@Field("role_name")
	private String roleName;
	private String note;
	//get和set方法
	@Override
	public String toString() {
		return "Role [id=" + id + ", roleName=" + roleName + ", note=" + note + "]";
	}
}

用户控制器

package com.springboot.chapter08.controller;

@Controller
@RequestMapping("/user")
public class UserController {
	@Autowired
	private UserService userService;
	/**
	 * 获取用户
	 * @param id
	 * @return
	 */
	@RequestMapping("/get")
	@ResponseBody
	public User getUser(Integer id) {
		User user = userService.getUser(id);
		return user;
	}
	
	/**
	 * 保存(新增或跟新)用户
	 * @param user
	 * @return
	 */
	@RequestMapping("/save")
	@ResponseBody
	public User saveUser(@RequestBody User user) {
		userService.saveUser(user);
		return user;
	}
	
	/**
	 * 查询用户
	 * @param userName  用户名称
	 * @param note  备注
	 * @param skip  跳过用户个数
	 * @param limit  限制返回用户个数
	 * @return
	 */
	@RequestMapping("/find")
	@ResponseBody
	public List<User> findUser(String userName,String note,Integer skip,Integer limit){
		List<User> userlist = userService.findUser(userName, note, skip, limit);
		return userlist;
	}
	
	/**
	 * 更新用户部分属性
	 * @param id  用户编号
	 * @param userName  用户名称
	 * @param note  备注
	 * @return
	 */
	@RequestMapping("/update")
	@ResponseBody
	public UpdateResult updateUser(Integer id,String userName,String note) {
		return userService.updateUser(id, userName, note);
	}
	
	/**
	 * 删除用户
	 * @param id  用户主键
	 * @return
	 */
	@RequestMapping("/delete")
	@ResponseBody
	public DeleteResult deleteUser(Integer id) {
		return userService.deleteUser(id);
	}
	
	/**
	 * 测试插入一条数据
	 * @return
	 */
	@RequestMapping("/insert")
	@ResponseBody
	public User insert() {
		return userService.insert();
	}
	/**
	 * 测试jpa接口,根据用户名模糊查询
	 * @param userName
	 * @return
	 */
	@RequestMapping("byname")
	@ResponseBody
	public List<User> findByUserNameLike(String userName){
		return userService.findByUserNameLike(userName);
	}
	/*
	 * 测试自定义方法,根据ID或用户名查询
	 */
	@RequestMapping("/findOr")
	@ResponseBody
	public User findByUserByIdOrUserName(Integer id,String userName) {
		return userService.findByUserByIdOrUserName(id, userName);
	}
}

  1. 使用MongoTemplate操作文档
    这里使用最为常用的方法,包括增删改查和分页等较为常用的功能。
    用户服务接口:
package com.springboot.chapter08.service;
public interface UserService {
	public void saveUser(User user);
	public DeleteResult deleteUser(Integer id);
	public List<User> findUser(String userName,String note,int skip,int limit);
	public UpdateResult updateUser(Integer id,String userName,String note);
	public User getUser(Integer id);
	
	public User insert();
	
	public List<User> findByUserNameLike(String userName);
	
	public User findByUserByIdOrUserName(Integer id,String userName);
}

用户服务接口的实现

package com.springboot.chapter08.service.impl;

@Service
public class UserServiceImpl implements UserService{
	//注入mongotemplate对象
	@Autowired
	private MongoTemplate mongoTemplate;
	@Autowired
	private UserDao userDao;
	
	@Override
	public void saveUser(User user) {
		// TODO Auto-generated method stub
		//使用名称为user文档保存用户信息
		mongoTemplate.save(user, "user");
		//如果文档采用类名首字母小写,则可以这样保存
		//mongoTemplate.save(user);
	}

	@Override
	public DeleteResult deleteUser(Integer id) {
		// TODO Auto-generated method stub
		//构件ID相等的条件
		Criteria criteriaId = Criteria.where("id").is(id);
		//查询对象
		Query query = Query.query(criteriaId);
		//删除用户
		DeleteResult result = mongoTemplate.remove(query, User.class);
		return result;
	}

	@Override
	public List<User> findUser(String userName, String note, int skip, int limit) {
		// TODO Auto-generated method stub
		//将用户名称和备注设置为模糊查询准则
		Criteria criteria = Criteria.where("user_name").regex(userName).and("note").regex(note);
		//构建查询条件,并设置分页跳过前skip个,至多返回limit个
		Query query = Query.query(criteria).limit(limit).skip(skip);
		//执行
		List<User> userList = mongoTemplate.find(query, User.class);
		return userList;
	}

	@Override
	public UpdateResult updateUser(Integer id, String userName, String note) {
		// TODO Auto-generated method stub
		//确定要跟新的对象
		Criteria criterId = Criteria.where("id").is(id);
		Query query = Query.query(criterId);
		//定义跟新对象,后续可变化的字符串代表排除在外的属性
		Update update = Update.update("user_name", userName);
		update.set("note", note);
		//更新单个对象
		UpdateResult result = mongoTemplate.updateFirst(query, update, User.class);
		//更新多个对象
		//UpdateResult result2 = mongoTemplate.updateMulti(query, update, User.class);
		return result;
	}

	@Override
	public User getUser(Integer id) {
		// TODO Auto-generated method stub
		User user = mongoTemplate.findById(id, User.class);
		return user;
		//如果只需要获取第一个也可以采用如下查询方法
//		Criteria criterId = Criteria.where("id").is(id);
//		Query query = Query.query(criterId);
//		return mongoTemplate.findOne(query, User.class);
	}

	@Override
	public User insert() {
		// TODO Auto-generated method stub
		Role roles1 = new Role();
		roles1.setId(2);
		roles1.setRoleName("11");
		roles1.setNote("111");
		Role roles2 = new Role();
		roles2.setId(3);
		roles2.setRoleName("22");
		roles2.setNote("222");
		List<Role> roles = new ArrayList<Role>();
		roles.add(roles1);
		roles.add(roles2);
		User user = new User();
		user.setId(12);
		user.setUserName("12");
		user.setNote("12");
		user.setRoles(roles);
		
		User user2 = mongoTemplate.insert(user);
		return user2;
	}

	@Override
	public List<User> findByUserNameLike(String userName) {
		// TODO Auto-generated method stub
		return userDao.findByUserNameLike(userName);
	}

	@Override
	public User findByUserByIdOrUserName(Integer id, String userName) {
		// TODO Auto-generated method stub
		return userDao.findByUserByIdOrUserName(id, userName);
	}
}

在上述代码的getUser方法中有一句

Criteria criterId = Criteria.where("id").is(id);

表示构件一个用户主键为变量ID的查询准则,然后通过

Query query = Query.query(criterId);

构件查询条件,然后就通过findOne查询出唯一的用户信息。
再看findUser方法,这里构建了一个查询准则:

Criteria criteria = Criteria.where("user_name").regex(userName).and("note").regex(note);

这里的where方法的参数设置为“userName”,这个字符串代表的是类User的属性userName;regex方法代表正则式匹配,即执行模糊查询;and方法代表连接字,代表同时满足。然后通过

Query query = Query.query(criteria).limit(limit).skip(skip);

构建查询条件,这里的limit代表限制至多返回limit条记录,而skip则代表跳过多少条记录。最后使用find方法,将结果查询为一个列表,返回给调用者。

测试插入一条数据

@Override
	public User insert() {
		// TODO Auto-generated method stub
		Role roles1 = new Role();
		roles1.setId(2);
		roles1.setRoleName("11");
		roles1.setNote("111");
		Role roles2 = new Role();
		roles2.setId(3);
		roles2.setRoleName("22");
		roles2.setNote("222");
		List<Role> roles = new ArrayList<Role>();
		roles.add(roles1);
		roles.add(roles2);
		User user = new User();
		user.setId(12);
		user.setUserName("12");
		user.setNote("12");
		user.setRoles(roles);
		
		User user2 = mongoTemplate.insert(user);
		return user2;
	}
@RequestMapping("/insert")
	@ResponseBody
	public User insert() {
		return userService.insert();
	}

插入成功将会以json数据格式返回到页面
在这里插入图片描述
查看MongoDB中的数据:
在这里插入图片描述
插入成功。

测试修改数据

@Override
	public UpdateResult updateUser(Integer id, String userName, String note) {
		// TODO Auto-generated method stub
		//确定要跟新的对象
		Criteria criterId = Criteria.where("id").is(id);
		Query query = Query.query(criterId);
		//定义跟新对象,后续可变化的字符串代表排除在外的属性
		Update update = Update.update("user_name", userName);
		update.set("note", note);
		//更新单个对象
		UpdateResult result = mongoTemplate.updateFirst(query, update, User.class);
		//更新多个对象
		//UpdateResult result2 = mongoTemplate.updateMulti(query, update, User.class);
		return result;
	}
@RequestMapping("/update")
	@ResponseBody
	public UpdateResult updateUser(Integer id,String userName,String note) {
		return userService.updateUser(id, userName, note);
	}

测试结果
在这里插入图片描述验证
在这里插入图片描述
修改成功

使用JPA

MongoDB是个十分接近于关系数据库的NoSQL数据库,它还可以使用JPA编程,只是于关系数据库不同的是提供给我们的接口不是JpaRepository<T,ID>,而是MongoRepository<T,ID>

  1. 基本用法
    使用Jpa只需要定义其接口,按照其名称就能够进行扩展,而无需实现接口的方法
    首先创建一个接口
package com.springboot.chapter08.dao;

import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.springboot.chapter08.pojo.User;
//表标识为dao层
@Repository
//扩展MongoRepository接口,T为实体类型,ID为主键的类型
public interface UserDao extends MongoRepository<User, Integer> {
	/**
	 * 符合jpa规范命名方法,则不需要再实现该方法也可用
	 * 在满足条件的文档按照用户名称进行模糊查询
	 * @param userName
	 * @return
	 */
	List<User> findByUserNameLike(String userName);
	
	/**
	 * 根据编号或者用户名查找用户
	 * @param id
	 * @param userName
	 * @return
	 */
	User findByUserByIdOrUserName(Integer id,String userName);
}

接下来的问题是如何将一个接口转化为一个spring bean。为此spring data bean提供了一个注解**@EnableMongoRepositories**,通过它便可以指定扫描对应的接口。

package com.springboot.chapter08.main;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@SpringBootApplication(scanBasePackages = "com.springboot.chapter08",exclude = DataSourceAutoConfiguration.class)
//指定扫描的包,用于继承了MongoRepository接口
@EnableMongoRepositories(basePackages = "com.springboot.chapter08.dao")
public class Chapter08Application {

	public static void main(String[] args) {
		SpringApplication.run(Chapter08Application.class, args);
	}
}

在UserService添加代码:

@Override
	public List<User> findByUserNameLike(String userName) {
		// TODO Auto-generated method stub
		return userDao.findByUserNameLike(userName);
	}

在UserController添加如下代码:

/**
	 * 测试jpa接口
	 * @param userName
	 * @return
	 */
	@RequestMapping("byname")
	@ResponseBody
	public List<User> findByUserNameLike(String userName){
		return userService.findByUserNameLike(userName);
	}

测试运行结果(查询userName中含有“1”的用户)
在这里插入图片描述

  1. 使用自定义查询
    当查询需要多个字段,或者需要进行较为复杂灵活的查询,JPA规范并不能满足这样的需求。
    自定义查询方法,在UserDao中加入如下方法:
/**
	 * 根据编号或者用户名查找用户
	 * @param id
	 * @param userName
	 * @return
	 */
	User findByUserByIdOrUserName(Integer id,String userName);

接下来实现这个方法,只是这里的UserDao接口扩展了MongoRepository,如果实现这个接口就要实现其定义的方法,会给使用者带来许多不便,而JPA自动生成方法逻辑的形式就荡然无存了。这时候spring给了我们新的约定,在spring中只要定义一个“接口名称+Impl”的类并且提供与接口定义相同的方法,spring就会自动找到这个类对应的方法作为JPA接口定义的实现,如下:

package com.springboot.chapter08.dao.impl;

@Repository
public class UserDaoImpl implements UserDao {
	@Autowired
	private MongoTemplate mongoTemplate;
	@Override
	public User findByUserByIdOrUserName(Integer id, String userName) {
		// TODO Auto-generated method stub
		//构造ID查询准则
		Criteria criteriaId = Criteria.where("id").is(id);
		//构造username查询准则
		Criteria criteriaUserName = Criteria.where("userName").is(userName);
		Criteria criteria = new Criteria();
		//使用$or操作符关联两个条件,形成或关系
		criteria.orOperator(criteriaId,criteriaUserName);
		Query query = Query.query(criteria);
		User resultUser = mongoTemplate.findOne(query, User.class);
		return resultUser;
	}
}

@EnableMongoRepositories(
		basePackages = "com.springboot.chapter08.dao"
		//使用自定义后缀,其默认为Impl
		//此时需要修改类名,UserDaoImpl-->UserDaoStuff
		//repositoryImplementationPostfix = "Stuff"
		)

测试

/*
	 * 测试自定义方法
	 */
	@RequestMapping("/findOr")
	@ResponseBody
	public User findByUserByIdOrUserName(Integer id,String userName) {
		return userService.findByUserByIdOrUserName(id, userName);
	}

测试结果
在这里插入图片描述id=5是不存在的
在这里插入图片描述userName=1100000十不存在的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot可以同时使用MySQL和MongoDB数据库。你可以使用Spring Data JPA来访问MySQL数据库,使用Spring Data MongoDB来访问MongoDB数据库。 首先,你需要在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> ``` 然后,你需要在application.properties或application.yml文件中配置MySQL和MongoDB的连接信息。例如: ``` # MySQL配置 spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver # MongoDB配置 spring.data.mongodb.host=localhost spring.data.mongodb.port=27017 spring.data.mongodb.database=test spring.data.mongodb.username=root spring.data.mongodb.password=123456 ``` 最后,你可以创建一个JPA实体类来映射MySQL数据库中的表,例如: ``` @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private String email; // 省略getter和setter } ``` 你还可以创建一个MongoDB的Repository接口来访问MongoDB数据库,例如: ``` @Repository public interface UserRepository extends MongoRepository<User, String> { } ``` 这样,你就可以在Spring Boot应用程序中同时使用MySQL和MongoDB数据库了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值