

启动Navicat,创建mysql连接
(1)明确建模目标(模型覆盖范围)
(2)定义实体集(自底向上标识和定义实体集)
(3)定义联系(实体间关联关系)
(4)建立信息模型(构造ER模型)
(5)确定实体集属性(属性描述一个实体集的特征或性质)
(6)对信息模型进行集成与优化(检查和消除命名不一致、结构不一致等)



(1)用户信息表
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
| id | bigint | 20 | 0 | 是 | 主键 |
| name | varchar | 50 | 否 | 姓名 | |
| phone | varchar | 100 | 否 | 手机号 | |
| sex | varchar | 2 | 否 | 性别 | |
| id_number | varchar | 18 | 否 | 身份证号 | |
| avatar | varchar | 500 | 否 | 头像 | |
| status | int | 11 | 0 | 否 | 状态(0:禁用;1:正常) |



●log对象的四个方法
| 方法名 | 作用 |
| info() | 输出普通信息 |
| debug() | 输出调试信息 |
| error() | 输出错误信息 |
| warn() | 输出警告信息 |

reggie,字符集采用utf8mb4



(五)查看数据库中的表

两种常用项目构建工具

创建Maven项目,配置项目信息


创建完项目之后,我们应该检查项目编码、maven仓库配置以及jdk配置

安装maven软件

配置maven的环境变量

检验maven环境变量是否配置成功

在maven配置文件添加阿里镜像源

检查IntelliJ IDEA里maven仓库的配置

检查jdk配置情况



在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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/>
</parent>
<groupId>net.hw</groupId>
<artifactId>ReggieTakeOut</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.14</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.4</version>
</plugin>
</plugins>
</build>
</project>
在resources目录下创建应用属性文件 - application.yml

mybatis-plus的IdType枚举类型 - 定义生成ID的类型

在设置对话框里找到plugins,搜索lombok,单击绿色的Install按钮

单击绿色的Restart IDE按钮

创建net.hw包,然后在包里创建ReggieTakeOutApplication类

(七)拷贝静态资源和模板页面
(八)创建MVC配置类,做静态资源映射





4. 后台登录功能开发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>瑞吉外卖管理端</title>
<link rel="shortcut icon" href="../../favicon.ico">
<!-- 引入样式 -->
<link rel="stylesheet" href="../../plugins/element-ui/index.css" />
<link rel="stylesheet" href="../../styles/common.css">
<link rel="stylesheet" href="../../styles/login.css">
<link rel="stylesheet" href="../../styles/icon/iconfont.css" />
<style>
.body{
min-width: 1366px;
}
</style>
</head>
<body>
<div class="login" id="login-app">
<div class="login-box">
<img src="../../images/login/login-l.png" alt="">
<div class="login-form">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" >
<div class="login-form-title">
<img src="../../images/login/logo.png" style="width:139px;height:42px;" alt="" />
</div>
<el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号" maxlength="20"
prefix-icon="iconfont icon-user" />
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginForm.password" type="password" placeholder="密码" prefix-icon="iconfont icon-lock" maxlength="20"
@keyup.enter.native="handleLogin" />
</el-form-item>
<el-form-item style="width:100%;">
<el-button :loading="loading" class="login-btn" size="medium" type="primary" style="width:100%;"
@click.native.prevent="handleLogin">
<span v-if="!loading">登录</span>
<span v-else>登录中...</span>
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="../../plugins/vue/vue.js"></script>
<!-- 引入组件库 -->
<script src="../../plugins/element-ui/index.js"></script>
<!-- 引入axios -->
<script src="../../plugins/axios/axios.min.js"></script>
<script src="../../js/request.js"></script>
<script src="../../js/validate.js"></script>
<script src="../../api/login.js"></script>
<script>
new Vue({
el: '#login-app',
data() {
return {
loginForm:{
username: 'admin',
password: '123456'
},
loading: false
}
},
computed: {
loginRules() {
const validateUsername = (rule, value, callback) => {
if (value.length < 1 ) {
callback(new Error('请输入用户名'))
} else {
callback()
}
}
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error('密码必须在6位以上'))
} else {
callback()
}
}
return {
'username': [{ 'validator': validateUsername, 'trigger': 'blur' }],
'password': [{ 'validator': validatePassword, 'trigger': 'blur' }]
}
}
},
created() {
},
methods: {
async handleLogin() {
this.$refs.loginForm.validate(async (valid) => {
if (valid) {
this.loading = true
let res = await loginApi(this.loginForm)
if (String(res.code) === '1') {
localStorage.setItem('userInfo',JSON.stringify(res.data))
window.location.href= '/backend/index.html'
} else {
this.$message.error(res.msg)
this.loading = false
}
}
})
}
}
})
</script>
</body>
</html>


(四)数据模型 - 雇员表
代码开发
(一)创建雇员实体类
package net.hw.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 功能:雇员实体类
* 作者:华卫
* 日期:2022年11月03日
*/
@Data // Lombok注解,注在类上,提供类的get、set、equals、hashCode、canEqual、toString方法
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String name;
private String password;
private String phone;
private String sex;
private String idNumber; // 对应字段 - id_number
private Integer status;
private LocalDateTime createTime; // 对应字段 - create_time
private LocalDateTime updateTime; // 对应字段 - update_time
@TableField(fill = FieldFill.INSERT) // mybatis-plus注解,填充策略
private Long createUser; // 对应字段 - create_user
@TableField(fill = FieldFill.INSERT_UPDATE) // mybatis-plus注解,填充策略
private Long updateUser; // 对应字段 - update_user
}
(二)创建雇员映射器接口

package net.hw.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.hw.entity.Employee;
import org.apache.ibatis.annotations.Mapper;
/**
* 功能:雇员映射器接口
* 作者:华卫
* 日期:2022年11月03日
*/
@Mapper // 交给Spring容器来管理
public interface EmployeeMapper extends BaseMapper<Employee> {
}
(三)创建雇员服务

package net.hw.service;
import com.baomidou.mybatisplus.extension.service.IService;
import net.hw.entity.Employee;
/**
* 功能:雇员服务接口
* 作者:华卫
* 日期:2022年11月03日
*/
public interface EmployeeService extends IService<Employee> {
}

package net.hw.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.hw.entity.Employee;
import net.hw.mapper.EmployeeMapper;
import net.hw.service.EmployeeService;
import org.springframework.stereotype.Service;
/**
* 功能:雇员服务接口实现类
* 作者:华卫
* 日期:2022年11月03日
*/
@Service // 交给Spring容器管理
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee>
implements EmployeeService {
}
(四)创建返回结果类


package net.hw.common;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data // Lombok注解,精简代码
public class R<T> {
private Integer code; // 编码:1成功,0和其它数字为失败
private String msg; // 错误信息
private T data; // 数据
private Map map = new HashMap(); // 动态数据
public static <T> R<T> success(T object) {
R<T> r = new R<T>();
r.data = object;
r.code = 1;
return r;
}
public static <T> R<T> error(String msg) {
R r = new R();
r.msg = msg;
r.code = 0;
return r;
}
public R<T> add(String key, Object value) {
this.map.put(key, value);
return this;
}
}
(五)创建雇员控制器


package net.hw.controller;
import lombok.extern.slf4j.Slf4j;
import net.hw.common.R;
import net.hw.entity.Employee;
import net.hw.service.EmployeeService;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@Slf4j // 日志注解
@RestController // 交给Spring容器管理
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {
return null;
}
}
1、将页面提交的密码password进行md5加密处理
2、根据页面提交的用户名username查询数据库
3、如果没有查询到则返回登录失败结果
4、密码比对,如果不一致则返回登录失败结果
5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果
6、登录成功,将员工id存入Session并返回登录成功结果



三、功能测试

(三)采用调试模式启动应用

(四)测试登录 - 成功



四、哈希加密


# 哈希加密是单向加密
# 导入加密模块
import hashlib
# 采用md5加密算法
obj = hashlib.md5()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('md5加密字符长度:{}'.format(len(cryptotext)))

# 哈希加密是单向加密
# 导入加密模块
import hashlib
# 采用sha256加密算法
obj = hashlib.sha256()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('sha256加密字符长度:{}'.format(len(cryptotext)))

# 哈希加密是单向加密
# 导入加密模块
import hashlib
# 采用sha512加密算法
obj = hashlib.sha512()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('sha512加密字符长度:{}'.format(len(cryptotext)))

# 哈希加密是单向加密
# 导入加密模块
import hashlib
# 采用sha1加密算法
obj = hashlib.sha1()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('sha1加密字符长度:{}'.format(len(cryptotext)))

# 哈希加密是单向加密
# 导入加密模块
import hashlib
# 采用sha224加密算法
obj = hashlib.sha224()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('sha224加密字符长度:{}'.format(len(cryptotext)))

5. 后台退出功能开发



二、代码开发


(二)编写代码


package net.hw.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import net.hw.common.R;
import net.hw.entity.Employee;
import net.hw.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* 功能:雇员控制器类
* 作者:华卫
* 日期:2022年11月03日
*/
@Slf4j // 日志注解
@RestController // 交给Spring容器管理
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {
// 1. 将页面提交的密码password进行md5加密处理
String password = employee.getPassword();
password = DigestUtils.md5DigestAsHex(password.getBytes());
// 2. 根据页面提交的用户名username查询数据库
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>(); // 查询包装器
queryWrapper.eq(Employee::getUsername, employee.getUsername()); // 等值查询
Employee emp = employeeService.getOne(queryWrapper); // 按查询包装器进行查询
// 3. 如果没有查询到则返回登录失败结果
if (emp == null) {
return R.error("登录失败[用户名错误]");
}
// 4. 密码比对,如果不一致则返回登录失败结果
if (! emp.getPassword().equals(password)) {
return R.error("登录失败[密码错误]");
}
// 5. 查看员工状态,如果为已禁用状态,则返回员工已禁用结果
if (emp.getStatus() == 0) {
return R.error("登录失败[账号已禁用]");
}
// 6. 登录成功,将员工id存入Session并返回登录成功结果
HttpSession session = request.getSession(); // 通过请求对象获取会话
session.setAttribute("employee", emp.getId()); // 将雇员id保存到会话里
return R.success(emp); // 返回登录成功结果
}
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request) {
// 清除雇员信息
request.getSession().removeAttribute("employee");
// 返回成功结果
return R.success("退出成功");
}
}

我已经开始学习Ruby,我已经阅读了一些教程,甚至还买了一本书(“ProgrammingRuby1.9-ThePragmaticProgrammers'Guide”),我遇到了一些以前从未见过的新东西使用我知道的任何其他语言(我是一名PHP网络开发人员)。block和过程。我想我明白它们是什么,但我不明白的是为什么它们如此伟大,以及我应该在何时何地使用它们。我到处都看到他们说block和过程是Ruby中的一个很棒的特性,但我不理解它们。这里有人能给像我这样的Ruby新手一些解释吗? 最佳答案 block有很多好处。电梯演讲:bloc
rails中View的解析过程是怎样的?我对View中erb标记中原始html与ruby代码的解析顺序部分感兴趣。我认为这是View代码被解析并最终发送给请求者的顺序:Controller调用ViewView代码从上到下解析当Rails在解析过程中遇到erb标记时:rails解析它并将结果附加到解析的html(这包括erb标签引用助手)一旦整个View被解析,整体结果将发送给请求者这似乎并非如此。看来View代码会扫描任何erb片段并首先解析那些片段(包括对助手的引用)。之后,rails然后从上到下解析所有View代码并将结果发送给请求者。以这个View为例:#_form.html
快速导航(持续更新中…)Cesium源码解析一(terrain文件的加载、解析与渲染全过程梳理)Cesium源码解析二(metadataAvailability的含义)Cesium源码解析三(metadata元数据拓展中行列号的分块规则解析)Cesium源码解析四(Quantized-Mesh(.terrain)格式文件在CesiumJS和UE中加载情况的对比)目录1.前言2.本篇的由来3.terrain文件的加载3.1更新环境3.2更新和执行渲染命令3.3数据优化3.4结束当前帧4.总结1.前言 目前市场上三维比较火的实现方案主要有两种,b/s的方案主要是Cesium,c/s的方案主要是u
美团外卖搜索工程团队在Elasticsearch的优化实践中,基于Location-BasedService(LBS)业务场景对Elasticsearch的查询性能进行优化。该优化基于Run-LengthEncoding(RLE)设计了一款高效的倒排索引结构,使检索耗时(TP99)降低了84%。本文从问题分析、技术选型、优化方案等方面进行阐述,并给出最终灰度验证的结论。1.前言最近十年,Elasticsearch已经成为了最受欢迎的开源检索引擎,其作为离线数仓、近线检索、B端检索的经典基建,已沉淀了大量的实践案例及优化总结。然而在高并发、高可用、大数据量的C端场景,目前可参考的资料并不多。因此
TCP是面向连接的协议,连接的建立和释放是每一次面向连接的通信中必不可少的过程。TCP连接的管理就是使连接的建立和释放都能正常地进行。三次握手TCP连接的建立—三次握手建立TCP连接①若主机A中运行了一个客户进程,当它需要主机B的服务时,就发起TCP连接请求,并在所发送的分段中用SYN=1表示连接请求,并产生一个随机发送序号x,如果连接成功,A将以x作为其发送序号的初始值:seq=x。主机B收到A的连接请求报文,就完成了第一次握手。客户端发送SYN=1表示连接请求客户端发送一个随机发送序号x,如果连接成功,A将以x作为其发送序号的初始值:seq=x②主机B如果同意建立连接,则向主机A发送确认报
听说PostgreSQL的可以用Ruby写存储过程但我一直没能找到更多关于它的信息,教人们如何实际去做。有人可以为此推荐好的资源。谢谢 最佳答案 显然,您需要安装PL/Ruby。之后,你可以写:CREATEFUNCTIONruby_max(int4,int4)RETURNSint4AS'ifargs[0].to_i>args[1].to_ireturnargs[0]elsereturnargs[1]end'LANGUAGE'plruby';查看其GitHubrepository安装说明。
我是Ruby新手。我正在学习ruby中的抽象原则。据我了解,过程抽象是对用户隐藏实现细节,或者只是专注于要点而忽略细节。我关心的是如何实现它1)是不是一个简单的函数调用就这样#functiontosortarray#@paramsarray[Array]tobesortdefmy_sort(array)returnarrayifarray.sizearray[i+1]array[i],array[i+1]=array[i+1],array[i]swapped=trueendendendarrayend然后这样调用sorted_array=my_sort([12,34,123,43,
我正在尝试找到一种更好的方法将IRB与我的常规ruby开发集成。目前我很少在我的代码中使用IRB。我只用它来验证语法或尝试一些小的东西。我知道我可以将我自己的代码加载到ruby中作为一个require'mycode'但这通常不符合我的编程风格。有时我要检查的变量超出范围或在循环内。有没有一种简单的方法可以启动我的脚本并在IRB内的某个点卡住?我想我正在寻找一种更简单的方法来调试我的ruby代码而不破坏我的F5(编译)键。也许有经验的ruby开发者可以和我分享一个更精简的开发方法。 最佳答案 安装ruby-debugg
为什么带有splat参数的Ruby(2.0)过程/block的行为与方法和lambda不同?deffoo(ids,*args)pidsendfoo([1,2,3])#=>[1,2,3]bar=lambdado|ids,*args|pidsendbar.call([1,2,3])#=>[1,2,3]baz=procdo|ids,*args|pidsendbaz.call([1,2,3])#=>1defqux(ids,*args)yieldids,*argsendqux([1,2,3]){|ids,*args|pids}#=>1这是对此行为的确认,但没有解释:http://makandra
我正在尝试创建一个haml模板,该模板使用我的ruby应用程序中的一些数据来填充一些内容。是否可以将参数传递给haml以使其正确呈现?以下是我获取haml模板并呈现它的方式:template=File.open('path/to/template.haml')html=Haml::Engine.new(template.read).render那么,是否可以将对象从本地Ruby脚本传递到模板文件中,以便正确呈现页面?或者,我可以让haml文件拉入对象吗?如果这不起作用,我唯一的其他想法是将模板构建为本地字符串,这对我来说似乎更乏味。那么,是否有一种不同的编码模式可以更有效地完成这项