Django学习day09随堂笔记
每日测验
"""
今日考题:
1.choices参数的应用场景有哪些,如何获取该字段的值
2.django是什么模型的框架,简述MTV与MVC模型
3.多对多表关系有几种创建方式,各有什么特点?
4.什么是ajax,请手写出ajax的基本语法结构及重要参数含义
"""
昨日内容回顾
在django部分,如果你写代码的时候报错了
"""
1.pycharm窗口提示,前端console界面
2.仔细核对代码(单词写错写多)
3.浏览器缓存没有清除
4.端口号可能冲突了,一直跑的是之前的项目
5.重启你的计算机
(自己学会百度搜索问题,出现bug千万不要慌 要冷静分析 自己想出一个排查思路)
"""
图书管理系统图书的增删改查
"""
将你之前所学的知识点尽量全部都用上(每个人都应该自己能够独立的完成)
"""
choices参数
"""
在设计表的时候 针对可以列举完全的可能性字段
一般都是用choices参数
"""
gender_choices = ((1,'male'),(2,'female'),(3,'others'))
gender = models.IntegerField() # 针对具有choices参数的字段 存储数据的时候还是按照字段本身的数据类型存储没有其他的约束,但是如果你存的字段在你列举的范围内 那么可以自动获取对应关系
user_obj.gender # 数字
user_obj.get_gender_display() # 固定格式 get_choices参数字段名_display()
"""有对应关系就拿对应关系,没有则还是数据本身不会报错""" # 自己看看一些模型表的设计 体会choices参数的使用
MTV与MVC模型
"""
django自称是MTV框架,但是它的本质其实还是MVC
"""
多对多三种创建方式
# 全自动(本地测试用这个比较方便)
authors = models.ManyToManyField(to="Author")
# 自动创建第三张关系表 扩展性差 add,remove,clear,set # 纯手动(基本不用)
# 自己创建第三张表 自己建外键
# 扩展性高 但是无法利用orm简便的查询方法了 # 半自动(实际项目用这个,扩展性好)
class Book(models.Model):
authors = models.ManyToManyField(to="Author",
through='Book2Author',
through_fields=('book','author')
)
class Author(models.Model):
books = models.ManyToManyField(to="Author",
through='Book2Author',
through_fields=('author','book')
)
class Book2Author(models.Model):
book = 外键()
author = 外键()
"""
第三张关系表 还是需要你自己手动建
但是你可以告诉django orm可以使用orm简便查询方法
"""
ajax
"""
异步提交
局部刷新 参考案例:github注册实时获取用户名发送给后端确认并动态展示校验结果(页面不刷新)
复习:input框实时监测事件 input事件 我们学的是jQuery版本的ajax,所以你必须要确保html页面已经提前加载了jQuery
"""
# ajax基本语法
$.ajax({
url:'', # 朝后端哪个地址发送 跟action三种书写方式一致
type:'get/post', # 提交方式 默认get 跟form表单method参数一致
data:{'username':'jason','password':123}, # 要发送的数据
success:function(args){
# 异步回调处理机制
}
})
"""
当你在利用ajax进行前后端交互的时候
后端无论返回什么都只会被回调函数接受 而不再影响这个浏览器页面了
""" # 扩展 参数 代码发布项目还会涉及
dataType:'JSON'
"""
当后端是以HttpResponse返回的json格式的数据
默认是不会自动反序列化的
1.自己手动JSON.parse()
2.配置dataType参数
""" # 结论:写ajax的时候 你可以直接将dataType参数加上 以防万一 或者后端就用JsonResonse
$.ajax({
url:'', # 朝后端哪个地址发送 跟action三种书写方式一致
type:'get/post', # 提交方式 默认get 跟form表单method参数一致
dataType:'JSON',
data:{'username':'jason','password':123}, # 要发送的数据
success:function(args){
# 异步回调处理机制
}
})
今日内容概要
- 前后端传输数据的编码格式(contentType)
- ajax发送json格式数据
- ajax发送文件数据
- ajax结合sweetalert实现删除按钮的二次确认
- django自带的序列化组件(drf做铺垫)
- 批量插入
- 自己写一个分页器(只需要掌握分页器的推导思路即可)
- 自定义分页器的拷贝及使用
今日内容详细
前后端传输数据的编码格式(contentType)
# 我们主要研究post请求数据的编码格式
"""
get请求数据就是直接放在url后面的
url?username=jason&password=123
"""
# 可以朝后端发送post请求的方式
"""
1.form表单
2.ajax请求
"""
"""
前后端传输数据的编码格式
urlencoded
formdata
json
"""
# 研究form表单
默认的数据编码格式是urlencoded
数据格式:username=jason&password=123
django后端针对符合urlencoded编码格式的数据都会自动帮你解析封装到request.POST中
username=jason&password=123 >>> request.POST
如果你把编码格式改成formdata,那么针对普通的键值对还是解析到request.POST中而将文件解析到request.FILES中
form表单是没有办法发送json格式数据的
# 研究ajax
默认的编码格式也是urlencoded
数据格式:username=jason&age=20
django后端针对符合urlencoded编码格式的数据都会自动帮你解析封装到request.POST中
username=jason&age=20 >>> request.POST
ajax发送json格式数据
"""
前后端传输数据的时候一定要确保编码格式跟数据真正的格式是一致的
不要骗人家!!!
{"username":"jason","age":25}
在request.POST里面肯定找不到
django针对json格式的数据 不会做任何的处理
request对象方法补充
request.is_ajax()
判断当前请求是否是ajax请求 返回布尔值
"""
#前端
<script>
$('#d1').click(function (){
$.ajax({
url:'',
type:'post',
{#data:{'username':'kk',age:22},#}
data:JSON.stringify({'username':'kk',age:22}),
contentType:'application/json',
success:function (){
}
})
})
</script>
#后端
#ajax发送json格式数据
def ab_json(request):
#print(request.is_ajax())#判断当前请求是否为ajax
if request.is_ajax():
print(request.body) #b'{"username":"kk","age":22}' 拿到前端发送的二进制json格式的数据
#针对json格式数据需要你自己手动处理
json_bytes = request.body
#json_str = json_bytes.decode('utf-8') #先将二进制json数据转换成字符串
#json_dict = json.loads(json_str) #loads()是把其他类型的对象转为Python对象
#print(json_dict, type(json_dict)) # {'username': 'kk', 'age': 22} <class 'dict'>
#json.loads括号内如果传入了一个二进制格式的数据,那么内部可以自动解码然后再反序列化
json_dict = json.loads(json_bytes)
print(json_dict, type(json_dict)) #{'username': 'kk', 'age': 22} <class 'dict'>
return render(request,'ab_json.html')
"""
ajax发送json格式数据需要注意点
1.前端ajax中contentType参数指定成:application/json
2.数据是真正的json格式数据
3.django后端不会帮你处理json格式数据需要你自己去request.body获取并处理
"""
ajax发送文件
"""
ajax发送文件需要借助于js内置对象FormData
"""
#前端
<script>
//点击按钮朝后端发送普通键值对和文件数据
$('#d4').click(function (){
// 1.需要先利用FormData生成一个内置对象
let formDateObj = new FormData();
//2.添加普通的键值对
formDateObj.append('username',$('#d1').val())
formDateObj.append('password',$('#d2').val())
//3.添加文件对象
formDateObj.append('myfile',$('#d3')[0].files[0])
//4.将对象基于ajax发送给后端
$.ajax({
url:'',
type:'post',
data:formDateObj,//直接将对象放入data后面即可
//ajax发送文件必须要指定两个参数
contentType:false, //不需要使用任何编码 django后端能够自动识别formdata对象
processData: false, //告诉浏览器不要对你的数据进行任何处理
success:function (args){
}
})
})
</script>
#后端
#ajax发送文件
def ab_file(request):
if request.is_ajax():
if request.method == 'POST':
print(request.POST) #<QueryDict: {'username': ['kk'], 'password': ['123']}>
print(request.FILES) #<MultiValueDict: {'myfile': [<InMemoryUploadedFile: 01234.jpg (image/jpeg)>]}>
return render(request,'ab_file.html')
"""
总结:
1.需要利用内置对象FormData
// 2 添加普通的键值对
formDateObj.append('username',$('#d1').val());
formDateObj.append('password',$('#d2').val());
// 3 添加文件对象
formDateObj.append('myfile',$('#d3')[0].files[0])
2.需要指定两个关键性的参数
contentType:false, // 不需使用任何编码 django后端能够自动识别formdata对象
processData:false, // 告诉你的浏览器不要对你的数据进行任何处理
3.django后端能够直接识别到formdata对象并且能够将内部的普通键值自动解析并封装到request.POST中 文件数据自动解析并封装到request.FILES中
"""
django自带的序列化组件(drf做铺垫)
#序列化组件相关
import json
from django.http import JsonResponse
from django.core import serializers
def ab_ser(request):
user_queryset = models.User.objects.all()
# [{},{},{},{}]
# user_list = []
# for user_obj in user_queryset:
# tmp = {
# 'pk':user_obj.pk,
# 'username':user_obj.username,
# 'age':user_obj.age,
# 'gender':user_obj.get_gender_display()
# }
# user_list.append(tmp)
# return JsonResponse(user_list,safe=False)
"""
[
{"pk": 1,"username": "melo","age": 25,"gender": "male"},
{"pk": 2,"username": "masiwei","age": 26,"gender": "male"},
{"pk": 3,"username": "knowknow","age": 25,"gender": "male"},
{"pk": 4,"username": "周淑怡","age": 23,"gender": "female"},
{"pk": 5,"username": "咔咔","age": 24,"gender": "female"}
]
前后端分离的项目
作为后端开发的你只需要写代码将数据处理好
能够序列化返回给前端即可
再写一个接口文档 告诉前端每个字段代表的意思即可
"""
#如果对象数量过多 那么一个个的写 效率太过低 这个时候 serializers 就来了哦
#序列化
res = serializers.serialize('json',user_queryset)
"""会自动帮你将数据变成json格式的字符串 并且内部非常的全面"""
return HttpResponse(res)
""""
[
{
"model": "app01.user",
"pk": 1,
"fields": {
"username": "melo",
"age": 25,
"gender": 1
}
},
{
"model": "app01.user",
"pk": 2,
"fields": {
"username": "masiwei",
"age": 26,
"gender": 1
}
},
{
"model": "app01.user",
"pk": 3,
"fields": {
"username": "knowknow",
"age": 25,
"gender": 1
}
},
{
"model": "app01.user",
"pk": 4,
"fields": {
"username": "周淑怡",
"age": 23,
"gender": 2
}
},
{
"model": "app01.user",
"pk": 5,
"fields": {
"username": "咔咔",
"age": 24,
"gender": 2
}
}
]
写接口就是利用序列化组件渲染数据然后写一个接口文档 该交代交代一下就完事
"""
ajax结合sweetalert
自己要学会如何拷贝
学会基于别人的基础之上做修改
研究各个参数表示的意思 然后找葫芦画瓢
//前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
{# 动态引入第三方弹窗库#}
{% load static %}
<link rel="stylesheet" href="{% static '/dist/sweetalert.css' %}">
<script src="{% static 'dist/sweetalert.js' %}"></script>
<style>
{#当引用第三方弹窗库的时候 将警告文字换成中文的时候会有一个小bug #}
{#利用谷歌浏览器检查定位到出问题的元素 进行自定义位置的修改#}
div.sweet-alert h2{
padding-top:10px;
}
</style>
</head>
<body>
<div class="container-fluid">
<h1 class="text-center">用户数据展示</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<table class="table-striped table table-hover">
<thead>
<tr>
<th>ID</th>
<th>用户名</th>
<th>年龄</th>
<th>性别</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for user_obj in user_queryset %}
<tr>
<td>{{ user_obj.id }}</td>
<td>{{ user_obj.username }}</td>
<td>{{ user_obj.age }}</td>
<td>{{ user_obj.get_gender_display }}</td>
<td>
<button class="btn btn-primary btn-xs">编辑</button>
<button class="btn btn-danger btn-xs del" delete_id = "{{ user_obj.pk }}">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<script>
$('.del').click(function (){
//先将当前标签对象存储起来
let currentBtn = $(this);
//二次确认弹窗 先在上面引入第三方弹窗库 然后直接在官网上拷贝使用代码
// 下载第三方库放在自己的static文件夹中后 需要在setting里面设置一下 把这个文件夹暴露出去
swal({
title: "你确定要删吗?",
text: "你可要考虑清除,可能需要拎包跑路哦!",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn-danger",
confirmButtonText: "是的,老子就要删",
cancelButtonText: "算了算了,不删了",
closeOnConfirm: false,
closeOnCancel: false,
showLoaderOnConfirm: true {# 删除的等待时间 显示转圈圈 #}
},
function(isConfirm) {
if (isConfirm) {
//朝后端发送ajax请求删除数据后,再弹下面的提示框
$.ajax({
//url:"/delete/user/" + currentBtn.attr('delete_id'), //传递主键值方式1
url:'/delete/user/', //传递主键值方式2 放在请求体里
type: 'post',
data:{'delete_id':currentBtn.attr('delete_id')},
success:function (args){ //args={'code':'','msg':''}
//判断响应状态码 然后做不同的处理
if(args.code === 1000){
swal("删了!",args.msg,'success');
//1.lowb版本 直接刷新当前页面
//window.location.reload()
//2.利用DOM操作 动态刷新
currentBtn.parent().parent().remove()
}else {
swal('完了','出现未知的错误','info')
}
}
})
} else {
swal("怂比", "不要说我认识你", "error");
}
});
})
</script>
</body>
</html>
#后端逻辑
#用户展示页面
def user_list(request):
user_queryset = models.User.objects.all()
return render(request,'user_list.html',locals())
#删除用户
import time
def delete_user(request):
"""
前后端在用ajax进行交互的时候,后端通常给ajax的回调函数返回一个字典格式的数据
"""
if request.is_ajax():
if request.method == 'POST':
back_dic = {"code":1000,'msg':''}
time.sleep(3) #模拟操作数据的延迟
delete_id = request.POST.get('delete_id')
models.User.objects.filter(pk=delete_id).delete()
back_dic['msg'] = '数据已经删了,你赶紧跑路吧!'
#我们需要告诉前端我们操作的结果
return JsonResponse(back_dic)
批量插入
def ab_pl(request):
#先给顾客表插入50条数据
#速度太慢 前端加载的慢 用户体验感不好
# for i in range(50):
# models.Book.objects.create(title="第%s本书"%i)
# #再将所有的数据查询并展示到前端页面
# book_queryset = models.Book.objects.all()
# return render(request,'ab_pl.html',locals())
#批量插入 速度明显要比前面这种快的太多了 推荐使用
book_list = []
for i in range(50):
book_obj = models.Book(title='第%s本书'%i)
book_list.append(book_obj)
models.Book.objects.bulk_create(book_list)
book_queryset = models.Book.objects.all()
return render(request, 'ab_pl.html', locals())
"""
当你想要批量插入数据的时候 使用orm给你提供的bulk_create能够大大的减少操作时间
"""
分页器
"""
总数据100 每页展示10 需要10
总数据101 每页展示10 需要11
总数据99 每页展示10 需要10
如何通过代码动态的计算出到底需要多少页?
在制作页码个数的时候 一般情况下都是奇数个 符合中国人对称美的标准
"""
# 分页
book_list = models.Book.objects.all()
# 想访问哪一页
current_page = request.GET.get('page',1) # 如果获取不到当前页码 就展示第一页
# 数据类型转换
try:
current_page = int(current_page)
except Exception:
current_page = 1
# 每页展示多少条
per_page_num = 10
# 起始位置
start_page = (current_page - 1) * per_page_num
# 终止位置
end_page = current_page * per_page_num
# 计算出到底需要多少页
all_count = book_list.count()
page_count, more = divmod(all_count, per_page_num)
if more:
page_count += 1
page_html = ''
xxx = current_page
if current_page < 6:
current_page = 6
for i in range(current_page-5,current_page+6):
if xxx == i:
page_html += '<li class="active"><a href="?page=%s">%s</a></li>'%(i,i)
else:
page_html += '<li><a href="?page=%s">%s</a></li>'%(i,i)
book_queryset = book_list[start_page:end_page]
"""
django中有自带的分页器模块 但是书写起来很麻烦并且功能太简单
所以我们自己想法和设法的写自定义分页器
上述推导代码你无需掌握 只需要知道内部逻辑即可
我们基于上述的思路 已经封装好了我们自己的自定义分页器
之后需要使用直接拷贝即可
"""
自定义分页器的拷贝及使用
#已经封装好了的分页器代码 直接cv即可
class Pagination(object):
def __init__(self, current_page, all_count, per_page_num=10, pager_count=11):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page < 1:
current_page = 1
self.current_page = current_page
self.all_count = all_count
self.per_page_num = per_page_num
# 总页码
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager
self.pager_count = pager_count
self.pager_count_half = int((pager_count - 1) / 2)
@property
def start(self):
return (self.current_page - 1) * self.per_page_num
@property
def end(self):
return self.current_page * self.per_page_num
def page_html(self):
# 如果总页码 < 11个:
if self.all_pager <= self.pager_count:
pager_start = 1
pager_end = self.all_pager + 1
# 总页码 > 11
else:
# 当前页如果<=页面上最多显示11/2个页码
if self.current_page <= self.pager_count_half:
pager_start = 1
pager_end = self.pager_count + 1
# 当前页大于5
else:
# 页码翻到最后
if (self.current_page + self.pager_count_half) > self.all_pager:
pager_end = self.all_pager + 1
pager_start = self.all_pager - self.pager_count + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1
page_html_list = []
# 添加前面的nav和ul标签
page_html_list.append('''
<nav aria-label='Page navigation>'
<ul class='pagination'>
''')
first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
page_html_list.append(first_page)
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
page_html_list.append(prev_page)
for i in range(pager_start, pager_end):
if i == self.current_page:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
page_html_list.append(temp)
if self.current_page >= self.all_pager:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
page_html_list.append(next_page)
last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append('''
</nav>
</ul>
''')
return ''.join(page_html_list)
"""
当我们需要使用到非django内置的第三方功能或者组件代码的时候
我们一般情况下会创建一个名为utils文件夹 在该文件夹内对模块进行功能性划分
utils可以在每个应用下创建 具体结合实际情况
我们到了后期封装代码的时候 不再局限于函数
还是尽量朝面向对象去封装
我们自定义的分页器是基于bootstrap样式来的 所以你需要提前导入bootstrap
bootstrap 版本 v3
jQuery 版本 v3
"""
# 后端
book_queryset = models.Book.objects.all()
current_page = request.GET.get('page',1)
all_count = book_queryset.count()
# 1 传值生成对象
page_obj = Pagination(current_page=current_page,all_count=all_count)
# 2 直接对总数据进行切片操作
page_queryset = book_queryset[page_obj.start:page_obj.end]
# 3 将page_queryset传递到页面 替换之前的book_queryset
# 前端
{% for book_obj in page_queryset %}
<p>{{ book_obj.title }}</p>
<nav aria-label="Page navigation">
</nav>
{% endfor %}
{#利用自定义分页器直接显示分页器样式#}
{{ page_obj.page_html|safe }}
"""
你们只需要掌握如何拷贝使用 以及大致的推导思路即可
"""
### 作业
```python
"""
必做
1.整理今日内容到博客
2.熟练掌握ajax发送json数据和文件数据代码
3.自己完成按钮的二次确认操作(ajax+sweetalert)
4.尝试理解自定义分页器逻辑,自己推导出简易版本代码
选做
1.阅读博客,预习自定义分页器封装版本使用方式
"""
Django学习day09随堂笔记的更多相关文章
- Django学习day13随堂笔记
每日测验 """ 今日考题 1.什么是django中间件,它的作用是什么,如何自定义中间件,里面有哪些用户可以自定义的方法,这些方法有何特点 2.基于django中间件的 ...
- Django学习day02随堂笔记
每日测验 """ 今日考题 1.谈谈你对web框架的认识,简述web框架请求流程 2.python三大主流web框架的区别 3.安装django需要注意的事项有哪些(最少 ...
- Django学习day12随堂笔记
每日测验 """ 1.什么是cookie和session,你能描述一下它们的由来和工作机制吗(切勿糊弄,敷衍了事) 2.django中如何操作cookie和session ...
- Django学习day08随堂笔记
今日考题 """ 今日考题 1.聚合查询,分组查询的关键字各是什么,各有什么特点或者注意事项 2.F与Q查询的功能,他们的导入语句是什么,针对Q有没有其他用法 3.列举常 ...
- Django学习day07随堂笔记
今日考题 """ 今日考题 1.必知必会N条都有哪些,每个都是干啥使的 2.简述神奇的双下划线查询都有哪些方法,作用是什么 3.针对多对多外键字段的增删改查方法有哪些,各 ...
- Django学习day05随堂笔记
每日测验 """ 今日考题 1.反向解析的本质是什么,无名和有名反向解析如何操作? 2..路由分发能够实现的前提是什么,需要注意什么,名称空间什么时候使用 3..什么是虚 ...
- Django学习day11随堂笔记
今日考题 """ 今日考题 1.简述自定义分页器的使用 2.forms组件是干什么用的,它的主要功能有哪些功能,你能否具体说说每个功能下都有哪些经常用到的方法及注意事项( ...
- Django学习day10随堂笔记
每日测验 """ 今日考题 1.默写ajax基本语法,及提交json数据和文件都需要添加哪些额外参数 2.什么是序列化,截止目前为止你所接触过的序列化有哪些 3.批量插入 ...
- Django学习day06随堂笔记
每日测验 """ 今日考题 1.什么是FBV与CBV,能不能试着解释一下CBV的运作原理 2.模版语法的传值需要注意什么,常见过滤器及标签有哪些 3.自定义过滤器,标签, ...
随机推荐
- MySQL学习02(操作数据库)
操作数据库 结构化查询语句分类 名称 解释 命令 DDL(数据库定义语言) 定义和管理数据对象,例如数据库和数据表 create.drop.alter DML(数据操作语言) 用于操作数据库对象中所包 ...
- BaiduSpider:爬取百度的利器
视频链接:https://www.zhihu.com/zvideo/1272864710321516544 BaiduSpider是一个能够爬取百度搜索结果的Python爬虫,轻量但强大.目前支持百度 ...
- DVWA-全等级暴力破解
之前写了dvwa的sql注入的模块,现在写一下DVWA的其他实验步骤: 环境搭建参考:https://www.freebuf.com/sectool/102661.html DVWA简介 DVWA(D ...
- DAY04 与用户交 互格式化输出与运算符
与用户交互 输入: input # python2与python3的区别 # python3 res = input('please in put your username>>>& ...
- noip9
T1 本次考试最水的一道题,然而我sb,前一个小时,找了一大堆跟题目无关的性质,干脆打了个20pts的表,然后就走了,最后几分钟才看出来,匆匆码出来,结果段错误,然后考试就结束了. 好吧,段错误是UB ...
- Java使用Lettuce操作redis
maven包 # 包含了lettuce jar <dependency> <groupId>org.springframework.boot</groupId> & ...
- 06.SpringMVC之参数绑定
默认支持的参数类型一 HttpServletRequest .HttpServletResponse .HttpSession.java.security.Principal.Locale .Inpu ...
- Spring parent 属性
Spring Framework Reference Documentation 6.7. Bean definition inheritance 注:本文中bean和definition意思等同 该 ...
- Flink中的Time与Window
一.Time 在Flink的流式处理中,会涉及到时间的不同概念 Event Time(事件时间):是事件创建的时间.它通常由事件中的时间戳描述,例如采集的日志数据中,每一条日志都会记录自己的生成时间, ...
- RabbitMq死信队列(接盘侠)
队列创建之后,后期对其修改或者参数添加会报错.需要把队列重新删除,重新创建线上环境不能把队列删除,优雅安全的方式是重新建一个队列,把死信队列相关的队列进行绑定 在有过期时间的队列中设定最大接收能力5条 ...