若依是一个基于 Spring Boot、Spring Security、MyBatis-Plus、Vue.js 的前后端分离的开源快速开发平台,它提供了代码生成器功能,能根据数据库表结构自动生成对应的实体类、Mapper 接口、Service 层、Controller 层代码,还能生成前端页面代码。

详细步骤:

1. 环境准备


确保已经安装好若依项目,并且数据库中已经创建了需要生成代码的表。
若依项目正常启动,能够访问其管理界面。


2. 登录若依管理系统


打开浏览器,访问若依管理系统的登录页面(通常是 http://localhost:8080 ),使用管理员账号登录。


3. 进入代码生成模块


登录成功后,在左侧菜单中找到 “系统工具” -> “代码生成”,点击进入代码生成页面。


4. 导入表结构


在代码生成页面,点击 “导入” 按钮,选择要生成代码的数据库表。若依会自动读取数据库中的表结构信息,包括表名、字段名、字段类型等。


5. 设置生成信息


基本信息:
表名:自动显示导入的表名,可根据需要修改。
描述:填写该表的简要描述,会在生成的代码注释中体现。
生成包路径:指定生成代码存放的包路径,例如 com.ruoyi.module。
生成模块名:填写生成代码所属的模块名,如 demo。
生成业务名:填写业务名称,如 用户管理。
生成功能名:填写具体的功能名称,如 用户列表。
生成作者:填写代码的作者信息。
字段信息:
对每个字段的注释、Java 类型、是否为查询条件、是否在列表显示等信息进行设置。
可以根据需要修改字段的默认设置,例如将某个字段设置为查询条件,或者在列表中显示。


6. 预览和生成代码


预览代码:点击 “预览” 按钮,可以查看生成的代码的预览效果,包括实体类、Mapper 接口、Service 层、Controller 层代码以及前端页面代码。
生成代码:确认预览无误后,点击 “生成” 按钮,若依会将生成的代码打包成一个压缩文件,下载到本地。


7. 导入生成的代码


后端代码:将下载的压缩文件解压,把后端代码(Java 文件)复制到若依项目的相应目录下,通常是 ruoyi-admin 模块的 src/main/java 目录下。
前端代码:将前端代码(Vue 文件、JS 文件、CSS 文件等)复制到若依项目的前端部分(通常是 ruoyi-ui 目录)的相应目录下。


8. 配置路由和菜单(可选)


如果需要在若依管理系统的菜单中显示新生成的功能,可以在 “系统管理” -> “菜单管理” 中添加相应的菜单,并配置路由信息。

后端各层:

在若依这种典型的前后端分离的企业级开发框架中,通常会采用分层架构设计,每层都有其特定的职责和功能,常见的分层包括表现层(View 层)、控制层(Controller 层)、业务逻辑层(Service 层)、数据访问层(DAO 层,也叫 Mapper 层)和实体层(Entity 层)。

1. 实体层(Entity 层)

  • 含义:实体层主要包含各种实体类,这些类通常对应数据库中的表结构,用于封装数据。它们是业务数据的载体,在各层之间传递数据。
  • 作用:将数据库中的表抽象成 Java 对象,方便在代码中对数据进行操作和处理。例如,在若依系统中,如果有一个用户表,那么就会有一个对应的 User 实体类,它包含了用户的各种属性,如用户名、密码、邮箱等。
package com.ruoyi.demo.domain;

import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

/**
 * 用户实体类
 */
public class User extends BaseEntity {
    private static final long serialVersionUID = 1L;

    /** 用户ID */
    private Long userId;

    /** 用户姓名 */
    private String userName;

    // Getter和Setter方法
    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
               .append("userId", getUserId())
               .append("userName", getUserName())
               .toString();
    }
}

2. 数据访问层(DAO 层,也叫 Mapper 层)

  • 含义数据访问层负责与数据库进行交互,执行数据库的增删改查操作。在若依中,通常使用 MyBatis - Plus 来简化数据访问操作,该层的代码主要是一些接口和对应的 XML 文件(如果使用 XML 方式编写 SQL)。
  • 作用:将业务逻辑层的请求转化为数据库操作,屏蔽数据库操作的细节,为业务逻辑层提供数据访问服务。
package com.ruoyi.demo.mapper;

import com.ruoyi.demo.domain.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * 用户数据访问接口
 */
@Mapper
public interface UserMapper {
    /**
     * 查询用户列表
     * @param user 查询条件
     * @return 用户列表
     */
    List<User> selectUserList(User user);

    /**
     * 根据用户ID查询用户
     * @param userId 用户ID
     * @return 用户信息
     */
    User selectUserById(Long userId);

    /**
     * 新增用户
     * @param user 用户信息
     * @return 影响行数
     */
    int insertUser(User user);

    /**
     * 修改用户信息
     * @param user 用户信息
     * @return 影响行数
     */
    int updateUser(User user);

    /**
     * 删除用户
     * @param userId 用户ID
     * @return 影响行数
     */
    int deleteUserById(Long userId);
}

3. 业务逻辑层(Service 层)

  • 含义业务逻辑层是整个系统的核心,负责处理业务逻辑,协调数据访问层和控制层之间的交互。它会调用数据访问层的方法获取数据,并对数据进行处理和转换,以满足业务需求。
  • 作用:封装业务逻辑,将业务规则和数据访问逻辑分离,提高代码的可维护性和可测试性。例如,在用户注册业务中,业务逻辑层可能会进行密码加密、用户信息验证等操作。
package com.ruoyi.demo.service;

import com.ruoyi.demo.domain.User;

import java.util.List;

/**
 * 用户业务逻辑接口
 */
public interface UserService {
    /**
     * 查询用户列表
     * @param user 查询条件
     * @return 用户列表
     */
    List<User> selectUserList(User user);

    /**
     * 根据用户ID查询用户
     * @param userId 用户ID
     * @return 用户信息
     */
    User selectUserById(Long userId);

    /**
     * 新增用户
     * @param user 用户信息
     * @return 结果
     */
    int insertUser(User user);

    /**
     * 修改用户信息
     * @param user 用户信息
     * @return 结果
     */
    int updateUser(User user);

    /**
     * 删除用户
     * @param userId 用户ID
     * @return 结果
     */
    int deleteUserById(Long userId);
}
package com.ruoyi.demo.service.impl;

import com.ruoyi.demo.domain.User;
import com.ruoyi.demo.mapper.UserMapper;
import com.ruoyi.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 用户业务逻辑实现类
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> selectUserList(User user) {
        return userMapper.selectUserList(user);
    }

    @Override
    public User selectUserById(Long userId) {
        return userMapper.selectUserById(userId);
    }

    @Override
    public int insertUser(User user) {
        return userMapper.insertUser(user);
    }

    @Override
    public int updateUser(User user) {
        return userMapper.updateUser(user);
    }

    @Override
    public int deleteUserById(Long userId) {
        return userMapper.deleteUserById(userId);
    }
}
4. 控制层(Controller 层)
  • 含义控制层负责接收前端的请求,调用业务逻辑层的方法处理请求,并将处理结果返回给前端。它是前后端交互的桥梁,通常使用 Spring MVC 框架来实现。
  • 作用:处理请求,将请求参数传递给业务逻辑层进行处理,然后将处理结果封装成合适的格式返回给前端。同时,它还负责处理一些请求的验证和异常处理。
package com.ruoyi.demo.controller;

import com.ruoyi.demo.domain.User;
import com.ruoyi.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 用户控制层
 */
@RestController
@RequestMapping("/demo/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 查询用户列表
     * @param user 查询条件
     * @return 用户列表
     */
    @GetMapping("/list")
    public List<User> selectUserList(User user) {
        return userService.selectUserList(user);
    }

    /**
     * 根据用户ID查询用户
     * @param userId 用户ID
     * @return 用户信息
     */
    @GetMapping("/{userId}")
    public User selectUserById(@PathVariable Long userId) {
        return userService.selectUserById(userId);
    }

    /**
     * 新增用户
     * @param user 用户信息
     * @return 结果
     */
    @PostMapping
    public int insertUser(@RequestBody User user) {
        return userService.insertUser(user);
    }

    /**
     * 修改用户信息
     * @param user 用户信息
     * @return 结果
     */
    @PutMapping
    public int updateUser(@RequestBody User user) {
        return userService.updateUser(user);
    }

    /**
     * 删除用户
     * @param userId 用户ID
     * @return 结果
     */
    @DeleteMapping("/{userId}")
    public int deleteUserById(@PathVariable Long userId) {
        return userService.deleteUserById(userId);
    }
}

前端部分:

表现层(View 层)

  • 含义:表现层主要负责用户界面的展示和交互,通常使用 Vue.js、React 等前端框架来实现。在若依中,前端部分使用 Vue.js 构建,包含了各种页面组件、路由、样式等。
  • 作用:将后端提供的数据以可视化的方式展示给用户,并处理用户的交互事件,如点击、输入等。同时,它会将用户的请求发送给后端,并将后端返回的数据展示在页面上。
<template>
  <div>
    <el-form :inline="true" :model="queryParams" ref="queryForm" size="small">
      <el-form-item label="用户姓名">
        <el-input v-model="queryParams.userName" placeholder="请输入用户姓名" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="用户ID" align="center" prop="userId" width="100" />
      <el-table-column label="用户姓名" align="center" prop="userName" :show-overflow-tooltip="true" />
    </el-table>

    <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
  </div>
</template>

<script>
import { listUser } from '@/api/demo/user';

export default {
  data() {
    return {
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        userName: undefined
      },
      userList: [],
      total: 0,
      loading: false
    };
  },
  methods: {
    /** 查询用户列表 */
    getList() {
      this.loading = true;
      listUser(this.queryParams).then(response => {
        this.userList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    // 其他方法...
  },
  created() {
    this.getList();
  }
};
</script>

完整的流程

前端流程

1. 用户操作触发请求

用户在前端页面上进行操作,比如点击按钮、提交表单等,这些操作会触发相应的事件。以若依系统中的用户登录功能为例,用户在登录页面输入用户名和密码后,点击 “登录” 按钮,就会触发登录请求。

2. 前端路由与组件响应

前端使用 Vue.js 框架,借助 Vue Router 实现路由管理。当用户操作触发时,对应的路由会被匹配,相关的组件会被渲染。在登录场景下,点击 “登录” 按钮会触发登录组件中的事件处理函数。

<template>
  <div>
    <el-form :model="loginForm" ref="loginFormRef" :rules="loginRules" label-width="80px">
      <el-form-item label="用户名" prop="username">
        <el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input v-model="loginForm.password" type="password" placeholder="请输入密码"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleLogin">登录</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import { login } from '@/api/login';

export default {
  data() {
    return {
      loginForm: {
        username: '',
        password: ''
      },
      loginRules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' }
        ]
      }
    };
  },
  methods: {
    handleLogin() {
      this.$refs.loginFormRef.validate(valid => {
        if (valid) {
          login(this.loginForm).then(response => {
            // 处理登录成功逻辑
            this.$message.success('登录成功');
            // 跳转到主页
            this.$router.push('/');
          }).catch(error => {
            // 处理登录失败逻辑
            this.$message.error(error.message);
          });
        }
      });
    }
  }
};
</script>

3. 调用 API 接口

前端使用 Axios 等工具封装 API 请求,在组件的事件处理函数中调用这些 API 接口,将用户输入的数据作为参数发送给后端。在上述登录示例中,handleLogin 方法调用了 login API 接口。

import request from '@/utils/request';

export function login(data) {
  return request({
    url: '/login',
    method: 'post',
    data
  });
}

4. 处理响应数据

前端接收到后端返回的响应数据后,根据响应状态码和数据内容进行相应的处理。如果登录成功,显示成功提示信息并跳转到主页;如果登录失败,显示错误提示信息。

后端流程

1. 接收请求

后端使用 Spring Boot 框架,通过控制层(Controller 层)接收前端发送的请求。在若依系统中,使用 @RestController 和 @RequestMapping 等注解来定义接口。

package com.ruoyi.system.controller;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.service.ISysLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/")
public class SysLoginController extends BaseController {

    @Autowired
    private ISysLoginService sysLoginService;

    @PostMapping("/login")
    public AjaxResult login(@RequestBody Map<String, String> loginBody) {
        String username = loginBody.get("username");
        String password = loginBody.get("password");
        // 调用业务逻辑层进行登录处理
        String token = sysLoginService.login(username, password);
        return AjaxResult.success(token);
    }
}

2. 调用业务逻辑层(Service 层)

控制层接收到请求后,调用业务逻辑层(Service 层)的方法进行业务处理。在登录示例中,SysLoginController 调用了 ISysLoginService 的 login 方法。

package com.ruoyi.system.service;

public interface ISysLoginService {
    String login(String username, String password);
}
package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

@Service
public class SysLoginServiceImpl implements ISysLoginService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public String login(String username, String password) {
        // 进行身份验证
        Authentication authentication = null;
        try {
            authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (BadCredentialsException e) {
            throw new RuntimeException("用户名或密码错误");
        }
        // 生成令牌
        String token = generateToken(authentication);
        return token;
    }

    private String generateToken(Authentication authentication) {
        // 生成令牌的具体逻辑
        return "generated_token";
    }
}

3. 调用数据访问层(DAO 层)

业务逻辑层可能需要从数据库中获取数据,这时会调用数据访问层(DAO 层)的方法。在若依系统中,通常使用 MyBatis - Plus 来实现数据访问。例如,在用户验证过程中,可能需要查询数据库中的用户信息。

package com.ruoyi.system.mapper;

import com.ruoyi.system.domain.SysUser;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface SysUserMapper {
    SysUser selectUserByUsername(String username);
}

4. 处理业务逻辑

业务逻辑层根据业务需求对数据进行处理,比如进行用户验证、权限检查、数据计算等。在登录示例中,SysLoginServiceImpl 会对用户输入的用户名和密码进行验证,并生成令牌。

5. 返回响应结果

业务逻辑处理完成后,将处理结果返回给控制层,控制层将结果封装成合适的响应格式(如 JSON)返回给前端。在登录示例中,SysLoginController 将生成的令牌封装在 AjaxResult 中返回给前端。

前后端交互总结

整个前后端交互流程可以概括为:前端用户操作触发请求,调用 API 接口将请求发送给后端;后端控制层接收请求,调用业务逻辑层进行业务处理,业务逻辑层可能会调用数据访问层获取数据;业务逻辑处理完成后,结果返回给控制层,控制层将响应结果返回给前端;前端接收到响应后,根据结果进行相应的处理和展示。通过这种方式,实现了前后端的高效协作和数据交互。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐