若依基本使用及改造记录

若依框架想必大家都了解得不少,不可否认这是一款及其简便易用的框架。

在某种情况下(比如私活)使用起来可谓是快得一匹。

在这里小兵结合自身实际使用情况,记录一下我对若依框架的使用和改造情况。

一、源码下载

前往码云进行下载。(vue前后端分离版)

RuoYi-Vue: 🎉 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本

下载后是下面图片的样子,除了 ruoyi-ui 是前端项目外,其它都是后端代码。

可以自行创建两个 git 项目如 ry-admin 、 ry-web,将后端源代码、前端源代码分别上传到自己的git 项目中方便后面管理。

二、源码启动

2.1 修改数据库连接

查看: ruoyi-admin\src\main\resources\application-druid.yml 中的配置,可看到其默认配置如下。

master:url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: password

把 库名 ry-vue 和 密码 password 换成自己的库名和密码. 

然后执行项目初始化sql: sql/ry_20240629.sql

2.2 启动后端服务

修改完数据库连接/redis连接并初始化sql后,找到 com/ruoyi/RuoYiApplication.java 右键启动

启动成功后,可以访问 8080 端口进行验证。

2.3 启动前端服务

先安装依赖 npm i 

 安装完成后启动  npm run dev

访问 localhost 使用 admin/admin123 可以看到初版页面。

默认的首页是若依框架的介绍页面,一般不会使用。可以先用若依提供的 views/index_v1.vue 中的内容替换 views/index.vue 的内容,有点首页的样子先。

右上角的工具栏,一般只需要保留全屏功能即可。

全局搜索“源码地址”,将无关功能注释或删掉,保留所需即可。

 若依官网的菜单也通过 系统管理-菜单管理 删除。 

验证码可以在application.yml中将方式修改为字符验证 captchaType: char

前端换名:搜索“若依”关键字,将其替换为自身项目名字,如erp管理系统。

 后端换名:在主目录pom.xml中将后端源项目名改为自身项目名字,如将 com.ruoyi 改成 com.erp

三、原始CURD使用

若依提供了基本的代码生成功能。

以如下测试表 demo1 为例

CREATE TABLE `demo1` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',`name` varchar(255) DEFAULT NULL COMMENT '用户名',`age` int(11) DEFAULT NULL COMMENT '年龄',`birthday` date DEFAULT NULL COMMENT '出生日期',`create_time` datetime DEFAULT NULL,`create_by` varchar(255) DEFAULT NULL,`update_time` datetime DEFAULT NULL,`update_by` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测试示例表1';

执行以上sql后,在前端页面  系统工具-代码生成 中生成对应代码,并使用。

将生成的 controller/service/mapper/domain/js/vue 代码复制到相应位置,并执行对应sql后,重启项目,可以使用对该表在页面中进行增删改查功能的使用。

四、使用mybatisPlus

 一般项目中可以使用 mybatisPlus 和 lombok 来加速开发,代码更为简便和优雅。若依中未进行使用。可以对其进行改造。

在 ruoyi-common/pom.xml 中导入相关依赖:

        <lombok.version>1.18.20</lombok.version><mybatis-plus.version>3.5.1</mybatis-plus.version><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency>

将mybatis改为mybatisPlus:

修改com/ruoyi/framework/config/MyBatisConfig.java 中的 SqlSessionFactoryBean 为 MybatisSqlSessionFactoryBean

final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();

再以上示测试表复制为 demo2 为例,对应实体如下:

package com.ruoyi.system.domain;import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import com.ruoyi.common.annotation.Excel;/*** 测试示例2对象 demo2** @author ruoyi* @date 2025-01-28*/
@Data
public class Demo2
{private static final long serialVersionUID = 1L;/** id */private Long id;/** 用户名 */@Excel(name = "用户名")private String name;/** 年龄 */@Excel(name = "年龄")private Long age;/** 出生日期 */@JsonFormat(pattern = "yyyy-MM-dd")@Excel(name = "出生日期", width = 30, dateFormat = "yyyy-MM-dd")private Date birthday;/** 创建者 */private String createBy;/** 创建时间 */@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createTime;/** 更新者 */private String updateBy;/** 更新时间 */@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date updateTime;}

对应mapper.xml 多继承 BaseMapper:

public interface Demo2Mapper extends BaseMapper<Demo2> {...
}

对应 service.java 多继承 IService:

public interface IDemo2Service extends IService<Demo2> {...
}

对应 serviceImpl.java 多继承 ServiceImpl: 

public class Demo2ServiceImpl extends ServiceImpl<Demo2Mapper, Demo2> implements IDemo2Service {....
}

为了使自动生成的代码也达到使用mybatisPlus的效果,需要修改 ruoyi-generator\src\main\resources\vm 对应的生成代码模板。

最终为自动生成代码改动的类有:

GenConstants、GenUtils、SecurityUtils、MyBatisConfig、MybatisPlusConfig、
generator.yml、controller.java.vm、domain.java.vm、mapper.java.vm、service.java.vm、serviceImpl.java.vm

GenConstants.java 如下:

package com.ruoyi.common.constant;/*** 代码生成通用常量** @author ruoyi*/
public class GenConstants
{/** 单表(增删改查) */public static final String TPL_CRUD = "crud";/** 树表(增删改查) */public static final String TPL_TREE = "tree";/** 主子表(增删改查) */public static final String TPL_SUB = "sub";/** 树编码字段 */public static final String TREE_CODE = "treeCode";/** 树父编码字段 */public static final String TREE_PARENT_CODE = "treeParentCode";/** 树名称字段 */public static final String TREE_NAME = "treeName";/** 上级菜单ID字段 */public static final String PARENT_MENU_ID = "parentMenuId";/** 上级菜单名称字段 */public static final String PARENT_MENU_NAME = "parentMenuName";/** 数据库字符串类型 */public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };/** 数据库文本类型 */public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };/** 数据库时间类型 */public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };/** 数据库数字类型 */public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer","bit", "bigint", "float", "double", "decimal" };/** 数据库int类型 */public static final String[] COLUMNTYPE_INT = { "tinyint", "smallint", "mediumint", "int", "integer", "bigint"};/** 页面不需要编辑字段 */public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };/** 页面不需要显示的列表字段 */public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by","update_time" };/** 页面不需要查询字段 */public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by","update_time", "remark" };/** Entity基类字段 */public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };/** Tree基类字段 */public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };/** 文本框 */public static final String HTML_INPUT = "input";/** 文本域 */public static final String HTML_TEXTAREA = "textarea";/** 下拉框 */public static final String HTML_SELECT = "select";/** 单选框 */public static final String HTML_RADIO = "radio";/** 复选框 */public static final String HTML_CHECKBOX = "checkbox";/** 日期控件 */public static final String HTML_DATETIME = "datetime";/** 图片上传控件 */public static final String HTML_IMAGE_UPLOAD = "imageUpload";/** 文件上传控件 */public static final String HTML_FILE_UPLOAD = "fileUpload";/** 富文本控件 */public static final String HTML_EDITOR = "editor";/** 字符串类型 */public static final String TYPE_STRING = "String";/** 整型 */public static final String TYPE_INTEGER = "Integer";/** 长整型 */public static final String TYPE_LONG = "Long";/** 浮点型 */public static final String TYPE_DOUBLE = "Double";/** 高精度计算类型 */public static final String TYPE_BIGDECIMAL = "BigDecimal";/** 时间类型 */public static final String TYPE_DATE = "Date";/** 模糊查询 */public static final String QUERY_LIKE = "LIKE";/** 相等查询 */public static final String QUERY_EQ = "EQ";/** 需要 */public static final String REQUIRE = "1";
}

GenUtils.java

package com.ruoyi.generator.util;import java.util.Arrays;
import org.apache.commons.lang3.RegExUtils;
import com.ruoyi.common.constant.GenConstants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.generator.config.GenConfig;
import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn;/*** 代码生成器 工具类** @author ruoyi*/
public class GenUtils
{/*** 初始化表信息*/public static void initTable(GenTable genTable, String operName){genTable.setClassName(convertClassName(genTable.getTableName()));genTable.setPackageName(GenConfig.getPackageName());genTable.setModuleName(getModuleName(GenConfig.getPackageName()));genTable.setBusinessName(getBusinessName(genTable.getTableName()));genTable.setFunctionName(replaceText(genTable.getTableComment()));genTable.setFunctionAuthor(GenConfig.getAuthor());genTable.setCreateBy(operName);}/*** 初始化列属性字段*/public static void initColumnField(GenTableColumn column, GenTable table){String dataType = getDbType(column.getColumnType());String columnName = column.getColumnName();column.setTableId(table.getTableId());column.setCreateBy(table.getCreateBy());// 设置java字段名column.setJavaField(StringUtils.toCamelCase(columnName));// 设置默认类型column.setJavaType(GenConstants.TYPE_STRING);column.setQueryType(GenConstants.QUERY_EQ);if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)){// 字符串长度超过500设置为文本域Integer columnLength = getColumnLength(column.getColumnType());String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;column.setHtmlType(htmlType);}else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)){column.setJavaType(GenConstants.TYPE_DATE);column.setHtmlType(GenConstants.HTML_DATETIME);}else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)){column.setHtmlType(GenConstants.HTML_INPUT);// 如果是浮点型 统一用BigDecimalString[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ",");if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0){column.setJavaType(GenConstants.TYPE_BIGDECIMAL);}//常用int 对应 Integer / Longelse  if (arraysContains(GenConstants.COLUMNTYPE_INT, dataType)) {if (dataType.equals(GenConstants.COLUMNTYPE_INT[GenConstants.COLUMNTYPE_INT.length - 1])) {column.setJavaType(GenConstants.TYPE_LONG);} else {column.setJavaType(GenConstants.TYPE_INTEGER);}}// 如果是整形else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10){column.setJavaType(GenConstants.TYPE_INTEGER);}// 长整形else{column.setJavaType(GenConstants.TYPE_LONG);}}// 插入字段(默认所有字段都需要插入)column.setIsInsert(GenConstants.REQUIRE);// 编辑字段if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk()){column.setIsEdit(GenConstants.REQUIRE);}// 列表字段if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk()){column.setIsList(GenConstants.REQUIRE);}// 查询字段if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()){column.setIsQuery(GenConstants.REQUIRE);}// 查询字段类型if (StringUtils.endsWithIgnoreCase(columnName, "name")){column.setQueryType(GenConstants.QUERY_LIKE);}// 状态字段设置单选框if (StringUtils.endsWithIgnoreCase(columnName, "status")){column.setHtmlType(GenConstants.HTML_RADIO);}// 类型&性别字段设置下拉框else if (StringUtils.endsWithIgnoreCase(columnName, "type")|| StringUtils.endsWithIgnoreCase(columnName, "sex")){column.setHtmlType(GenConstants.HTML_SELECT);}// 图片字段设置图片上传控件else if (StringUtils.endsWithIgnoreCase(columnName, "image")){column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD);}// 文件字段设置文件上传控件else if (StringUtils.endsWithIgnoreCase(columnName, "file")){column.setHtmlType(GenConstants.HTML_FILE_UPLOAD);}// 内容字段设置富文本控件else if (StringUtils.endsWithIgnoreCase(columnName, "content")){column.setHtmlType(GenConstants.HTML_EDITOR);}}/*** 校验数组是否包含指定值** @param arr 数组* @param targetValue 值* @return 是否包含*/public static boolean arraysContains(String[] arr, String targetValue){return Arrays.asList(arr).contains(targetValue);}/*** 获取模块名** @param packageName 包名* @return 模块名*/public static String getModuleName(String packageName){int lastIndex = packageName.lastIndexOf(".");int nameLength = packageName.length();return StringUtils.substring(packageName, lastIndex + 1, nameLength);}/*** 获取业务名** @param tableName 表名* @return 业务名*/public static String getBusinessName(String tableName){int lastIndex = tableName.lastIndexOf("_");int nameLength = tableName.length();return StringUtils.substring(tableName, lastIndex + 1, nameLength);}/*** 表名转换成Java类名** @param tableName 表名称* @return 类名*/public static String convertClassName(String tableName){boolean autoRemovePre = GenConfig.getAutoRemovePre();String tablePrefix = GenConfig.getTablePrefix();if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)){String[] searchList = StringUtils.split(tablePrefix, ",");tableName = replaceFirst(tableName, searchList);}return StringUtils.convertToCamelCase(tableName);}/*** 批量替换前缀** @param replacementm 替换值* @param searchList 替换列表* @return*/public static String replaceFirst(String replacementm, String[] searchList){String text = replacementm;for (String searchString : searchList){if (replacementm.startsWith(searchString)){text = replacementm.replaceFirst(searchString, "");break;}}return text;}/*** 关键字替换** @param text 需要被替换的名字* @return 替换后的名字*/public static String replaceText(String text){return RegExUtils.replaceAll(text, "(?:表|若依)", "");}/*** 获取数据库类型字段** @param columnType 列类型* @return 截取后的列类型*/public static String getDbType(String columnType){if (StringUtils.indexOf(columnType, "(") > 0){return StringUtils.substringBefore(columnType, "(");}else{return columnType;}}/*** 获取字段长度** @param columnType 列类型* @return 截取后的列类型*/public static Integer getColumnLength(String columnType){if (StringUtils.indexOf(columnType, "(") > 0){String length = StringUtils.substringBetween(columnType, "(", ")");return Integer.valueOf(length);}else{return 0;}}
}

SecurityUtils.java

package com.ruoyi.common.utils;import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.PatternMatchUtils;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;/*** 安全服务工具类** @author ruoyi*/
public class SecurityUtils
{/*** 用户ID**/public static Long getUserId(){try{return getLoginUser().getUserId();}catch (Exception e){throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED);}}/*** 获取部门ID**/public static Long getDeptId(){try{return getLoginUser().getDeptId();}catch (Exception e){throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED);}}public static String getOperator() {LoginUser loginUser = getLoginUser();return String.format("{\"userId\":%s,\"userName\":\"%s\"}", loginUser.getUser().getUserId(), loginUser.getUser().getUserName());}/*** 获取用户账户**/public static String getUsername(){try{return getLoginUser().getUsername();}catch (Exception e){throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED);}}/*** 获取用户**/public static LoginUser getLoginUser(){try{return (LoginUser) getAuthentication().getPrincipal();}catch (Exception e){throw new ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED);}}/*** 获取Authentication*/public static Authentication getAuthentication(){return SecurityContextHolder.getContext().getAuthentication();}/*** 生成BCryptPasswordEncoder密码** @param password 密码* @return 加密字符串*/public static String encryptPassword(String password){BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();return passwordEncoder.encode(password);}/*** 判断密码是否相同** @param rawPassword 真实密码* @param encodedPassword 加密后字符* @return 结果*/public static boolean matchesPassword(String rawPassword, String encodedPassword){BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();return passwordEncoder.matches(rawPassword, encodedPassword);}/*** 是否为管理员** @param userId 用户ID* @return 结果*/public static boolean isAdmin(Long userId){return userId != null && 1L == userId;}/*** 验证用户是否具备某权限** @param permission 权限字符串* @return 用户是否具备某权限*/public static boolean hasPermi(String permission){return hasPermi(getLoginUser().getPermissions(), permission);}/*** 判断是否包含权限** @param authorities 权限列表* @param permission 权限字符串* @return 用户是否具备某权限*/public static boolean hasPermi(Collection<String> authorities, String permission){return authorities.stream().filter(StringUtils::hasText).anyMatch(x -> Constants.ALL_PERMISSION.equals(x) || PatternMatchUtils.simpleMatch(x, permission));}/*** 验证用户是否拥有某个角色** @param role 角色标识* @return 用户是否具备某角色*/public static boolean hasRole(String role){List<SysRole> roleList = getLoginUser().getUser().getRoles();Collection<String> roles = roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toSet());return hasRole(roles, role);}/*** 判断是否包含角色** @param roles 角色列表* @param role 角色* @return 用户是否具备某角色权限*/public static boolean hasRole(Collection<String> roles, String role){return roles.stream().filter(StringUtils::hasText).anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role));}}

MyBatisConfig.java

package com.ruoyi.framework.config;import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import javax.sql.DataSource;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.io.VFS;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;
import com.ruoyi.common.utils.StringUtils;/*** Mybatis支持*匹配扫描包** @author ruoyi*/
@Configuration
public class MyBatisConfig {@Autowiredprivate Environment env;static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";public static String setTypeAliasesPackage(String typeAliasesPackage) {ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);List<String> allResult = new ArrayList<String>();try {for (String aliasesPackage : typeAliasesPackage.split(",")) {List<String> result = new ArrayList<String>();aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+ ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;Resource[] resources = resolver.getResources(aliasesPackage);if (resources != null && resources.length > 0) {MetadataReader metadataReader = null;for (Resource resource : resources) {if (resource.isReadable()) {metadataReader = metadataReaderFactory.getMetadataReader(resource);try {result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());} catch (ClassNotFoundException e) {e.printStackTrace();}}}}if (result.size() > 0) {HashSet<String> hashResult = new HashSet<String>(result);allResult.addAll(hashResult);}}if (allResult.size() > 0) {typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));} else {throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");}} catch (IOException e) {e.printStackTrace();}return typeAliasesPackage;}public Resource[] resolveMapperLocations(String[] mapperLocations) {ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();List<Resource> resources = new ArrayList<Resource>();if (mapperLocations != null) {for (String mapperLocation : mapperLocations) {try {Resource[] mappers = resourceResolver.getResources(mapperLocation);resources.addAll(Arrays.asList(mappers));} catch (IOException e) {// ignore}}}return resources.toArray(new Resource[resources.size()]);}@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");String mapperLocations = env.getProperty("mybatis.mapperLocations");String configLocation = env.getProperty("mybatis.configLocation");typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);VFS.addImplClass(SpringBootVFS.class);//        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);sessionFactory.setTypeAliasesPackage(typeAliasesPackage);sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));//mp全局配置GlobalConfig globalConfig = new GlobalConfig();GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();dbConfig .setIdType(IdType.AUTO);globalConfig.setDbConfig(dbConfig);globalConfig.setMetaObjectHandler(new MybatisPlusConfig());sessionFactory.setGlobalConfig(globalConfig);return sessionFactory.getObject();}
}

MybatisPlusConfig.java

package com.ruoyi.framework.config;import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.ruoyi.common.utils.SecurityUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Configuration;import java.util.Date;/*** MybatisPlus配置类* 实现插入/修改时自动修改时间、操作人(实体类上使用 @TableField(fill = FieldFill.INSERT/INSERT_UPDATE))*/
@Configuration
public class MybatisPlusConfig implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {this.fillStrategy(metaObject, "createTime", new Date());if (ObjectUtil.isNotEmpty(SecurityUtils.getUserId())) {this.fillStrategy(metaObject, "createBy", SecurityUtils.getOperator());}}@Overridepublic void updateFill(MetaObject metaObject) {this.fillStrategy(metaObject, "updateTime", new Date());if (ObjectUtil.isNotEmpty(SecurityUtils.getUserId())) {this.fillStrategy(metaObject, "updateBy", SecurityUtils.getOperator());}}}

controller.java.vm

package ${packageName}.controller;import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import ${packageName}.domain.${ClassName};
import ${packageName}.service.I${ClassName}Service;
import com.ruoyi.common.utils.poi.ExcelUtil;
#if($table.crud || $table.sub)
import com.ruoyi.common.core.page.TableDataInfo;
#elseif($table.tree)
#end/*** ${functionName}Controller** @author ${author}* @date ${datetime}*/
@RestController
@RequestMapping("/${moduleName}/${businessName}")
public class ${ClassName}Controller extends BaseController {@Autowiredprivate I${ClassName}Service ${className}Service;/*** 查询${functionName}列表*/@PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')")@GetMapping("/list")
#if($table.crud || $table.sub)public TableDataInfo list(${ClassName} ${className}){startPage();List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});return getDataTable(list);}
#elseif($table.tree)public AjaxResult list(${ClassName} ${className}){List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});return success(list);}
#end/*** 导出${functionName}列表*/@PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')")@Log(title = "${functionName}", businessType = BusinessType.EXPORT)@PostMapping("/export")public void export(HttpServletResponse response, ${ClassName} ${className}){List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);util.exportExcel(response, list, "${functionName}数据");}/*** 获取${functionName}详细信息*/@PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')")@GetMapping(value = "/{${pkColumn.javaField}}")public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}){return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));}/*** 新增${functionName}*/@PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')")@Log(title = "${functionName}", businessType = BusinessType.INSERT)@PostMappingpublic AjaxResult add(@RequestBody ${ClassName} ${className}){return toAjax(${className}Service.insert${ClassName}(${className}));}/*** 修改${functionName}*/@PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')")@Log(title = "${functionName}", businessType = BusinessType.UPDATE)@PutMappingpublic AjaxResult edit(@RequestBody ${ClassName} ${className}){return toAjax(${className}Service.update${ClassName}(${className}));}/*** 删除${functionName}*/@PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')")@Log(title = "${functionName}", businessType = BusinessType.DELETE)@DeleteMapping("/{${pkColumn.javaField}s}")public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s){return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s));}
}

domain.java.vm

package ${packageName}.domain;import java.util.Date;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.IdType;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.ToString;
import com.ruoyi.common.annotation.Excel;/*** ${functionName}对象 ${tableName}** @author ${author}* @date ${datetime}*/
@Data
@ToString
public class ${ClassName} {private static final long serialVersionUID = 1L;#foreach ($column in $columns)/** $column.columnComment */#set($parentheseIndex=$column.columnComment.indexOf("("))#if($parentheseIndex != -1)#set($comment=$column.columnComment.substring(0, $parentheseIndex))#else#set($comment=$column.columnComment)#end#if($parentheseIndex != -1)@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")#elseif($column.columnType == "date")@JsonFormat(pattern = "yyyy-MM-dd")@Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")#elseif($column.columnType == "datetime")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")@Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")#else@Excel(name = "${comment}")#end#if($column.javaField == "createTime")@TableField(fill = FieldFill.INSERT)#elseif($column.javaField == "createBy")@TableField(fill = FieldFill.INSERT)#end#if($column.javaField == "updateTime")@TableField(fill = FieldFill.UPDATE)#elseif($column.javaField == "updateBy")@TableField(fill = FieldFill.UPDATE)#end#if($column.isPk == 1)@TableId(type = IdType.AUTO)#endprivate $column.javaType $column.javaField;#end
}

mapper.java.vm

package ${packageName}.mapper;import java.util.List;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ${packageName}.domain.${ClassName};
#if($table.sub)
import ${packageName}.domain.${subClassName};
#end/*** ${functionName}Mapper接口** @author ${author}* @date ${datetime}*/
public interface ${ClassName}Mapper extends BaseMapper<${ClassName}> {/*** 查询${functionName}列表** @param ${className} ${functionName}* @return ${functionName}集合*/public List<${ClassName}> select${ClassName}List(${ClassName} ${className});}

service.java.vm

package ${packageName}.service;import java.util.List;import com.baomidou.mybatisplus.extension.service.IService;
import ${packageName}.domain.${ClassName};/*** ${functionName}Service接口** @author ${author}* @date ${datetime}*/
public interface I${ClassName}Service extends IService<${ClassName}> {/*** 查询${functionName}** @param ${pkColumn.javaField} ${functionName}主键* @return ${functionName}*/public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});/*** 查询${functionName}列表** @param ${className} ${functionName}* @return ${functionName}集合*/public List<${ClassName}> select${ClassName}List(${ClassName} ${className});/*** 新增${functionName}** @param ${className} ${functionName}* @return 结果*/public int insert${ClassName}(${ClassName} ${className});/*** 修改${functionName}** @param ${className} ${functionName}* @return 结果*/public int update${ClassName}(${ClassName} ${className});/*** 批量删除${functionName}** @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合* @return 结果*/public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);/*** 删除${functionName}信息** @param ${pkColumn.javaField} ${functionName}主键* @return 结果*/public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
}

serviceImpl.java.vm

package ${packageName}.service.impl;import java.util.Arrays;
import java.util.List;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
#foreach ($column in $columns)
#if($column.javaField == 'createTime' || $column.javaField == 'updateTime')
import com.ruoyi.common.utils.DateUtils;
#break
#end
#end
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#if($table.sub)
import java.util.List;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import ${packageName}.domain.${subClassName};
#end
import ${packageName}.mapper.${ClassName}Mapper;
import ${packageName}.domain.${ClassName};
import ${packageName}.service.I${ClassName}Service;/*** ${functionName}Service业务层处理** @author ${author}* @date ${datetime}*/
@Service
public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}> implements I${ClassName}Service {@Autowiredprivate ${ClassName}Mapper ${className}Mapper;/*** 查询${functionName}** @param ${pkColumn.javaField} ${functionName}主键* @return ${functionName}*/@Overridepublic ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) {return getById(${pkColumn.javaField});}/*** 查询${functionName}列表** @param ${className} ${functionName}* @return ${functionName}*/@Overridepublic List<${ClassName}> select${ClassName}List(${ClassName} ${className}) {return ${className}Mapper.select${ClassName}List(${className});}/*** 新增${functionName}** @param ${className} ${functionName}* @return 结果*/
#if($table.sub)@Transactional
#end@Overridepublic int insert${ClassName}(${ClassName} ${className}) {save(${className});#foreach ($column in $columns)#if($column.isPk == '1')return ${className}.get${column.capJavaField}();#end#end}/*** 修改${functionName}** @param ${className} ${functionName}* @return 结果*/
#if($table.sub)@Transactional
#end@Overridepublic int update${ClassName}(${ClassName} ${className}) {return updateById(${className}) ? 1 : 0;}/*** 批量删除${functionName}** @param ${pkColumn.javaField}s 需要删除的${functionName}主键* @return 结果*/@Overridepublic int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s) {return removeBatchByIds(Arrays.asList(${pkColumn.javaField}s))  ? 1 : 0;}/*** 删除${functionName}信息** @param ${pkColumn.javaField} ${functionName}主键* @return 结果*/@Overridepublic int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) {return removeById(${pkColumn.javaField}) ? 1 : 0;}
#if($table.sub)/*** 新增${subTable.functionName}信息** @param ${className} ${functionName}对象*/public void insert${subClassName}(${ClassName} ${className}) {List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List();${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}();if (StringUtils.isNotNull(${subclassName}List)){List<${subClassName}> list = new ArrayList<${subClassName}>();for (${subClassName} ${subclassName} : ${subclassName}List){${subclassName}.set${subTableFkClassName}(${pkColumn.javaField});list.add(${subclassName});}if (list.size() > 0){${className}Mapper.batch${subClassName}(list);}}}
#end
}


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/893988.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka 深入服务端 — 时间轮

Kafka中存在大量的延迟操作&#xff0c;比如延时生产、延时拉取和延时删除等。Kafka基于时间轮概念自定义实现了一个用于延时功能的定时器&#xff0c;来完成这些延迟操作。 1 时间轮 Kafka没有使用基于JDK自带的Timer或DelayQueue来实现延迟功能&#xff0c;因为它们的插入和…

数据分析系列--②RapidMiner导入数据和存储过程

一、下载数据 点击下载AssociationAnalysisData.xlsx数据集 二、导入数据 1. 在本地计算机中创建3个文件夹 2. 从本地选择.csv或.xlsx 三、界面说明 四、存储过程 将刚刚新建的过程存储到本地 Congratulations, you are done.

HarmonyOS简介:HarmonyOS核心技术理念

核心理念 一次开发、多端部署可分可合、自由流转统一生态、原生智能 一次开发、多端部署 可分可合 自由流转 自由流转可分为跨端迁移和多端协同两种情况 统一生态 支持业界主流跨平台开发框架&#xff0c;通过多层次的开放能力提供统一接入标准&#xff0c;实现三方框架快速…

ES6语法

一、Let、const、var变量定义 1.let 声明的变量有严格局部作用域 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&g…

书生大模型实战营3

文章目录 L0——入门岛git基础Git 是什么&#xff1f;Git 中的一些基本概念工作区、暂存区和 Git 仓库区文件状态分支主要功能 Git 平台介绍GitHubGitLabGitee Git 下载配置验证下载 Git配置 Git验证 Git配置 Git常用操作Git简易入门四部曲Git其他指令 闯关任务任务1: 破冰活动…

前端——js高级25.1.27

复习&#xff1a;对象 问题一&#xff1a; 多个数据的封装提 一个对象对应现实中的一个事物 问题二&#xff1a; 统一管理多个数据 问题三&#xff1a; 属性&#xff1a;组成&#xff1a;属性名属性值 &#xff08;属性名为字符串&#xff0c;属性值任意&#xff09; 方…

[创业之路-270]:《向流程设计要效率》-2-企业流程架构模式 POS架构(规划、业务运营、支撑)、OES架构(业务运营、使能、支撑)

目录 一、POS架构 二、OES架构 三、POS架构与OES架构的差异 四、各自的典型示例 POS架构典型示例 OES架构典型示例 示例分析 五、各自的典型企业 POS架构典型企业 OES架构典型企业 分析 六、各自典型的流程 POS架构的典型流程 OES架构的典型流程 企业流程架构模式…

计算机的错误计算(二百二十二)

摘要 利用大模型化简计算 实验表明&#xff0c;虽然结果正确&#xff0c;但是&#xff0c;大模型既绕了弯路&#xff0c;又有数值计算错误。 与前面相同&#xff0c;再利用同一个算式看看另外一个大模型的化简与计算能力。 例1. 化简计算摘要中算式。 下面是与一个大模型的…

【现代深度学习技术】深度学习计算 | 参数管理

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

C语言,无法正常释放char*的空间

问题描述 #include <stdio.h> #include <stdio.h>const int STRSIZR 10;int main() {char *str (char *)malloc(STRSIZR*sizeof(char));str "string";printf("%s\n", str);free(str); } 乍一看&#xff0c;这块代码没有什么问题。直接书写…

【开源免费】基于Vue和SpringBoot的在线文档管理系统(附论文)

本文项目编号 T 038 &#xff0c;文末自助获取源码 \color{red}{T038&#xff0c;文末自助获取源码} T038&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

忘记宝塔的访问地址怎么找

在linux中安装宝塔面板后会生成网址、账号和密码 如果网址忘记了那将进不去宝塔面板该怎么办呢&#xff1f; bt命令 我们输入 bt 命令的时候&#xff0c;是在根目录里面进行操作的。 / bt 我们根据自己的需要&#xff0c;选择对应的数字就可以了。 bt 14 输入 14 查看面板默…

力扣hot100-->滑动窗口、贪心

你好呀&#xff0c;欢迎来到 Dong雨 的技术小栈 &#x1f331; 在这里&#xff0c;我们一同探索代码的奥秘&#xff0c;感受技术的魅力 ✨。 &#x1f449; 我的小世界&#xff1a;Dong雨 &#x1f4cc; 分享我的学习旅程 &#x1f6e0;️ 提供贴心的实用工具 &#x1f4a1; 记…

【蓝桥杯嵌入式入门与进阶】2.与开发板之间破冰:初始开发板和原理图2

个人主页&#xff1a;Icomi 专栏地址&#xff1a;蓝桥杯嵌入式组入门与进阶 大家好&#xff0c;我是一颗米&#xff0c;本篇专栏旨在帮助大家从0开始入门蓝桥杯并且进阶&#xff0c;若对本系列文章感兴趣&#xff0c;欢迎订阅我的专栏&#xff0c;我将持续更新&#xff0c;祝你…

Spring Boot - 数据库集成02 - 集成JPA

集成JPA 文章目录 集成JPA一&#xff1a;JPA概述1&#xff1a;JPA & JDBC2&#xff1a;JPA规范3&#xff1a;JPA的状态和转换关系 二&#xff1a;Spring data JPA1&#xff1a;JPA_repository1.1&#xff1a;CurdRepostory<T, ID>1.2&#xff1a;PagingAndSortingRep…

从ai产品推荐到利用cursor快速掌握一个开源项目再到langchain手搓一个Text2Sql agent

目录 0. 经验分享&#xff1a;产品推荐 1. 经验分享&#xff1a;提示词优化 2. 经验分享&#xff1a;使用cursor 阅读一篇文章 3. 经验分享&#xff1a;使用cursor 阅读一个完全陌生的开源项目 4. 经验分享&#xff1a;手搓一个text2sql agent &#xff08;使用langchain l…

【Java-数据结构】Java 链表面试题下 “最后一公里”:解决复杂链表问题的致胜法宝

我的个人主页 我的专栏&#xff1a;Java-数据结构&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 引言&#xff1a; Java链表&#xff0c;看似简单的链式结构&#xff0c;却蕴含着诸多有趣的特性与奥秘&#xff0c;等待我们去挖掘。它就像一…

智慧园区系统的类型及其在企业管理效率提升中的关键作用解析

内容概要 在智慧园区的建设中&#xff0c;各类系统的采用是提升管理效率的关键所在。快鲸智慧园区(楼宇)管理系统&#xff0c;通过其全面数字化的管理手段&#xff0c;已经成为了企业管理的新标杆。这一系统能够有效整合租赁管理、资产管理、招商管理和物业管理等功能&#xf…

多级缓存(亿级并发解决方案)

多级缓存&#xff08;亿级流量&#xff08;并发&#xff09;的缓存方案&#xff09; 传统缓存的问题 传统缓存是请求到达tomcat后&#xff0c;先查询redis&#xff0c;如果未命中则查询数据库&#xff0c;问题如下&#xff1a; &#xff08;1&#xff09;请求要经过tomcat处…

第27篇 基于ARM A9处理器用C语言实现中断<三>

Q&#xff1a;基于ARM A9处理器怎样设计C语言工程&#xff0c;同时使用按键中断和定时器中断在红色LED上计数&#xff1f; A&#xff1a;基本原理&#xff1a;设置HPS Timer 0和按键中断源&#xff0c;主程序调用set_A9_IRQ_stack( )函数设置中断模式的ARM堆栈指针&#xff0c…