前台:用户能操作的页面。后台:用户看不到,只能管理员,维修人员,开发者能操作的页面。前端:使用前端技术开发,页面的开发为前端 。后端:使用后端技术进行开发。前台,后台管理系统都有前端和后端组成。
在实体类中添加自动填充,时间会自动添加和更新。
mybatisplus的乐观锁
乐观锁就是为了解决,丢失更新的问题,丢失更新:多个人同时修改同一条记录,最后提交的把之前提交的数据覆盖。
使用乐观锁主要是,添加一个字段version,在修改数据时version由1变为2,然后数据库的数据版本为1,然后修改的时候比较版本号,一致就可以修改版本然后加1,否则不能修改。在实体类中针对版本号加上@version。然后在配置类中配置乐观锁插件,使用乐观锁时,需要进行先查询数据然后再修改数据,这样version值才会增加。
针对逻辑删除,他是假删除,物理删除是真删除,实现逻辑删除主要是依据@TableLogic,在一个字段上加上这个注解就是依据这个字段来实现逻辑删除,这个字段默认初始为0,在配置类中配置逻辑删除插件。
前后端分离开发
前端使用ajax操作调用后端接口(这个接口更多是以controller和service,mapper形成的)。针对mp自带的代码生成器,引入依赖velocity-engine-core,其中有一个测试类,是专门生成代码文件,或者逆向工程生成代码,从数据库获取信息后直接生成代码。
@RestController
是@controller和@ResponseBody 的结合,@Controller 将当前修饰的类注入SpringBoot IOC容器,使得从该类所在的项目跑起来的过程中,这个类就被实例化。@ResponseBody 它的作用简短截说就是指该类中所有的API接口返回的数据,甭管你对应的方法返回Map或是其他Object,它会以Json字符串的形式返回给客户端。controller类中,在方法的属性列加中@PathVariable,是属于获取路径赋给的数值,然后再方法体中根据值进行操作。rest风格:每种操作使用到不同的请求方式或者说是提交方式,比如查询用get提交方式,添加用put提交方式,修改用post提交方式,删除用delete提交方式,这就是rest风格。
swagger的使用
生成api文档,同时能够测试接口请求api等。首先引入相关swagger依赖,然后再进行配置类中配置,在启动类中,如果这个配置类不是在启动类的子级目录,那么就加上@ComponentScan来扫描配置类,然后启动,输入路径http://localhost:8001/swagger-ui.html,一般情况下,生成的文档更多是controller类中可执行的方法。
统一结果返回
一般情况返回的是JSON格式,json数据格式有两种:对象和数组,对象是大括号,数组是中括号
分页
首先,加入一个分页插件,此插件是mp自带的,在配置类中配置。然后new page,直接可以使用创建的分页对象。针对实现复杂查询,使用更多是querywrapper。
都是基于mp进行分页,两种分页方法:一种是先在配置类中配置分页插件,手动设置分页条件
设置条件的查询方式有,可以先设置要查询的条件类,然后使用这个类在querywrapper进行实现。
第二种就是为了响应前端页面的数据
统一异常处理
全局异常处理,只要出现异常都会执行这个方法,创建一个类,加上注解@ControllerAdvice在类的体里加上注解 @ExceptionHandler(Exception.class)。如果有特殊异常处理,针对特定异常,只是改变了注解@ExceptionHandler(ArithmeticException.class),注解这个就是特殊异常处理。会先执行这个特殊的,还有自定义异常处理,这个自定义异常,首先创建一个类继承这个RuntimeException,在这个类中定义属性,比如code,message等,然后在另一个类中创建一个方法,方法是自定义异常处理方法,方法属性是创建的这个自定义类,自定义异常不是前面一样自动运行,需要最后在controller类中try catch后使用throw出自定义异常类的对象。
统一日志
日志记录器(Logger)的行为是分等级的,如下所示:
分为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL
默认情况下spring boot从控制台打印出来的日志级别只有INFO及以上级别。
vue相关
ES6,是一种规范,而JavaScript更好的遵循实现了这个规范。
常见基本语法:①let定义变量
// var 声明的变量没有局部作用域
// let 声明的变量 有局部作用域
// var 可以声明多次
// let 只能声明一次
②const声明常量(只读变量)
// 1、声明之后不允许改变
// 2、一但声明必须初始化,否则会报错
③解构赋值
解构赋值是对赋值运算符的扩展。他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。也方便了复杂对象中数据字段获取。
//1、数组解构
// 传统
let a = 1, b = 2, c = 3
console.log(a, b, c)
// ES6
let [x, y, z] = [1, 2, 3]
console.log(x, y, z)
//2、对象解构
let user = {name: 'Helen', age: 18}
// 传统
let name1 = user.name
let age1 = user.age
console.log(name1, age1)
// ES6
let {name, age} = user//注意:结构的变量必须是user中的属性
console.log(name, age)
④模板字符串
模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。
// 1、多行字符串
let string1 = `Hey,
can you stop angry now?`
console.log(string1)
// Hey,
// can you stop angry now?
// 2、字符串中调用函数
function f(){
return "have fun!"
}
let string2 = `Game start,${f()}`
console.log(string2); // Game start,have fun!
⑤声明对象简写
⑥定义方法简写
// 传统
const person1 = {
sayHi:function(){
console.log("Hi")
}
}
person1.sayHi();//"Hi"
// ES6
const person2 = {
sayHi(){
console.log("Hi")
}
}
person2.sayHi() //"Hi"
⑦对象拓展运算符
拓展运算符(…)用于取出参数对象所有可遍历属性然后拷贝到当前对象。
// 1、拷贝对象
let person1 = {name: "Amy", age: 15}
let someone = { ...person1 }
console.log(someone) //{name: "Amy", age: 15}
⑧箭头函数
箭头函数提供了一种更加简洁的函数书写方式。基本语法是:
参数 => 函数体
箭头函数多用于匿名函数的定义
// 传统
var f1 = function(a){
return a
}
console.log(f1(1))
// ES6
var f2 = a => a
console.log(f2(1))
// 当箭头函数没有参数或者有多个参数,要用 () 括起来。
// 当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,
// 当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
var f3 = (a,b) => {
let result = a+b
return result
}
console.log(f3(6,2)) // 8
// 前面代码相当于:
var f4 = (a,b) => a+b
vue的相关使用:vue是一个用于构建用户界面的框架,当创建html文件时,也需要引入vue.js文件。
基本数据渲染和指令:v-bind特性被称为指令。是一个单向数据绑定,指令带有前缀v- ,除了使用插值表达式{{}}进行数据渲染,也可以使用 v-bind指令,它的简写的形式就是一个冒号(: )。<h1 v-bind:title="message">
{{content}}
</h1>
<!-- v-bind 指令的简写形式: 冒号(:) -->
<h1 :title="message">
{{content}}
</h1>
针对双向数据绑定,主要是v-model,使用它可以在页面修改数据时,显示效果也跟着改。
<input type="text" v-model="searchMap.keyWord">
vue事件的操作:事件绑定就是,常见的前端调用方法
<button v-on:click="search()">查询1</button>
<!-- vue绑定事件简写 -->
<button @click="search()">查询2</button>
修饰符 (Modifiers) 是以半角句号(.)指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。
例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():即阻止事件原本的默认行为。
组件的相关使用: el: '#app',
// 定义局部组件,这里可以定义多个局部组件
components: {
//组件的名字(随便起名)
'mxy': {
//组件的内容
template: '<ul><li>首页</li><li>学员管理</li></ul>'
}
}
<div id="app">
<mxy></mxy>
</div>
全局组件就是创建一个js文件,然后再js文件中自定义<mxy></mxy>,使用时引入这个自定义的js文件即可。
vue生命周期
created方法(在页面渲染之前执行)和mounted方法(在页面渲染之后执行)
路由
在html文件中引入<script src="vue-router.min.js"></script>,然后编写script标签内容,当运行html后会有跳转效果,通过不同url访问不同的内容。
axios:axios是独立的项目,不是vue里面的一部分,axios经常和vue一起使用,实现ajax操作,这个相关操作还是引入js文件 <script src="axios.min.js"></script>在前端中使用axios操作
node.js :简单来说node.js就是运行在服务端的JavaScript,我们学java时想要运行程序需要jdk环境。node.js对JavaScript的作用,就相当于jdk对java的作用:node.js是JavaScript的运行环境,用于执行JavaScript代码。我们前面都是将js文件引入到html页面中(如:<script src="vue.min.js"></script>),然后通过浏览器访问这个html页面才可以使得js文件执行,有了node.js后,不需要浏览器,直接使用node.js就可以运行JavaScript代码。Node.js下载安装后,进入要执行的js文件目录下打开cmd,然后输入命令 node 文件名.js就可以显示该js的内容。
npm:NPM全称Node Package Manager,是Node.js包管理工具,是全球最大的模块生态系统,里面所有的模块都是开源免费的;也是Node.js的包管理工具,管理前端js依赖,联网下载js依赖。相当于后端的Maven 。在vscode终端输入命令npm init初始化该文件夹为一个前端项目,最后npmdemo文件夹下有一个package.json文件,这个是包的配置文件,相当于maven的pom.xml。npm默认下载依赖在c盘,修改可以根据如下图,下载依赖的命令是npm install 依赖名称@版本号。
Babel
Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,为什么我们需要将ES6代码转为ES5代码呢?因为我们现在写的代码都是es6代码,但是es6代码浏览器兼容性很差,低版浏览器有很多es6代码都是不认识的。只要有箭头函数(参数 => 函数体)就一定是es6代码,因为箭头函数es5是没有的。下载转码器npm install --save-dev babel-preset-es2015@6.24.1,使用如下命令来完成"根据文件转码" , babel es6/01.js --out-file dist1/000001.js #下面这个命令是上面那个命令的简写 babel es6/01.js -o dist1/000001.js
前端模块化
类似我们开发后端接口(mapper、service、controller)时,在service注入mapper,在controller注入service,那么前端就是在01.js中写方法,然后表明什么方法可以被调用 module.exports = { 方法名 } 然后再02.js文件引入01.js,在02.js中写入下面代码就可以实现调用。有两种方式定义调用,第一种就是单个方法export定义
//在01.js中定义方法,并且设置哪些方法可以被其它js调用
export function getList() {
console.log('getList......')
}
第二种就是整体export定义
export default {
getList() {
console.log('getList......')
},
save() {
console.log('save......')
}
const m = require('./01.js')
m.01的方法名
如果使用es6写法实现模块化操作,在node.js环境中是不能直接运行的,需要使用babel把es6代码转换为es5代码,才可以在node.js中运行 。
webpack:Webpack是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。webpack的好处:Webpack 可以将多种静态资源 js、css、less 转换成一个静态文件,这就就减少了页面的请求次数。首先在终端中安装相关插件 npm install -g webpack@4.41.4 webpack-cli@3.3.2 然后创建webpack.config.js配置文件,文件内容大致为如下,需要注意,main.js中是引入了其他的js文件,所以打包main.js就可以了
const path = require("path"); //Node.js内置模块
module.exports = {
entry: './main.js', //配置入口文件
output: {
path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径
filename: 'bundle.js' //输出的文件的名字
}
}
最后就是在端口使用命令进行打包:webpack #有黄色警告 webpack --mode=development #没有警告 webpack --mode=production #没有警告
如果是打包css文件,那么需要在main.js中引入css文件,因为webpack只能打包js文件,所以再下载css相关插件 npm install --save-dev style-loader@1.1.3 css-loader@3.4.2,最后在webpack.config.js文件中配置css相关操作,最后打包还是上面的命令三个之一。
前端页面搭建
去官网下载后,使用vue-admin-template框架来进行环境搭建,把这个文件放入到项目里后,进入这个文件的终端使用npm install进行下载。下载完成后 npm run dev 运行,我们前端页面环境使用的vue-admin-template框架(模板)主要基于两种技术实现出来。就是vue-admin-template模板 = vue + element-ui。使用这个框架的基本目录结构:1.build目录:放项目构建的脚本文件(一般不用管这个目录) 2.config目录:基本配置信息 3.node_modules目录:存放下载的依赖 4.static目录:存放静态资源(一般不用管这个目录) 5.src目录
当运行后,其中index.js是导航栏,在这个文件中引入了路由,首先是登录,使用的页面是xx.vue页面显示,登录成功后显示该index.js的导航栏。当有路径跳转到xx.vue页面中,此时created方法中
this.$route.params
表示得到路由中的参数this.$route.params.id
表示得到路由中名字为id的参数
针对讲师列表的修改功能, 当点击修改时,此时的路由对应于index.js中自定义的path属性值,这是路由跳转,然后跳转到index.js后,就会接着跳转import引用的路径。数据回显的思路,当页面接收到跳转过来的路径的id值后,把值传入到方法,方法再进行查询数据库,查询时也要封装成一个整体对象返回,然后在前端找那返回对象。
$route(to, from){...}
是固定写法,表示路由变化方式,只要路由发生变化,该方法就会执行。这样的话,本来点击"修改"路由时在表单页面,再点击"添加讲师"路由,此时仍在表单页面,但是因为路由发生了变化,所以就会执行$route(to, from){...}
方法
注意:要注意mybatis plus模糊查询中文时,有数据但查不到,原因是application.properties中数据库没有配置&characterEncoding=utf-8。
使用更多的前端模版组件
在模版中vue-element-admin–>src–>components下有很多组件,复制进项目的components目录下后,在save.vue中写入相关的上传头像配置。
课程分类功能:
使用二级分类,也就是说一级分类的数据中的id是二级的id,假设id为1是张三,二级分类就是在在id为1下还有多条数据。
针对于easyExcel框架,使用先引入依赖,创建实体类作为一级分类,然后在测试类中进行测试。写入Excel是使用write方法,读取Excel数据,需要建立监听器类,在监听器中完成读取。课程分类在前端页面显示的效果,首先是要创建两个实体类,然后在实现类的方法中写出相关业务逻辑。
跨域问题:什么叫跨域:通过一个地址去访问另外一个地址,这个过程中如果①访问协议(http、https)、②ip地址、③端口号这三处只要有任何一处不一样,就叫做跨域。跨域问题的解决方式有很多种,简单列举两种:
- 在后端接口controller上添加注解@CrossOrigin(常用)
- 使用网关解决
阿里云oss对象存储:需要把内容存到一个所有人都能访问到的地方,这个地方就是对象存储oss:存到oss中的文件可以被别人访问。使用阿里云oss对象存储,创建一个模块,引入依赖aliyun-sdk-oss,然后创建properties配置文件,配置阿里云id和密钥,创建启动类,给启动类的注解@SpringBootApplication添加属性exclude = DataSourceAutoConfiguration.class
,该属性作用是:默认不加载数据库配置。创建一个常量类,常量类中获取properties文件的oss配置,然后设置实现类的具体oss操作,最后在controller类中调用这个实现类的方法
nginx相关:
请求转发
负载均衡
动静分离
我们在tomcat里面放了java代码部分,然后又专门找了个服务器放静态资源(html、图片…),当我们访问java代码时就去请求tomcat,当我们访问静态资源时就去请求我们的静态服务器
进入nginx所在目录运行cmd,使用命令nginx.exe启动nginx,如果看到光标在闪就说明启动成功,用命令nginx.exe -s stop关闭nginx,重启是 nginx.exe -s reload。
课程管理:
使用代码生成器,写出相关的控制器,和业务类,然后创建一个vo类封装需要的属性(包含两个表的部分属性合并一起),然后在业务实现类中使用二级分类学的类转换,分别把vo类的属性值添加到两个表中。
前台系统
服务端渲染技术NUXT
1.以前是客户端发送ajax请求给服务端,然后服务端返回数据给客户端。不利于网站进行SEO()
2.下面这种方式利于SEO:客户端请求服务端时,服务端的node.js会请求tomcat得到数据,得到数据后在node.js中把数据做封装,然后将数据一次性返回给客户端。
和ajax的区别是:ajax方式是客户端请求服务端的tomcat;而nuxt方式是服务端的node.js请求服务端的tomcat,客户端只负责显示数据,请求过程是通过node.js实现的,请求数据是发生在服务端而不像ajax那样那样发生在客户端。NUXT是对node.js的封装,所以我们这里使用NUXT框架来搭建前台系统。Nuxt.js 是一个基于 Vue.js 的通用应用框架,具有静态文件服务、热加载、服务端渲染等特性。项目的前台的前端项目使用的NUXT框架只基于vue实现,本身并没有集成element-ui,如果我们想使用element-ui就需要将element-ui引入过来。
在vue页面中实现动态跳转,需要动态路由就是:每次生成的路由地址不一样,比如课程详情,如果我们需要根据id查询一条记录,就需要使用动态路由。NUXT的动态路由是以下划线开头的vue文件,参数名为下划线后边的文件名,如_id.vue。
token:按照一定规则(规则不是固定的,我们可以根据需求制定规则)生成的字符串,这个字符串中可以包含用户信息
比如说我们制定的规则是:ip+用户名+用户年龄,假设是192.1.1.1lucy22,然后我们将这串字符进行base64编码,再做一个加密,最后就得到了token字符串,具体实现:1.在项目的任意一个模块进行登录后,我们按照一定规则生成一个token字符串,要求这个字符串中包含用户信息,然后将这个字符串进行返回(两种方式返回:把字符串通过cookie返回、把字符串通过地址栏返回)。JWT就是给我们制定好了规则,我们使用JWT规则可以生成token字符串,且这个字符串中包含用户信息。
springsecurity
认证授权过程
springico容器
OAuth2
他是一个授权框架,使应用程序能够访问其它公司提供的资源,比如腾讯、阿里、华为等公司的开放平台。
微服务相关
微服务介绍
- 微服务是架构风格
- 把一个项目拆分成独立的多个服务,多个服务是独立运行,每个服务占用独立进程(我们前面的8001、8002、8003端口就是这样的)
-
注册中心介绍:如果我们想要实现不同的微服务模块之间的调用,就需要把这些模块在注册中心进行注册,这样一个模块服务可以调用另一个模块服务的方法。常见的注册中心有zookeeper和nacos以及Consul(原生,GO语言开发)
- 注册时用到模块的ip和端口号
- 生产者就是提供方法的;消费者就是调用方法的。我们需要实现在service_edu模块调用service_vod模块的方法,那么此时service_edu就是消费者;service_vod就是生产者。
nacos使用:直接使用资料下载的文件夹,在文件夹中有cmd,直接运行,然后访问,访问地址是:http://localhost:8848/nacos 账号密码都是nacos,然后就是引入nacos依赖,在service_edu的配置文件application.properties中配置nacos地址(即nacos的ip和端口号),在service_edu的启动类中添加Nacos客户端注解@EnableDiscoveryClient
,目的是让注册生效。生产者和消费者都是这样操作,然后登录nacos查看两个注册。实现服务之间的调用需要用到Spring Cloud中的组件Feign,在消费方创建接口,接口里引入消费方的名称和定义另一个服务的方法路径,在消费方的控制器类中注入刚创建的接口,然后使用接口调用定义的方法。在nacos中注册服务,分别起个各自服务的名字,在消费者服务模块中的启动类加上这个注解,然后在消费者接口中加注解同时加上生产者服务名字,接着在接口中写你要调用的生产者的某个方法。最后在消费者某个方法中注入这个接口,使用注入的对象直接调用方法。
在消费者服务模块中创建一个接口
redis整合
redis有五种数据类型:string,hash,list,set,sorted set。
持久化:通过内存进行存储,不过也可以存到硬盘里面去
- 为什么要通过内存进行存储呢?存到内存中读取速度快,如果存到硬盘中读取时还要进行io操作,读取速度很慢
在Windows中使用redis
仅是针对终端使用,如果在cmd中,先启动redis-server,然后再启动redis-cli,在redis-cli终端窗口操作相关命令。
仅是针对桌面可视化使用,使用redis-desktop工具。
如果是集成java使用,在pom文件导入data-redis相关依赖,在yml文件中配置连接端口和密码,然后再创建一个的配置类,配置类继承CachingConfigurerSupport类,最后使用时需要注入RedisTemplate,使用这个自带的set和get方法。
如果是常规的使用,首先是对于实体类,要加上@RedisHash,这是命名redis名字,然后创建一个接口继承CrudRepository接口,在测试类中中使用相关接口自带的save方法就可以保存到redis中。
在Linux中使用redis:进入图形化界面后进入root用户,使用wget http://download.redis.io/releases/redis-7.0.0.tar.gz首先下载相关的redis,然后解压缩(注意:虚拟机镜像主要有两个,centos和Ubuntu,其中Ubuntu自带图形化界面,centos需要安装时再选择安装图像化界面。)
基于注解使用redis:1.@Cacheable注解:根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。2.@CachePut注解:使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。3.@CacheEvict注解:使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上。然后在配置文件中配置虚拟机的ip和端口号。在虚拟机中打开redis,查看键值信息。
Linux常见命令:Linux系统终端vi编辑器命令(1)_linuxvi编辑器命令_缓慢前进的小尘的博客-CSDN博客