Django Model设计详解

Django Model 设计

Django Model设计是Django五项基础核心设计之一(Model设计,URL配置,View编写,Template设计,From使用),也是MVC模式中重要的环节。

如果图片无法访问,大家可以移步GitHub Django Model 设计查看

Model是数据模型,并不是数据库,它描述了数据的构成和他们之间的逻辑关系,在Django中,Model设计实质上就是一个类,所以我们可以直接站在类的角度来看Model,这样可以尽量避免一些晦涩的概念影响理解。

下面是python中一个基本类的构成

class ClassName(object):# 属性(类属性)Attribute = ""# 方法def Method():pass

根据上面python中的类,我们依次研究Django Model

  • 基类:定义Django Model的类必须继承自models.Model
  • 类名:在Django Model设计中,类名会被当作是这个数据模型的名称。
  • 类属性:Django Model设计过程中,类属性有两方面的作用,一是申明字段,二是申明关系(一对多,多对多,一对一)
  • 方法:由于是派生类,所以我们不需要自己定义很多方法,Model基类已经做的足够完善了,只是在有必要的时候我们需要重写一些方法,如常见的__str__
  • 内嵌类Meta:Django Model设计过程中,内嵌类Meta用来定义元数据,所谓元数据就是不是字段的任何数据,比如定义排序规则等

下面依次介绍字段,关系,Meta

1.字段 Field

都说官方文档才是学习一门语言最好的教程,访问官方文档

1.1 字段类型(Field types)

字面意思,用来申明该字段的类型,比如常见的字符,数字,日期,邮箱等待,下面列举常见的字段类型

AutoField(主键)

这一个字段一般不需要我们手动定义,主要用于ID的自动递增,Django会默认为我们创建一个id

# 每一个Model Django都会为我们添加这个字段
id = models.AutoField(primary_key=True)

如果想把自己定义的字段设置为主键,需要添加参数primary_key,这时(显式设置主键)Django将不会为我们添加ID字段

与之类似还有一个BigAutoField,它支持更大的范围,最大到9223372036854775807(九百二十亿亿)足够绝大多数的使用

IntegerField(整数字段)

字面意思,用来保存整数的字段,支持 -2147483648 到 2147483647 的数字

同样与之类似有BigIntegerField 支持-9223372036854775808 到 9223372036854775807 的数字

类似还有FloatField,支持浮点数

BooleanField(布尔字段)

用来存储布尔值,与之类似的还有NullBooleanField,NullBooleanField相当于BooleanField(null=true),不过在Django 2.1 之后不建议使用后者,应为它有可能在未来版本被弃用

CharField(字符字段)

这应该是最常用的一个字段了吧,用于少量的字符串的储存(大量字符串请使用TextField)这个字段有一个必须参数max_length用来申明允许储存的最大长度

 class CharField(Field):description = _("String (up to %(max_length)s)")# ...def _check_max_length_attribute(self, **kwargs):if self.max_length is None:return [checks.Error("CharFields must define a 'max_length' attribute.",obj=self,id='fields.E120',)]

根据源码,我们可以发现如果不指定max_length会直接报"CharFields must define a ‘max_length’ attribute."

DateField(时间日期字段)

该字段有两个常用参数 auto_now 和 auto_now_add

  • auto_now :指定这个参数,可以在每次调用save()时将当前时间作为字段的值(会覆盖默认值或之前的值),但使用QuerySet.update()等方法不会跟新值
  • auto_now_add : 在初始化会以当前时间戳作为值给字段赋值,不管你有没有定义默认值,定义了也会被覆盖
  • 区别:使用auto_now会在每次save()时修改字段值,而auto_now_add只是在首次创建对象时才会把当前时间给字段。
  • 如果你想能够修改这个字段的值,请使用default=date.today需要引入from datetime.date.today()
  • auto_now,auto_now_add与default是互斥的,任何一种组合都会出错
  • 将auto_now或auto_now_add设置为True的结果与editable = False和blank = True的效果一样

与DateField类似的还有DateTimeField

  • 如果使用DateTimeField想要修改字段的值,需要使用default=timezone.now 同样需要引入from django.utils.timezone.now()
  • 另外还有TimeField,用来表示时间,接受的参数与DateField一样

[外链图片转存失败(img-w7TfUVCo-1567244122546)(…/image/DjangoModel_01.png)]

EmailField

实质上是CharField,不过使用EmailValidator检查了字符串是否是有效电子邮件地址而已,默认max_length=254

TextField

实质上也是一个CharField,是一个比较大的文本字段

FileField

class FileField(upload_to=None, max_length=100, **options)

正如文档所说,这是一个文件上传字段,有两个可选参数upload_to和max_length,后者默认100

upload_to

见名知意,upload_to用来申明上传目录,如果给定一个字符串类型初值,Django会在他后面添加时间(就是以上传时间分类文件),用户上传文件一般保存到media目录中,media目录路径需要在setting.py里定义

MEDIA_ROOT = os.path.join(BASE_DIR, "media")

这个media文件夹如果我们没有建立,保存文件时Django会自动创建

class MyModel(models.Model):# file will be uploaded to MEDIA_ROOT/uploadsupload = models.FileField(upload_to='uploads/')# or...# file will be saved to MEDIA_ROOT/uploads/2015/01/30upload = models.FileField(upload_to='uploads/%Y/%m/%d/')

如果需要动态存储文件,如按用户存储,可以把一个函数的返回值作为upload_to的值,这个函数必须接受两个参数:instance(主键,传给当前文件的唯一实例)和filename(文件名),如:

def user_directory_path(instance, filename):# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>return 'user_{0}/{1}'.format(instance.user.id, filename)class MyModel(models.Model):upload = models.FileField(upload_to=user_directory_path)

这里看着有点复杂,其实也不难,instance是当前FileField的模型实例的模型实例,也就是我们定义的字段,上面的示例是的user是和User表对应的,当然也可以不是user,比如:

def user_directory_path(instance, filename):# 我没有用user,而是自己定义了一个name字段return 'user_{0}/{1}'.format(instance.name, filename)class Diary(models.Model):name = models.CharField(max_length=10)creat_time = models.DateTimeField(auto_now_add=True)time = models.TimeField(auto_now=True)upload = models.FileField(upload_to=user_directory_path,default="")class Meta:verbose_name = "Diary"verbose_name_plural = "Diarys"

[外链图片转存失败(img-SGnfpXgs-1567244122548)(…/image/DjangoModel_02.png)]

保存之后就可以看见项目根目录下的文件了

[外链图片转存失败(img-KUPPj7yc-1567244122552)(…/image/DjangoModel_03.png)]

使用时间也是一样的

class Diary(models.Model):name = models.CharField(max_length=10)creat_time = models.DateTimeField(auto_now_add=True)time = models.TimeField(auto_now=True)# upload = models.FileField(upload_to=user_directory_path,default="")upload = models.FileField(upload_to='user_123/%Y/%m/%d/',default="")class Meta:verbose_name = "Diary"verbose_name_plural = "Diarys"def __str__(self):return self.name

[外链图片转存失败(img-oPc8recT-1567244122558)(…/image/DjangoModel_04.png)]

FileField 和 FieldFile

当您访问model上的FileField时,会获得一个FieldFile的实例作为访问基础文件的代理。它是继承自python的File的,有read(),write()等,还自己封装了一些方法,如url,name等,看官网

ImageField

class ImageField(FileField):attr_class = ImageFieldFiledescriptor_class = ImageFileDescriptordescription = _("Image")def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):self.width_field, self.height_field = width_field, height_fieldsuper().__init__(verbose_name, name, **kwargs)

由源码可以看到,ImageField是继承自FileField的一个字段,除了FileField中的特殊属性外,它额外添加了width_field, height_field两个属性用来描述图片大小,它会检查一个文件是否是图片,其他用法与FileField一样。

其他

除了上面常见的这些,还有一些字段,诸如用作URL的URLField,还有不同大小的IntField,如PositiveSmallIntegerFieldPositiveIntegerFieldSmallIntegerField,用作IP地址的GenericIPAddressField等待,此外,你也可以自定义字段,看文档就好。

1.2 参数总结

之前遇到很多参数,如max_length,default等,这里再做总结

null

如果为True,Django将在数据库中将空值存储为NULL。 默认值为False。

避免在基于字符串的字段(如CharField和TextField)上使用null。 如果基于字符串的字段具有null = True,则表示它具有“无数据”的两个可能值:NULL和空字符串。 在大多数情况下,为“无数据”提供两个可能的值是多余的; Django约定是使用空字符串,而不是NULL。

blank

如果为真,则允许该字段为空。默认是假的。注意,这与null不同。null纯粹与数据库相关,而blank则与验证相关。如果字段为blank=True,表单验证将允许输入空值。如果字段为空=False,则需要该字段。

choices

为字段提供选项,首先他的值应该是一个可迭代对象,如列表或元组,其次每一项中都应该包含两个元素,第一个是要存储到数据库中的真实值,第二个是展示给人的值,比如

class Diary(models.Model):SEX_CHOICES = (('boy', 'BOY'),('girl', 'GIRL'),('else', 'ELSE'))sex = models.CharField(max_length=10,choices=SEX_CHOICES,default="")

这个Model展示在admin页面是这样的,请忽略其他字段,那是之前写的

[外链图片转存失败(img-mRp1xKaa-1567244122563)(…/image/DjangoModel_05.png)]

在随便存储一个值后,在MySQL数据库中可以看到是这样的(最后一项)

[外链图片转存失败(img-0JWk72Nk-1567244122565)(…/image/DjangoModel_06.png)]

展示给我们的是后面大写的,而存储在数据库中的则是前面小写的

除此之外,如果Model中有多个字段需要选项,可以把这些选项分类放在同一个可迭代对象中,如

MEDIA_CHOICES = (('Audio', (('vinyl', 'Vinyl'),('cd', 'CD'),)),('Video', (('vhs', 'VHS Tape'),('dvd', 'DVD'),)),('unknown', 'Unknown'),
)

default

指定默认值,可以是默认字符串也可以是函数返回值

db_column

用于此字段的数据库列的名称。 如果没有给出,Django将使用该字段的名称。

db_index

如果为True,则将为此字段创建数据库索引。

db_tablespace

如果此字段已编制索引,则用于此字段索引的数据库表空间的名称。 默认值为项目的DEFAULT_INDEX_TABLESPACE设置(如果已设置)或模型的db_tablespace(如果有)。 如果后端不支持索引的表空间,则忽略此选项。

editable

如果为False,则该字段不会显示在admin或任何其他ModelForm中。 在模型验证期间也会跳过它们。 默认为True。

error_messages

error_messages参数允许您覆盖字段将引发的默认消息。传入一个字典,其中的关键字与您要覆盖的错误消息相匹配。

在 表单字段 级别或者 表单 Meta 级别定义的错误信息优先级总是高于在 模型字段 级别定义的。

在 模型字段 上定义的错误信息只有在 模型验证 步骤引发 ValidationError 时才会使用,并且没有在表单级定义相应的错误信息。

您可以通过添加 NON_FIELD_ERRORS 键到 ModelForm 内部的 Meta 类的 error_messages 中来覆盖模型验证引发的 NON_FIELD_ERRORS 错误信息。

help_text

使用表单小部件显示的额外“帮助”文本。 即使您的字段未在表单上使用,它也对文档很有用。

请注意,此值不会在自动生成的表单中进行HTML转义。 如果您愿意,这可以让您在help_text中包含HTML。 例如:

help_text="Please use the following format: <em>YYYY-MM-DD</em>."

primary_key

如果为True,则此字段将作为Model的主键

unique

如果需要设置该字段值唯一,需要把unique设置为True,如果尝试保存一个已经存在的值,将会引发django.db.IntegrityError异常,我们需要捕捉这个异常,用于诸如用户名等方面

总结

常用的主要这几个

  • blank:允许为空
  • choices:提供选择
  • default:提供默认值
  • db_column:提供数据表列名
  • unique:设置是否唯一

2 关系字段

关系也是一种字段,只是这个字段的值是别的某个或多个Model,只有三种关系字段 ForeignKey,ManyToManyField 和 OneToOneField

2.1 ForeignKey

这是一种多对一的关系。 需要两个参数:要关联的模型类和on_delete选项。

如果要创建递归关系 ( 与自身具有多对一关系的对象 )请使用

models.ForeignKey('self',on_delete = models.CASCADE)。

如果需要在尚未定义的模型上创建关系,可以使用模型的名称,而不是模型对象本身:

class Diary(models.Model):Ordinary_user = models.ForeignKey('Demo2',on_delete=models.CASCADE,default="")class Demo2(models.Model):email: str = models.EmailField(blank=True,db_column="邮箱",default="")Tel_Num = models.CharField(max_length=20,blank=True,db_column="联系电话",default="")address: str = models.CharField(max_length=100,blank=True,db_column="住址",default="")ID_card = models.CharField(max_length=20, db_column="身份证号",default="")

这样,我们建立了两张表,Diary表中Ordinary_user字段与Demo2是一个多对一的关系,先看一下两张表在MySQL数据库中的样子

先是diary表,同样请忽略其他字段,表名是app名_类名

[外链图片转存失败(img-j7xvKUZD-1567244122568)(…/image/DjangoModel_07.png)]

其次是Demo2表

[外链图片转存失败(img-uHS783Pt-1567244122571)(…/image/DjangoModel_08.png)]

发现Django把ForeignKey字段的列名命名为目标Model名_id这里之所以是_id是应为id是这个表的主键,而里面存储的也是对应的id序号,就是通过保存主键的方式实现一对多的。

然后再看一下再admin界面的样子把

[外链图片转存失败(img-oGREHt43-1567244122573)(…/image/DjangoModel_09.png)]

点加号会打开一个新窗口让你添加Dome的数据,应该挺方便

[外链图片转存失败(img-BcLglQBH-1567244122575)(…/image/DjangoModel_10.png)]

on_delete

这是必选参数,当删除ForeignKey引用的对象时,Django将模拟on_delete参数指定的SQL约束的行为。总共有六种选择
CASCADE,PROTECT,SET_NULL,SET_DEFAULT,SET(),DO_NOTHING

  • CASCADE:级联删除。 Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。
  • PROTECT:通过引发ProtectedError(django.db.IntegrityError的子类)来防止删除引用的对象。
  • SET_NULL:将ForeignKey设置为null; 这只有在null为True时才有可能
  • SET_DEFAULT:将ForeignKey设置为其默认值; 必须设置ForeignKey的默认值。
  • SET():将ForeignKey设置为传递给SET()的值,或者如果传入了回调函数,则调用它的结果。 在大多数情况下,为了避免在导入models.py时执行查询,必须传递一个回调函数。
  • DO_NOTHING:不采取行动。 如果数据库后端强制实施参照完整性,则除非您手动将SQL ON DELETE约束添加到数据库字段,否则将导致IntegrityError。

2.2 ManyToManyField

多对多的关系。 只有一个必须参数:与模型相关的类,它与ForeignKey的工作方式完全相同,包括递归和惰性关系。

2.2.1 参数

(1).symmetrical

只有在和自己建立多对多关系时才有效,为true时建立的是对称关系,反之为False建立非对称关系,默认为True,例如:

class Demo2(models.Model):friends = models.ManyToManyField("self",symmetrical=False,)

默认为true的情况下,如果建立A时指定friend为B,C,那么在B,C中,A也会被申明为自己的朋友,反之则不会

(2).through

Django将自动生成一个表来管理多对多关系。 但是,如果要手动指定中间表,可以使用through选项指定表示要使用的中间表的Django模型

此选项最常见的用途是,您希望将额外数据与多对多关系相关联。

如果未指定显式直通模型,则仍可使用隐式直通模型类来直接访问为保持关联而创建的表。 它有三个字段来链接模型。

如果源模型和目标模型不同,表中的字段如下:

  • id: 主键
  • <containing_model>_id: 申明多对多关系的模型id
  • <other_model>_id: 指向的模型id

[外链图片转存失败(img-A9IklSnF-1567244122579)(…/image/DjangoModel_11.png)]

如果原模型与目标Model相同(自己与自己建立多对多关系),表中的字段如下:

  • id:关系的主键。
  • from_ <model> _id:源实例
  • to_ <model> _id:目标模型实例

[外链图片转存失败(img-pRlQ5pOm-1567244122581)(…/image/DjangoModel_12.png)]

(3).through_fields

仅在指定自定义中间模型时使用。 Django通常会确定要使用哪个中间模型字段,以便自动建立多对多关系。 但是,请考虑以下情况:

from django.db import modelsclass Person(models.Model):name = models.CharField(max_length=50)class Group(models.Model):name = models.CharField(max_length=128)members = models.ManyToManyField(Person,through='Membership',through_fields=('group', 'person'),)class Membership(models.Model):group = models.ForeignKey(Group, on_delete=models.CASCADE)person = models.ForeignKey(Person, on_delete=models.CASCADE)inviter = models.ForeignKey(Person,on_delete=models.CASCADE,related_name="membership_invites",)invite_reason = models.CharField(max_length=64)

Membership有两个外键(person和inviter),这使得关系模糊不清,Django无法知道使用哪一个。 在这种情况下,您必须使用through_fields明确指定Django应使用哪些外键,如上例所示。

through_fields接受2元组(‘field1’,‘field2’),其中field1是定义ManyToManyField的模型的外键名称(在本例中为group),field2是外键的名称。 目标模型(本例中的person)。

如果中间模型上有多个外键到参与多对多关系的任何(甚至两个)模型,则必须指定through_fields。 这也适用于使用中间模型时的递归关系,并且模型有两个以上的外键,或者您想要明确指定Django应该使用哪两个。

使用中间模型的递归关系总是被定义为非对称的 - 也就是说,symmetrical=False 因此,存在“源”和“目标”的概念。 在这种情况下,'field1’将被视为关系的“源”,'field2’将被视为“目标”。

2.3 OneToOneField

一对一的关系。 从概念上讲,这类似于具有unique = True的ForeignKey,但关系的“反向”一侧将直接返回单个对象。

这作为模型的主键是最有用的,它以某种方式“扩展”另一个模型; 例如,通过从子模型向父模型添加隐式一对一关系来实现多表继承。

需要一个位置参数:与模型相关的类。 这与ForeignKey完全相同,包括有关递归和惰性关系的所有选项。

如果没有为OneToOneField指定related_name参数,Django将使用当前模型的小写名称作为默认值。

3. Meta

用来定义元数据(除字段以外的别的数据),常见的元数据:

  • app_label:如果你定义的Model不在app目录下的models.py中,就需要指定该字段为app名称
  • db_table:自定义数据表名,如果不指定,默认用app名_model名
  • db_tablespace:指定某些数据库的表空间
  • ordering:指定排序集
  • verbose_name:可读的名字
  • verbose_name_plural:Model的复数形式

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

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

相关文章

python设置全局变量失败_Python全局变量与global关键字常见错误解决方案

在Python的变量使用中&#xff0c;经常会遇到这样的错误:local variable a referenced before assignment它的意思是&#xff1a;局部变量“a”在赋值前就被引用了。比如运行下面的代码就会出现这样的问题&#xff1a;a 3def Fuc():print (a)a a 1Fuc()​ 但是如果把 a a …

Atititi tesseract使用总结

Atititi tesseract使用总结 消除bug&#xff0c;优化&#xff0c;重新发布。当前版本为3.02 项目下载地址为&#xff1a;http://code.google.com/p/tesseract-ocr。 Windows cmd命令行使用Tesseract-OCR引擎识别验证码: 1、下载安装Tesseract-OCR引擎(3.0版本才支持中文识别) t…

Javascipt数组去重的几种方式

方法一 function unique(arr) {var retArr [];for (var i 0; i < arr.length; i) {(retArr.indexOf(arr[i]) -1) && retArr.push(arr[i]);}return retArr; } 方法二 function unique(arr) {return arr.filter(function(item, index, array) {return array.indexO…

01_JS语法

JS语法 严格区分大小写以;结尾&#xff0c;不写浏览器会自动加&#xff0c;但不准确&#xff0c;且会占用浏览器资源自动忽略多个空格和换行 写在哪 所有JS代码都必须依托网页运行 内嵌 写在html的script标签中 <script>// JS代码 </script>事件 写在某个ht…

pythonwhile循环love_python基础之while循环及编码

while 条件&#xff1a;循环体死循环&#xff1a;没有终止条件(修改方法&#xff1a;1.改变条件2.使用break)break 终止当前循环contiune&#xff1a;跳出本次循环&#xff0c;继续下次循环break和contione必须在循环体里while 条件&#xff1a;循环体else&#xff1a;结果当wh…

css页面布局

居中布局 水平居中 父元素和子元素的宽度都未知 inline-block text-ailgn .child{display:inline-block;} .parent{text-align:center;} 优点&#xff1a;兼容性好 缺点&#xff1a;子元素文本继承了text-align属性&#xff0c;子元素要额外加text-align:left; table ma…

02_JS变量

JS变量 字面量 常量&#xff0c;不可变量 变量 变量用 var 变量名声明 命名 变量命名以数字字母下划线和$组成&#xff0c;不能以数字开头&#xff0c;还可以是utf-8的任意字符&#xff0c;包括中文&#xff0c;一般采用驼峰命名法 常用的几个函数 alert():浏览器弹窗d…

Rotate String

Given a string and an offset, rotate string by offset. (rotate from left to right) Example Given "abcdefg". offset0 > "abcdefg" offset1 > "gabcdef" offset2 > "fgabcde" offset3 > "efgabcd"分析&am…

音视频播放、录音、拍照

音频 在iOS中音频播放从形式上可以分为音效播放和音乐播放。前者主要指的是一些短音频播放&#xff0c;通常作为点缀音频&#xff0c;对于这类音频不需要进行进度、循环等控制。后者指的是一些较长的音频&#xff0c;通常是主音频&#xff0c;对于这些音频的播放通常需要进行精…

python 递归函数与循环的区别_提升Python效率之使用循环机制代替递归函数

斐波那契数列当年&#xff0c;典型的递归题目&#xff0c;斐波那契数列还记得吗&#xff1f;def fib(n):if n1 or n2:return 1else:return fib(n-1)fib(n-2)当然, 为了程序健壮性&#xff0c;加上try...except...def fib(n):if isinstance(n, int):print(兄弟,输入正整数哈)ret…

03_JS数据类型

JS数据类型 基本数据类型 String 字符串类型&#xff0c;申明时用单引号或双引号引起来&#xff0c;两种引号不可嵌套&#xff0c;不可混用 Number 数值型&#xff0c;有两个特殊的数字 Infint:无穷大NaN&#xff1a;非数值型数字&#xff0c;不与任何类型相等 Boolean …

7.5

姓名 崔巍 时间 2016年7月5日 学习内容 最后一次确定同步控制力度等实现细节。 学习了Visual Studio C#软件测试方面的工具。巩固了等价类黑盒测试方法的相关理论&#xff0c;并且学习了集成测试、回归测试的相关内容&#xff0c;并进行了测试。 集成测试&#xff0c;…

python scratch ev3_如何在scratch上连接乐高ev3?

乐高教育的官网有关于EV3使用Python的详细介绍https://education.lego.com/zh-cn/support/mindstorms-ev3/python-for-ev3​education.lego.com来自网易有道Scratch是现在小朋友们最热的编程工具&#xff0c;也是各学校和培训机构对小学生编程的入门首选。网易有道Kada平台是一…

04_JS运算符

JS运算符 一元运算符 -,正负号&#xff0c;对非数值类型做正负操作会先转换成数值型&#xff0c;可以用快速进行类型转换 逻辑运算符 且 &&&#xff0c;从左到右看&#xff0c;一旦返现值为false的表达式立刻返回false&#xff0c;全真为真或 ||&#xff0c;从左到右…

C语言 第八章 函数、指针与宏

一、函数 函数是一个包含完成一定功能的执行代码段。我们可以把函数看成一个"黑盒子", 你只要将数据送进去就能得到结果, 而函数内部究竟是如何工作的的, 外部程序是不知道的。外部程序所知道的仅限于输入给函数什么以及函数输出什么。函数提供了编制程序的手段,使之…

ByteBuffer用法小结

在NIO中,数据的读写操作始终是与缓冲区相关联的.读取时信道(SocketChannel)将数据读入缓冲区,写入时首先要将发送的数据按顺序填入缓冲区.缓冲区是定长的,基本上它只是一个列表,它的所有元素都是基本数据类型.ByteBuffer是最常用的缓冲区,它提供了读写其他数据类型的方法,且信道…

promise用法_Promise的秘密

写在前面本篇文章将会带大家从分解promise入手&#xff0c;一步步实现一个promise。但阅读之前需要比较熟练地了解了解用法&#xff0c;结合用法看文章可能更容易理解。结构先看一下简单的用法。const promise new Promise((resolve, reject) > {setTimeout(() > {resol…

SpringMVC视图解析器(转)

前言 在前一篇博客中讲了SpringMVC的Controller控制器&#xff0c;在这篇博客中将接着介绍一下SpringMVC视图解析器。当我们对SpringMVC控制的资源发起请求时&#xff0c;这些请求都会被SpringMVC的DispatcherServlet处理&#xff0c;接着Spring会分析看哪一个HandlerMapping定…

05_JS流程控制语句

JS流程控制语句 顺序结构 选择结构 if-else语句 var aprompt(); var bprompt(); var cprompt(); if(a && b || c){alert(); }else if(a || b || c){alert(); }else{alert(); }条件分支语句 var aprompt(); switch(a){case 1:alert("1");break;case 2:al…

ForkJoinPool 学习示例

在JAVA7之前&#xff0c;并行处理数据非常麻烦。第一&#xff0c;你得明确把包含数据的数据结构分成若干份。第二&#xff0c;你要将每个子部分分配给一个独立的线程。第三&#xff0c;你要在恰当的时候对它们进行同步避免不希望的竞争条件&#xff0c;等待所有线程完成&#x…