💡版本依赖
jdk 17
SpringBoot 3.1.0
Mongo 6.0.8
mybatis-plus 2.0.2
💡环境准备
🌵MongoDB安装
安装教程请查看:一文搞定(linux+windows+docker)安装MongoDB
🌵导入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-mongo-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-mongo-demo</name>
<description>springboot-mongo-demo</description>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mongo -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.32</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
🌵application.yml配置
server:
port: 8080 # 设置访问端口
spring:
data:
mongodb:
uri: mongodb://47.98.123.147:27017/mongo_db
# 上方为明确指定某个数据的用户进行连接
# 也可以使用admin 数据库中的用户进行连接 统一到admin 数据库进行认证
# admin 用户认证 url 写法: mongodb://账户:密码%40@ip:端口/数据库名?authSource=admin&authMechanism=SCRAM-SHA-1
💡使用实例
🌵mongo 封装顶级service
public abstract class MongoServiceImpl<T> implements MongoService<T> {
protected abstract Class<T> getEntityClass();
@Autowired
protected MongoTemplate mgt;
@Override
public void save(T entity) {
mgt.save(entity);
}
@Override
public void update(T entity) {
// 反向解析对象
Map<String, Object> map = null;
try {
map = parseEntity(entity);
} catch (Exception e) {
e.printStackTrace();
}
// ID字段
String idName = null;
Object idValue = null;
// 生成参数
Update update = new Update();
if (EmptyUtil.isNotEmpty(map)) {
for (String key : map.keySet()) {
if (key.indexOf("{") != -1) {
// 设置ID
idName = key.substring(key.indexOf("{") + 1, key.indexOf("}"));
idValue = map.get(key);
} else {
update.set(key, map.get(key));
}
}
}
mgt.updateFirst(new Query().addCriteria(where(idName).is(idValue)), update, getEntityClass());
}
@Override
public void delete(Serializable... ids) {
if (EmptyUtil.isNotEmpty(ids)) {
for (Serializable id : ids) {
mgt.remove(mgt.findById(id, getEntityClass()));
}
}
}
@Override
public T find(Serializable id) {
return mgt.findById(id, getEntityClass());
}
@Override
public List<T> findAll() {
return mgt.findAll(getEntityClass());
}
@Override
public List<T> findAll(String order) {
List<Order> orderList = parseOrder(order);
if (EmptyUtil.isEmpty(orderList)) {
return findAll();
}
return mgt.find(new Query().with(Sort.by((orderList))), getEntityClass());
}
@Override
public List<T> findByProp(String propName, Object propValue) {
return findByProp(propName, propValue, null);
}
@Override
public List<T> findByProp(String propName, Object propValue, String order) {
Query query = new Query();
// 参数
query.addCriteria(where(propName).is(propValue));
// 排序
List<Order> orderList = parseOrder(order);
if (EmptyUtil.isNotEmpty(orderList)) {
query.with(Sort.by(orderList));
}
return mgt.find(query, getEntityClass());
}
@Override
public List<T> findByProps(String[] propName, Object[] propValue) {
return findByProps(propName, propValue, null);
}
@Override
public List<T> findByProps(String[] propName, Object[] propValue, String order) {
Query query = createQuery(propName, propValue, order);
return mgt.find(query, getEntityClass());
}
@Override
public T uniqueByProp(String propName, Object propValue) {
return mgt.findOne(new Query(where(propName).is(propValue)), getEntityClass());
}
@Override
public T uniqueByProps(String[] propName, Object[] propValue) {
Query query = createQuery(propName, propValue, null);
return mgt.findOne(query, getEntityClass());
}
@Override
public Page<T> pageAll(int pageNo, int pageSize) {
return pageAll(pageNo, pageSize, null);
}
@Override
public Page<T> pageAll(int pageNo, int pageSize, String order) {
return pageByProp(pageNo, pageSize, null, null, order);
}
@Override
public Page<T> pageByProp(int pageNo, int pageSize, String param, Object value) {
return pageByProp(pageNo, pageSize, param, value, "sendTime");
}
@Override
public Page<T> pageByProp(int pageNo, int pageSize, String param, Object value, String order) {
String[] params = null;
Object[] values = null;
if (EmptyUtil.isNotEmpty(param)) {
params = new String[] { param };
values = new Object[] { value };
}
return pageByProps(pageNo, pageSize, params, values, order);
}
@Override
public Page<T> pageByProps(int pageNo, int pageSize, String[] params, Object[] values) {
return pageByProps(pageNo, pageSize, params, values, null);
}
@Override
public Page<T> pageByProps(int pageNo, int pageSize, String[] params, Object[] values, String order) {
// 创建分页模型对象
Page<T> page = new Page<>(pageNo, pageSize);
// 查询总记录数
int count = countByCondition(params, values);
page.setTotal(count);
// 查询数据列表
Query query = createQuery(params, values, order);
// 设置分页信息
query.skip((page.getCurrent()-1)*page.getSize());
query.limit(page.getSize());
query.with(Sort.by(Direction.DESC,"sendTime"));
// 封装结果数据
page.setRecords(mgt.find(query, getEntityClass()));
return page;
}
@Override
public int countByCondition(String[] params, Object[] values) {
Query query = createQuery(params, values, null);
Long count = mgt.count(query, getEntityClass());
return count.intValue();
}
/**
* 创建带有where条件(只支持等值)和排序的Query对象
*
* @param params
* 参数数组
* @param values
* 参数值数组
* @param order
* 排序
* @return Query对象
*/
protected Query createQuery(String[] params, Object[] values, String order) {
Query query = new Query();
// where 条件
if (EmptyUtil.isNotEmpty(params) && EmptyUtil.isNotEmpty(values)) {
for (int i = 0; i < params.length; i++) {
query.addCriteria(where(params[i]).is(values[i]));
}
}
// 排序
List<Order> orderList = parseOrder(order);
if (EmptyUtil.isNotEmpty(orderList)) {
query.with(Sort.by(orderList));
}
return query;
}
/**
* 解析Order字符串为所需参数
*
* @param order
* 排序参数,如[id]、[id asc]、[id asc,name desc]
* @return Order对象集合
*/
protected List<Order> parseOrder(String order) {
List<Order> list = null;
if (EmptyUtil.isNotEmpty(order)) {
list = new ArrayList<Order>();
// 共有几组排序字段
String[] fields = order.split(",");
Order o = null;
String[] item = null;
for (int i = 0; i < fields.length; i++) {
if (EmptyUtil.isEmpty(fields[i])) {
continue;
}
item = fields[i].split(" ");
if (item.length == 1) {
o = new Order(Direction.ASC, item[0]);
} else if (item.length == 2) {
o = new Order("desc".equalsIgnoreCase(item[1]) ? Direction.DESC : Direction.ASC, item[0]);
} else {
throw new RuntimeException("排序字段参数解析出错");
}
list.add(o);
}
}
return list;
}
/**
* 将对象的字段及值反射解析为Map对象<br>
* 这里使用Java反射机制手动解析,并且可以识别注解为主键的字段,以达到根据id进行更新实体的目的<br>
* key:字段名称,value:字段对应的值
*
* @param t
* 要修改的对象
* @return Map对象,注意:id字段的key封装为“{id字段名称}”,以供后续识别
* @throws Exception
*/
protected Map<String, Object> parseEntity(T t) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
/*
* 解析ID
*/
String idName = "";
Field[] declaredFields = getEntityClass().getDeclaredFields();
for (Field field : declaredFields) {
if (field.isAnnotationPresent(Id.class)) {
field.setAccessible(true);
map.put("{" + field.getName() + "}", field.get(t));
idName = field.getName();
break;
}
}
/*
* 解析其他属性
*/
Method[] methods = getEntityClass().getDeclaredMethods();
if (EmptyUtil.isNotEmpty(methods)) {
for (Method method : methods) {
if (method.getName().startsWith("get") && method.getModifiers() == Modifier.PUBLIC) {
String fieldName = parse2FieldName(method.getName());
if (!fieldName.equals(idName)) {
map.put(fieldName, method.invoke(t));
}
}
}
}
return map;
}
/**
* 将get方法名转换为对应的字段名称
*
* @param methodName
* 如:getName
* @return 如:name
*/
private String parse2FieldName(String methodName) {
String name = methodName.replace("get", "");
name = name.substring(0, 1).toLowerCase() + name.substring(1);
return name;
}
}
🌵EmptyUtil
public class EmptyUtil {
/**
* 私有构造
*/
private EmptyUtil() {
}
/**
* 判断字符串是否为空
*
* @param str
* @return true or false
*/
public static boolean isEmpty(String str) {
return str == null || str == "" || str.trim() == "" || str.length() <= 0;
}
/**
* 判断List是否为空
*
* @param list
* @return true or false
*/
public static <T> boolean isEmpty(List<T> list) {
return list == null || list.isEmpty();
}
/**
* 判断Map是否为空
*
* @param map
* @return true or false
*/
public static <K, V> boolean isEmpty(Map<K, V> map) {
return map == null || map.isEmpty();
}
/**
* 判断数组是否为空
*
* @param array
* @return true or false
*/
public static <T> boolean isEmpty(T[] array) {
return array == null || array.length == 0;
}
/**
* 判断字符串是否不为空
*
* @param str
* @return true or false
*/
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
/**
* 判断List是否不为空
*
* @param list
* @return true or false
*/
public static <T> boolean isNotEmpty(List<T> list) {
return !isEmpty(list);
}
/**
* 判断Map是否不为空
*
* @param map
* @return true or false
*/
public static <K, V> boolean isNotEmpty(Map<K, V> map) {
return !isEmpty(map);
}
/**
* 判断数组是否不为空
*
* @param array
* @return true or false
*/
public static <T> boolean isNotEmpty(T[] array) {
return !isEmpty(array);
}
}
🌵User
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
private static final long serialVersionUID = -4328989516223829865L;
/**
* 用户ID
*/
private String id;
/**
* 用户账号
*/
private String userName;
/**
* 密码
*/
private String password;
}
🌵UserMServiceImpl
public class UserMServiceImpl extends MongoServiceImpl<User> implements UserMService {
@Override
protected Class<User> getEntityClass() {
return User.class;
}
@Override
public void insert(User user) {
save(user);
}
@Override
public User selectById(String id) {
return find(id);
}
}
🌵MongoController
@RestController
@RequestMapping("/mongo")
public class MongoController {
@Autowired
private UserMService userMService;
@ResponseBody
@GetMapping("/add")
public User add(){
String id = UUID.randomUUID().toString();
User user = User.builder().id(id).userName("aa").password("111111").build();
userMService.insert(user);
User userMb= userMService.selectById(id);
return userMb;
}
}