一、定义

1.什么是ORM?

ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。

2.ORM的优缺点

优点:摆脱复杂的SQL操作,适应快速开发;让数据结构变得简洁;数据库迁移成本更低(如从mysql->oracle)

缺点:性能较差、不适用于大型应用;复杂的SQL操作还需通过SQL语句实现

映射关系:

     表名  <-------> 类名

       字段  <-------> 属性

    表记录 <------->类实例对象

二、创建表(建立模型)

实例:我们来假定下面这些概念,字段和关系

作者模型:一个作者有姓名和年龄。

作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)

出版商模型:出版商有名称,所在城市以及email。

书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。

models.py

from django.db import models

# Create your models here.

class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5, decimal_places=2) read_num=models.IntegerField(default=0)
commnet_num=models.IntegerField(default=0)
poll_num=models.IntegerField(default=0) # publish:与当前书籍对象关联的的出版社对象,与Publish建立一对多的关系,外键字段建立在多的一方
publish=models.ForeignKey(to="Publish",to_field="id") # authors: 与当前书籍关联的所有作者的集合
# 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to="Author")
def __str__(self):
return self.title
class Author(models.Model):
name=models.CharField(max_length=32)
age=models.IntegerField() class AuthorDetail(models.Model):
tel=models.CharField(max_length=32)
email=models.CharField(max_length=32) #与Author建立一对一的关系
author=models.OneToOneField("Author") class Publish(models.Model):
name=models.CharField(max_length=32)
email=models.CharField(max_length=32) def __str__(self):
return self.name # #收到创建第三张表
# class Author2Book(models.Model):
# author=models.ForeignKey(to="Author")
# book=models.ForeignKey(to="Book")

语法

#与Author建立一对一的关系
author=models.OneToOneField("Author")
    # 与Publish建立一对多的关系,
#publish:与当前书籍对象关联的的出版社对象,外键字段建立在多的一方
publish=models.ForeignKey(to="Publish",to_field="id") # authors: 与当前书籍关联的所有作者的集合
# 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to="Author")

通过logging可以查看翻译成的sql语句

settings.py

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}  

注意事项:

1、 表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称  

2、id 字段是自动添加的

3、对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名

4、这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。

5、定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。

6、外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。

字段选项

每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义,这里我们只简单介绍一些最常用的:

(1)null

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

(1)blank

如果为True,该字段允许不填。默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。 (2)default 字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。 (3)primary_key 如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
否则没必要设置任何一个字段的primary_key=True。 (4)unique 如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的 (5)choices
由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,而且这个选择框的选项就是choices 中的选项。 这是一个关于 choices 列表的例子: YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
('GR', 'Graduate'),
)
每个元组中的第一个元素,是存储在数据库中的值;第二个元素是在管理界面或 ModelChoiceField 中用作显示的内容。 在一个给定的 model 类的实例中,想得到某个 choices 字段的显示值,就调用 get_FOO_display 方法(这里的 FOO 就是 choices 字段的名称 )。例如: from django.db import models class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES) >>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
'L'
>>> p.get_shirt_size_display()
'Large'

二、添加表记录

1.普通字段(单表操作)

方式1

publish_obj=Publish(name="人民出版社",city="北京",email="renMin@163.com")
publish_obj.save() # 将数据保存到数据库

方式2

返回值publish_obj是添加的记录对象
publish_obj=Publish.objects.create(name="人民出版社",city="北京",email="renMin@163.com")<br><br>方式3<br>表.objects.create(**request.POST.dict())

2.外键字段

表关系为一对一:在任何一张表中加入一个关联字段,但关联字段必须唯一约束

表关系为一对多:在多的一张表中加关联字段

方式1:
publish_obj=Publish.objects.get(nid=1)
Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=665,pageNum=334,publish=publish_obj) 方式2:
Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=665,pageNum=334,publish_id=1)  

3.多对多字段

创建第三张表,主键,两个关联字段。

book_obj=Book.objects.create(title="追风筝的人",publishDate="2012-11-12",price=69,pageNum=314,publish_id=1)

author_yuan=Author.objects.create(name="yuan",age=23,authorDetail_id=1)
author_egon=Author.objects.create(name="egon",age=32,authorDetail_id=2)

book_obj.authors.add(author_egon,author_yuan) # 将某个特定的 model 对象添加到被关联对象集合中。 ======= book_obj.authors.add(*[author_egon,author_yuan]) #添加筛选条件的关联,与年龄大于20的关联
author_list=Author.objects.filter(age_gt=20)
bool_obj.authors.add(*author_list) book_obj.authors.create() #创建并保存一个新对象,然后将这个对象加被关联对象的集合中,然后返回这个新对象。

解除关系:

book_obj.authors.remove()     # 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])
book_obj.authors.clear() #清空被关联对象集合。

例如

def add_book(request):
if request.method=="POST":
title=request.POST.get("title")
price=request.POST.get("price")
pub_date=request.POST.get("pub_date")
publish_id=request.POST.get("publish_id") # 一对多的添加方式
# 方式1:
#book_obj=Book.objects.create(title=title,price=price,publishDate=pub_date,publish_id=publish_id)
# 方式2:
# publish_obj=Publish.objects.filter(id=2).first()
# book_obj=Book.objects.create(title=title, price=price, publishDate=pub_date,publish=publish_obj) # 多对多关系的创建
book_obj = Book.objects.create(title=title, price=price, publishDate=pub_date, publish_id=publish_id) print("==",book_obj.authors.all()) # <QuerySet []> # add 方法 绑定多对多的关系
#jing = Author.objects.filter(name="景丽洋").first()
#alex = Author.objects.filter(name="alex").first()
#book_obj.authors.add(jing,alex)
#book_obj.authors.add(*[jing,alex])
#author_list=Author.objects.filter(age__gt=20)
#book_obj.authors.add(*author_list)
# remove 方法 绑定多对多的关系
book_obj=Book.objects.get(nid=9)
#alex = Author.objects.filter(name="alex").first()
#book_obj.authors.remove(alex)
book_obj.authors.clear() #print("==", book_obj.authors.all()) # 失败的原因:找不到第三张关系表的名字
# book_authors.objects.create(book_id=book_obj.id,author_id=jing.id)
# book_authors.objects.create(book_id=book_obj.id,author_id=alex.id) return redirect("/index/") publish_list=Publish.objects.all()
return render(request,"add_book.html",locals())

三、修改表记录

 Book.objects.filter().update(price=50,.....)

四、删除表记录

删除方法就是 delete()。它运行时立即删除对象而不返回任何值。例如:

Book.objects.filter().delete() # 默认级联删除

你也可以一次性删除多个对象。每个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中所有的对象。

例如,下面的代码将删除 pub_date 是2005年的 Entry 对象:

Entry.objects.filter(pub_date__year=2005).delete()

五、查询表记录

1.查询相关API

<1> all():                 查询所有结果,返回的是queryset,集合

<2> filter(**kwargs):      它包含了与所给筛选条件相匹配的对象,返回的是queryset,集合

<3> get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
如果符合筛选条件的对象超过一个或者没有都会抛出错误。返回的是对象 <5> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 <4> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
model的实例化对象,而是一个可迭代的字典序列 <9> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 <6> order_by(*field): 对查询结果排序 <7> reverse(): 对查询结果反向排序 <8> distinct(): 从返回结果中剔除重复纪录 <10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。 <11> first(): 返回第一条记录 <12> last(): 返回最后一条记录 <13> exists(): 如果QuerySet包含数据,就返回True,否则返回False

2.双下划线之单表查询

models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感 models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and startswith,istartswith, endswith, iendswith 

3.基于对象的跨表操作(子查询)

正向查询:通过关联字段所在的表查询另外一张关联表
反向查询:通过一张关联表查询关联字段所在的表

  • 一对多

正向查询,按字段:publish
反向查询,按表名小写_set

    #查询java的出版社的邮箱(正向查询:按字段book_obj.publish)
book_obj=Book.objects.filter(title="java").first()
print(book_obj.publish.email)

  #查询人民出版社出版过的所有的书籍名称(反向查询:按表名小写_set publish_obj.book_set)
publish_obj=Publish.objects.filter(name="人民出版社").first() print("---",publish_obj.book_set.all())
  • 多对多

正向查询,按字段:authors
反向查询,按表名小写_set

    #查询php这本书籍的所有作者的名字以及年龄(正向查询:按字段book_obj.authors)
book_obj=Book.objects.filter(title="php").first()
print(book_obj.authors.all())
for obj in book_obj.authors.all():
print(obj.name,obj.age) #查询alex出版社过的所有书籍的名称和价格(反向查询,按表名小写_set)
alex=Author.objects.filter(name="alex").first()
print(alex.book_set.all())
for obj in alex.book_set.all():
print(obj.title,obj.price)
  • 一对一

正向查询,按字段:author
反向查询,按表名小写

    # 一对一查询
查询tel=789的作者的名字 正向查询按字段
ad=AuthorDetail.objects.filter(tel="").first()
print(ad.author.name) # 查询alex的手机号是多少
alex=Author.objects.filter(name='alex').first()
print(alex.authordetail.tel) #

4.基于QuerySet的跨表查询(join查询)

正向查询,按字段:publish
反向查询,按表名小写

  • 一对多

例1:
查询java这本书的出版社的邮箱(正向查询) ret=Book.objects.filter(nid__gt=6).values("publish__name") sql:
SELECT "app01_publish"."name"
FROM "app01_book" INNER JOIN "app01_publish"
ON ("app01_book"."publish_id" = "app01_publish"."id")
WHERE "app01_book"."nid" > 6 LIMIT 21; values实现机制:
对调用的QuerySet集合对象里面的每一个对象循环遍历,取出每一个对象的显示字段的值,组成新的字典,放在一个新的QuerySet中,返回 例2:
# 查询人民出版社出版过的所有的书籍名称(反向查询)
ret=Publish.objects.filter(name="人民出版社").values("book__title")
print(ret)
#<QuerySet [{'book__title': 'golang'}, {'book__title': 'linux2'}, {'book__title': 'qq'}, {'book__title': 'www'}]>
  • 多对多

    #查询php这本书籍的所有作者的名字以及年龄
ret=Book.objects.filter(title="php").values("authors__name","authors__age")
print(ret)
#查询alex出版社过的所有书籍的名称和价格
ret=Author.objects.filter(name="alex").values("book__title","book__price")
print(ret)
  • 一对一

    #查询tel=789的作者的名字
ret=AuthorDetail.objects.filter(tel="").values("author__name")
# 查询alex的手机号是多少
ret=Author.objects.filter(name="alex").values("authordetail__tel")

扩展

扩展:
#查询人民出版社出版过的所有的书籍名称(两种查询思路,基表不同) ret=Publish.objects.filter(name="人民出版社").values("book__title")
ret=Book.objects.filter(publish__name="人民出版社").values("title") # 手机号以151开头的作者出版过的所有书籍名称以及出版社名称 ret=Book.objects.filter(authors__authordetail__tel__startswith="").values("title","publish__name")
print(ret) SELECT "app01_book"."title", "app01_publish"."name" FROM "app01_book"
INNER JOIN "app01_book_authors" ON ("app01_book"."nid" = "app01_book_authors"."book_id")
INNER JOIN "app01_author" ON ("app01_book_authors"."author_id" = "app01_author"."id")
INNER JOIN "app01_authordetail" ON ("app01_author"."id" = "app01_authordetail"."author_id")
INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."id")
WHERE
"app01_authordetail"."tel" LIKE '7%' ESCAPE '\' LIMIT 21; args=('7%',)

5.聚合查询与分组查询

聚合函数:Sum  Count Avg Min Max

    单表:
emp:
id name salary dep
1 张三 2000 销售部
2 李四 5000 IT部
3 王五 6000 销售部
4 赵六 5000 人事部
5 主七 2000 人事部 select Count(*),dep from emp group by dep
select * from emp group by id,name,salary,dep 跨表:
emp: dep:
id name salary dep_id id name
1 张三 2000 1 1 销售部
2 李四 5000 2 2 IT部
3 王五 6000 1 3 人事部
4 赵六 5000 3
5 主七 2000 2 dep---emp id dep.id dep.name emp.id emp.name emp.salary emp.dep_id
1 1 销售部 1 张三 2000 1
2 1 销售部 3 王五 6000 1
3 2 IT部 2 李四 5000 2
4 2 IT部 5 主七 2000 2
5 3 人事部 4 赵六 5000 3 select Count(*) from emp
select * from dep group by id SELECT "app01_publish"."name", COUNT("app01_book"."title") AS "c"
FROM "app01_publish" LEFT OUTER JOIN "app01_book" ON ("app01_publish"."id" = "app01_book"."publish_id")
GROUP BY "app01_publish"."id", "app01_publish"."name", "app01_publish"."email" LIMIT 21; args=()

辅助理解

  • 聚合:aggregate(*args, **kwargs)

# 计算所有图书的平均价格
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}

aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

    # 聚合函数  aggregate
from django.db.models import Sum,Count,Max,Min,Avg
# ret=Book.objects.all().aggregate(Sum("price"))
# print(ret)
  • 分组:annotate()

为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。

统计每一本书的作者个数

bookList=Book.objects.annotate(authorsNum=Count('authors'))
for book_obj in bookList:
print(book_obj.title,book_obj.authorsNum)
SELECT
"app01_book"."nid",
"app01_book"."title",
"app01_book"."publishDate",
"app01_book"."price",
"app01_book"."pageNum",
"app01_book"."publish_id",
COUNT("app01_book_authors"."author_id") AS "authorsNum"
FROM "app01_book" LEFT OUTER JOIN "app01_book_authors"
ON ("app01_book"."nid" = "app01_book_authors"."book_id")
GROUP BY
"app01_book"."nid",
"app01_book"."title",
"app01_book"."publishDate",
"app01_book"."price",
"app01_book"."pageNum",
"app01_book"."publish_id" sql

sql解析

Book.objects.annotate(authorsNum=Count('authors'))
拆分解析:
Book.objects等同于Book.objects.all(),翻译成的sql类似于: select id,name,.. from Book
这样得到的对象一定是每一本书对象,有n本书籍记录,就分n个组,不会有重复对象,每一组再由annotate分组统计。

(2) 如果想对所查询对象的关联对象进行聚合:

统计每一个出版社的最便宜的书

publishList=Publish.objects.annotate(MinPrice=Min("book__price"))

for publish_obj in publishList:
print(publish_obj.name,publish_obj.MinPrice)

annotate的返回值是querySet,如果不想遍历对象,可以用上valuelist:

queryResult= Publish.objects
            .annotate(MinPrice=Min("book__price"))
            .values_list("name","MinPrice")
print(queryResult)

统计每一本以py开头的书籍的作者个数:

 queryResult=Book.objects
           .filter(title__startswith="Py")
           .annotate(num_authors=Count('authors'))

统计不止一个作者的图书
queryResult=Book.objects
          .annotate(num_authors=Count('authors'))
          .filter(num_authors__gt=1)
        # 查询每一个出版社出版社出版的书籍个数
# ret=Publish.objects.all().annotate(c=Count("book__title")).values("name","c")
# print(ret) # <QuerySet [<Publish: 人民出版社>, <Publish: 机械出版社>, <Publish: 北京出版社>]> # 查询每一本书的作者个数
#ret=Book.objects.all().annotate(author_num=Count("authors")).values("author_num","title")
# ret=Book.objects.all().annotate(author_num=Count("authors")).filter(author_num__gt=0)
# print(ret)

6.F查询和Q查询

  • F查询

F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

# 查询评论数大于收藏数的书籍

   from django.db.models import F
Book.objects.filter(commnetNum__lt=F('keepNum'))

Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。

# 查询评论数大于收藏数2倍的书籍
Book.objects.filter(commnetNum__lt=F('keepNum')*2)

修改操作也可以使用F函数,比如将每一本书的价格提高30元:

Book.objects.all().update(price=F("price")+30) 
  • Q查询

filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象

from django.db.models import Q
Q(title__startswith='Py')

Q 对象可以使用& 和| 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。

bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))

等同于下面的SQL WHERE 子句:WHERE name ="yuan" OR name ="egon"

你可以组合& 和|  操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询:

bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title")

查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:

    bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),
title__icontains="python"
)
    # 评论数大于点赞数的书籍
from django.db.models import F ,Q
# ret=Book.objects.filter(poll_num__gt=F("commnet_num")*2)
# print(ret)
#Book.objects.all().update(price=F("price")+100)
# 查询 2018-01-09出版的或者价格大于150的书籍
ret=Book.objects.filter(Q(publishDate="2018-01-17")&~Q(price__gt=300))
print(ret)
return HttpResponse("OK")

【django基础之ORM】的更多相关文章

  1. django基础 -- 5. ORM 数据库操作

    一. ORM 对象关系映射 类   ------   表 类对象   ------   记录 类属性   ------   字段 二.  连接数据库配置 1.在  setting.py 文件中重新设置 ...

  2. python django基础四 ORM简介

    ORM,全称是object relation mapping.翻译过来,就是对象关系映射. 主要来学习MySQL操作,MySQL是一个软件.它的优点:1.免费 2.开源 pymysql,就是Mysql ...

  3. 【django基础之ORM,增删改查】

    一.定义 1.什么是ORM? ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候, ...

  4. django 基础进阶ORM 2

    1.多表操作 添加记录: 针对一对多 book_obj=Book.objects.create(title="python葵花宝典",price=100,publishDate=& ...

  5. django 基础进阶ORM COOKIE

    ORM: class Book(models.Model): title=models.CharFiled(max_length=32) 类-----------------表    #  Book- ...

  6. 初学Django基础02 ORM操作

    django的ORM操作 之前我们知道了models.py这个文件,这个文件是用来读取数据结构的文件,每次操作数据时都走这个模块 常用字段 AutoField int自增列,必须填入参数 primar ...

  7. python django基础五 ORM多表操作

    首先在创建表的时候看下分析一下 1.作者表和作者详细地址表  一对一关系 理论上谁都能当主表 把Author设置成主表 au=models.OneToOneField(to='AuthorDetail ...

  8. Django基础之ORM操作

    ################################################################## # PUBLIC METHODS THAT ALTER ATTRI ...

  9. {Django基础六之ORM中的锁和事务}一 锁 二 事务

    Django基础六之ORM中的锁和事务 本节目录 一 锁 二 事务 一 锁 行级锁 select_for_update(nowait=False, skip_locked=False) #注意必须用在 ...

随机推荐

  1. centos7 系统安装问题汇总

    centos7 系统安装问题汇总: 1.使用u盘 安装centos7时,一直提示:'.../dev/root  does not exist,could not boot' 解决方法: 2.不能将原来 ...

  2. shiro中 UnknownAccountException

    一 shiro的session.request和response与服务端容器自身的这三个对象的关系 在web.xml中配置了一个Filter,拦截/*,所有的uri.在拦截器中还会调用ShiroFil ...

  3. 关于linux命令ssh的总结

    因为项目计算量比较大,需要将任务分布到多台电脑上面运行,因为对于分布式概念不熟,就想到了linux最简单的ssh协议,远程控制其他电脑,然后写shell脚本统一在所有电脑上运行程序.(我的操作系统为U ...

  4. 豹哥嵌入式讲堂:ARM开发之文件详解(3)- project文件

    大家好,我是豹哥,猎豹的豹,犀利哥的哥.今天豹哥给大家讲的是嵌入式开发里的project文件. 前面两节课里,豹哥分别给大家介绍了嵌入式开发中的两种典型input文件:source文件.linker文 ...

  5. Head First设计模式之策略模式

    这是学习的第一个设计模式,而书中写的实例相对比较复杂,参考了网上的文章进行总结 一.定义 策略模式(strategy pattern): 定义了算法族, 分别封闭起来, 让它们之间可以互相替换, 此模 ...

  6. SQLSERVER 死锁标志

    最开始做DBA的时候,整天死锁到头痛1222,至今都能回想到这个错误窗口: 死锁定义:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待 ...

  7. vue2 watch引用类型 失败原因

    vue中watch基本用法: new Vue({ el: '#t1', data: { a: { b: 1, c: 2 }, }, methods: { ch() { this.a.d=5 //不打印 ...

  8. Python的伪私有属性

    什么是伪私有属性? 在Python中,没有类似 private 之类的关键字来声明私有方法或属性. Python中要声明私有属性,需要在属性前加上双下划线(但是结尾处不能有双下划线),如:self._ ...

  9. MySQL 优化实施方案

    1.1 前言 在进行MySQL的优化之前必须要了解的就是MySQL的查询过程,很多的查询优化工作实际上就是遵循一些原则让MySQL的优化器能够按照预想的合理方式运行而已.更多关于MySQL查询相关参照 ...

  10. spring中Bean后置处理器实现总结

    BeanPostProcessor接口 bean的后置处理器实现功能主要是 可以在bean初始化之前和之后做增强处理.自定义MyBeanProcessor实现BeanPostProcessor接口,重 ...