什么是rest_framework序列化?

在写前后端不分离的项目时:

  我们有form组件帮我们去做数据校验

  我们有模板语法,从数据库取出的queryset对象不需要人为去转格式

当我们写前后端分离项目的时:

  我们需要自己去做数据校验

  我们需要手动去转数据格式,因为跨平台数据传输都用json字符串,不能直接jsonqueryset对象

这个时候你就要想想了,原生django里有这么神奇的组件,那rest_framework里会不会也有这样的组件呢?嗯...果然有!

这就是rest_framework的序列化组件,下面我们一起来看!

怎么用rest_framework的序列化组件?

首先我们需要从rest_framework导几个模块

from rest_framework.serializers import Serializer,ModelSerializer
from rest_framework import serializers
Serializer是rest_framework原生的序列化组件
ModelSerializer是rest_framework在原生的序列化组件的基础上封装了一层的序列化组件

用法:1、在用我们的rest_framework序列化组件的时候,我们的视图层都必须写视图类,不能再写视图函数

   2、我们需要针对每一张模型表写一个类来继承Serailizer或者ModelSerailizer类,

    当我们在视图类里需要对数据进行序列化或者反序列化的时候,在自己定义的类传入需要序列化的数据实例化,调用.data即可拿到序列化或者校验后的数据了

原生Serializer用法:

详细使用我们来上代码,我们起一个django项目,在app01里面新建myserializer文件,这里面写我们定义的序列化类。

看项目应用目录

路由层

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
# /books/的时候表示获取所有图书, /book/1/ 表示对id为1的图书进行操作
url(r'^book/(?P<id>\w+)/$|(?P<type>books)/$', views.Book.as_view()), # 获取所有出版社信息
url(r'^publish/$', views.Publishs.as_view()), # 对某个出版社进行操作
url(r'^publish/(?P<id>\w+)/$', views.Publish.as_view()), # 作者author部分暂没写
]

模型层

from django.db import models

# Create your models here.
from django.contrib.auth.models import User,AbstractUser class UserInfo(AbstractUser):
phone = models.CharField(max_length=15)
avatar = models.FileField(upload_to='static/avatar',default=None) class Book(models.Model):
title = models.CharField(max_length=64)
price = models.DecimalField(max_digits=10,decimal_places=2)
publish_time = models.DateField(null=True)
authors = models.ManyToManyField(to='Author')
publish = models.ForeignKey(to="Publish")
def __str__(self):
return self.title class Author(models.Model):
name = models.CharField(max_length=64)
choices = ((0, '男'), (1, '女'), (2, '保密'))
sex = models.IntegerField(choices=choices)
info = models.CharField(null=True,max_length=255) def __str__(self):
return self.name class Publish(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(null=True,max_length=15)
address = models.CharField(null=True,max_length=255) def __str__(self):
return self.name

序列化组件层

from rest_framework import serializers
from app01 import models """
使用步骤:
1、新建序列化类,继承Serializer
2、类中定义和模型表一一对应的字段
-其中类中的名字可以改变,需要在serializers.CharField()的括号中指定source=某个字段,建议映射关系
-外键关系的字段可以用serializers.SerializerMethodField(),需要在下方固定写 get_字段名 的方法,
这里可以写具体逻辑,最终返回结果就是该字段的结果
3、当新增数据的时候需要重写父类的create方法,逻辑由自己实现,可以参考下面BookSerilizers类中实现的create方法
4、当修改数据的时候需要重写父类的update方法,逻辑由自己实现,可以参考下面BookSerilizers类中实现的update方法
5、当完成这些配置后就可以在视图类中实例化调用了,序列化的时候序列化,反序列化的时候校验
""" class PublishSerilizers(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(max_length=32)
phone = serializers.CharField(max_length=15)
address = serializers.CharField(max_length=255) class AuthorSerilizers(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(max_length=32)
sex = serializers.CharField()
info = serializers.CharField(max_length=255) class BookSerilizers(serializers.Serializer):
id = serializers.IntegerField(read_only=True) #read_only 是指当前字段只读,前端可以不用传 write_only是指不给前端返回这个字段,但是前端新增和修改必须传
title = serializers.CharField(max_length=64)
price = serializers.DecimalField(max_digits=8,decimal_places=2)
publish_time = serializers.DateField()
# publish = serializers.CharField(source="publish.name") # source 参数可以指定当下显示的字段名关联至模型表里的哪个字段名,当指定了以后当前命名的名字就不能和数据库里相应的字段名相同了
publish = serializers.SerializerMethodField(allow_null=True) # SerializerMethodField的方式,然后下面定义get_字段名的方法,即可在方法体写逻辑代码返回你希望得到值
def get_publish(self,obj): # 这里的obj必传,obj是当前循环到的数据对象
res = PublishSerilizers(instance=obj.publish) # 序列化当前数据对象关联的publish表里的相应数据记录
return res.data authors = serializers.SerializerMethodField(allow_null=True)
def get_authors(self,obj):
authors_list = obj.authors.all() # author与book是多对多关系,所以需要.all()取到所有的记录,就是ORM的方法
res = AuthorSerilizers(instance=authors_list,many=True) #由于是序列化多条记录,指定many=True
return res.data def create(self, validated_data):
ret = models.Book.objects.create(**validated_data) # 用Django ORM的操作将视图层传来的数据新增到数据库
return ret def update(self, instance, validated_data): # instance是数据库原来的对象 validated_data是个字典,装的是校验完成后的需要修改的数据
instance.name = validated_data.get("name")
instance.price = validated_data.get("price")
instance.publish_time = validated_data.get("publish_time")
instance.publish_id = validated_data.get("publish_id")
instance.save() # 逐个替换后保存
instance.authors.set(validated_data.get("authors")) # 修改多对多表记录,修改需要用set([1,2,4])的形式
return instance

视图层

from django.shortcuts import render,HttpResponse

# Create your views here. 以Book信息为例

from rest_framework.views import APIView,Response
from app01 import models
from app01 import myserializers
from app01 import mymodelSer
class Book(APIView):
def get(self,request,*args,**kwargs):
if kwargs.get("type") == 'books': # 根据路由请求过来的方式来判断是查询所有书籍信息还是一本书的信息,这里是查所有的
books = models.Book.objects.all()
many= True # 指定序列化参数,如果是序列化多条数据就是True
elif kwargs.get("id").isdigit(): # 如果查询携带id,那么就查单本书的
books = models.Book.objects.filter(id=kwargs.get("id")).first() #序列化单条数据的数据要.first()
many = False # 指定序列化参数,如果是序列化单条数据就是True res = myserializers.BookSerilizers(instance=books,many=many) # 将数据库取的queryset对象传入自己定义的序列化类进行序列化
return Response(res.data)
pass def post(self,request,**kwargs):
response = {"status_code":100,"msg":"新增成功!"}
ret = myserializers.BookSerilizers(data=request.data,many=False) #反序列化前端传来的数据
if ret.is_valid(): # 数据校验,当执行这句判断时,才会去做校验
print(ret.validated_data) # 校验后的结果,用ret.validated_data,它会过滤掉不属于模型表字段的键值对,包括前端传来的publish,authors,因为在序列化类里面这两个字段用了SerializerMethodField
ret.validated_data["publish_id"] = request.data.get("publish_id") #在创建book对象前需要手动叫publish字段的键值对添加进去,然后创建book记录
res = ret.create(ret.validated_data) # 这里的create方法调用的是我们在BookSerilizers里面重写的父类的create方法
# 在create的时候必须重写父类的create方法,不然就只能用Django ORM新增,在这里的create里面实际上也是用ORM的新增
res.authors.add(*request.data.get("authors")) #手动用ORM新建多对多第三张表的记录
res.save()
response["data"] = myserializers.BookSerilizers(instance=res).data # res 是数据对象,需要序列化得到数据.data获取
return Response(response)
else:
response["status_code"] = 101
response['msg'] = '新增失败!'
response["data"] = ret.errors # 如果校验不成功,错误信息会自动放在errors里,errors = {"name":"局部错误信息",..."detail":"全局错误信息"}
return Response(response)
pass def put(self,request,**kwargs):
response = {"status_code": 200, "msg": "修改成功!"}
obj = models.Book.objects.filter(id = kwargs.get("id")).first()
ret = myserializers.BookSerilizers(instance=obj,data=request.data, many=False) # 修改时需要将原数据对象和前端传来的将要修改的信息传入BookSerilizers反序列化校验
if ret.is_valid(): # 校验成功时
ret.validated_data['publish_id'] = request.data.get("publish_id")
ret.validated_data['authors'] = request.data.get("authors")
res = ret.update(instance=obj,validated_data=ret.validated_data) # 将数据对象和校验后的结果传入更新
response["data"] = ret.validated_data
return Response(response)
else:
response["data"] = ret.errors
return Response(response)
pass def delete(self,request): pass

 

 Serailizer使用总结:定义序列化类继承Serailizer,类中定义与模型表一一对应的字段,然后再定义局部钩子和全局钩子做校验用,重写create和update方法,最后再视图类中实例化序列化类,通过.data取到序列化后的数据

下面我们来看ModelSerailizer的使用:

路由层

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publish/$', views.PublishsView.as_view()),
url(r'^publish/(?P<pk>\d+)/$', views.PublishView.as_view()),
url(r'^book/$', views.BooksView.as_view()),
url(r'^book/(?P<pk>\d+)/$', views.BookView.as_view()),
url(r'^author/$', views.AuthorsView.as_view()),
url(r'^author/(?P<pk>\d+)/$', views.AuthorView.as_view()), ]

模型层

from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.class Publish(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(max_length=15)
address = models.CharField(max_length=255) class Book(models.Model):
title = models.CharField(max_length=64)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish = models.ForeignKey(to='Publish')
authors = models.ManyToManyField(to='Author') class Author(models.Model):
name = models.CharField(max_length=32)
sex = models.IntegerField(choices=((1,'男'),(0,'女'),(2,'保密')),default=1)
info = models.CharField(max_length=255,default='这人很懒,什么都没写!')

序列化组件层

from rest_framework.serializers import Serializer,ModelSerializer
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from app01 import models """
使用步骤:
1、新建序列化类,继承ModelSerializer
2、类中定义和模型表一一对应的字段,这里可以定义class Meta() 然后指定模型表model和 映射字段fields,比Serializer更简洁
-其中类中的名字可以改变,需要在serializers.CharField()的括号中指定source=某个字段,建议映射关系
-外键关系的字段可以用serializers.SerializerMethodField(),需要在下方固定写 get_字段名 的方法,
这里可以写具体逻辑,最终返回结果就是该字段的结果
3、当新增数据的时候不需要重写父类的create方法,这里ModelSerializer做了封装
4、当修改数据的时候不需要重写父类的update方法,这里ModelSerializer做了封装
5、当完成这些配置后就可以在视图类中实例化调用了,序列化的时候序列化,反序列化的时候校验 """ class PublishSerializer(ModelSerializer):
# 自定义序列化类继承ModelSerializer可以在类里面写class Meta()
class Meta(): # 如果不想每个字段都自己写,那么这就是固定写法,在继承serializer中字段必须自己写,这是二者的区别
model = models.Publish # 指定需要序列化的模型表
fields = ("__all__") # 指定需要校验的字段 "__all__" 表示所有字段,也可以指定字段(字段一,字段二)     # exclude = ('name') 和fields用法相反,取除了某个字段以外的字段
    # depth = 1 指定数据跨表深度,2 指跨2两张表,外键关系会取到完整信息 def validate_name(self,value): # 局部钩子 validate_加字段名,需要给定形参,这个形参就是字段值
if value.startswith("sb"):
raise ValidationError("出版社名称含有敏感词汇") # 抛出异常,但这个异常是在errors信息中返回给前端,不会在后端报出
return value # 对哪个字段进行校验之后需要将该字段值返回 def validate_phone(self,value):
if not value.isdigit():
raise ValidationError("出版社联系方式不合法!")
return value def validate(self, attrs): # 全局钩子 做全局性的数据校验,attrs即需要校验的数据{"name":'xxx',...}
name = attrs.get("name")
phone = attrs.get("phone")
address = attrs.get("address")
if (not phone) and (not address):
raise ValidationError("出版社联系方式和地址必须选填一项")
return attrs class BookSerializer(ModelSerializer):
class Meta():
model = models.Book
fields = ('title','price','authors','publish') #指定序列化的字段 #加上以下这一段在get请求数据的时候会拿到关联字段的详细信息,但是在存的时候会报错 ---方便取,不方便存,存需要另外定义反序列化类
#如果去掉下面这一段在get请求的时候会拿到关联字段的id返回前端,存的时候不会报错
# =======================================================
authors = serializers.SerializerMethodField()
def get_authors(self,obj):
res = AuthorSerializer(instance=obj.authors.all(),many=True)
return res.data
publish = serializers.SerializerMethodField()
def get_publish(self,obj):
res = PublishSerializer(instance=obj.publish)
return res.data
# ================================================== def validate_title(self,value): # 局部钩子校验
if value.startswith("sb"):
raise ValidationError("书名不能包含敏感词汇")
return value def validate_price(self,value): # 全局钩子校验
if not value:
raise ValidationError("图书价格不能为空!")
try:
float(value)
except ValueError:
raise ValidationError("请输入合法的图书价格!")
return value class AuthorSerializer(ModelSerializer):
class Meta():
model = models.Author
fields = ('name','sex','info')
# 以下如果自定义sex字段的取值内容,取的时候会取到 '男','女','其他',但存的时候会报错
# 如果不自定义的话,取的是数据库存储的内容 1,0,2 存可以直接通过0,1,2去存,也就是前端只需要传sex的数字值即可存
# ============================================================
sex = serializers.CharField(source="get_sex_display")
# ============================================================

视图层

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models
from app01.Object_Seriailzers import PublishSerializer,BookSerializer,AuthorSerializer # Create your views here.
#出版社接口 class PublishsView(APIView):
def get(self,request,*args,**kwargs):
response = {"status_code":100,"msg":"查询成功!",'data':""}
queryset = models.Publish.objects.all()
# 对多条数据进行序列化需要制定many=True
ret = PublishSerializer(instance=queryset,many=True)
response['data'] = ret.data
return Response(response)
pass def post(self,request,*args,**kwargs):
response = {"status_code":200,'msg':"新增成功!","data":''}
ret = PublishSerializer(data=request.data)
if ret.is_valid(): # 这里会执行所有的校验,系统及自定义
ret.save() # 这里的保存就会执行数据库的保存,不需要去自己写create方法
response['data'] = ret.data #如果是继承原生的Serailizer,获取到过滤后的数据要通过ret.validated_data取
else:
response["status_code"] = 201
response['msg'] = '新增失败!'
response['data'] = ret.errors
return Response(response) pass class PublishView(APIView): def get(self,request,pk,*args,**kwargs):
response = {"status_code":100,'msg':'查询成功!','data':''}
ret = PublishSerializer(models.Publish.objects.filter(pk=pk).first())
response['data'] = ret.data # 取到序列化后的对象
return Response(response)
pass def put(self,request,pk,*args,**kwargs):
response = {"status_code":200,'msg':'修改成功!','data':''}
# 先查出对象
query = models.Publish.objects.filter(pk=pk).first() # 将数据库对象和前端请求的数据交由PublishSerializer序列化
ret = PublishSerializer(instance=query,data=request.data)
if ret.is_valid(): #判断是否校验通过
# 将数据库对象和前端请求的数据交由update更新,update内部已经封装更新和保存操作
# 如果涉及到多表更新或其他复杂操作,可以在PublishSerializer中自定义update方法,update返回的是更新后的对象
data = ret.update(instance=query,validated_data=ret.validated_data)
# 将修改后的数据返回,注意取ret.data是过滤后的数据,如果是继承原生的Serailizer取过滤后的数据是ret.validated_data取
response['data'] = ret.data
else:
response['status_code'] = 201
response['msg'] = '修改失败!'
response['data'] = ret.errors
return Response(response)
pass def delete(self,request,pk,*args,**kwargs):
response = {'status_code':200,'msg':'删除成功!'}
models.Publish.objects.filter(pk=pk).first().delete()
return Response(response)
pass # 图书接口
class BooksView(APIView): def get(self, request,*args,**kwargs):
response = {"status_code":200,'msg':'查询成功!','data':''}
queryset = models.Book.objects.all()
ret = BookSerializer(instance=queryset,many=True)
response['data'] = ret.data
return Response(response) pass def post(self, request,*args,**kwargs):
response = {"status_code": 200, 'msg': '新增成功!', 'data': ''}
ret = BookSerializer(data=request.data)
if ret.is_valid():
obj = ret.save()
response['data'] = ret.data
else:
response['status_code'] = 201
response['msg'] = '新增失败!'
response['data'] = ret.errors
return Response(response)
pass class BookView(APIView): def get(self, request,pk,*args,**kwargs):
response = {"status_code": 200, 'msg': '查询成功!', 'data': ''}
ret = BookSerializer(instance=models.Book.objects.filter(pk=pk).first())
response['data'] = ret.data
return Response(response)
pass def put(self, request,pk):
response = {"status_code": 200, 'msg': '更新成功!', 'data': ''}
query = models.Book.objects.filter(pk=pk).first()
ret = BookSerializer(instance=query,data=request.data)
if ret.is_valid(): # 这里的if也可以不需要,只需要在is_valid()中配置raise_exception=True即可,
                 # 如果校验不通过,内部会直接返回错误信息给前端,下面代码不会走
obj = ret.save()
response['data'] = BookSerializer(instance=obj).data
else:
response['status_code'] = 201
response['msg'] = '更新失败!'
response['data'] = ret.errors
return Response(response) pass def delete(self, request,pk):
response = {"status_code": 200, 'msg': '删除成功!', 'data': ''}
models.Book.objects.filter(pk=pk).first().delete()
return Response(response)
pass # 作者接口
class AuthorsView(APIView):
def get(self,request):
response = {"status_code": 200, 'msg': '查询成功!', 'data': ''} queryset = models.Author.objects.all()
ret = AuthorSerializer(instance=queryset,many=True)
response['data'] = ret.data
return Response(response)
pass def post(self,request):
response = {"status_code": 200, 'msg': '新增成功!', 'data': ''} ret = AuthorSerializer(data=request.data)
if ret.is_valid():
obj = ret.save()
response['data'] = AuthorSerializer(instance=obj).data
else:
response['msg'] = '新增失败!'
response['data'] = ret.errors
return Response(response)
pass class AuthorView(APIView):
def get(self,request,pk,*args,**kwargs):
response = {"status_code": 200, 'msg': '查询成功!', 'data': ''}
ret = AuthorSerializer(instance=models.Author.objects.filter(pk=pk).first())
response['data'] = ret.data
return Response(response)
pass def put(self,request,pk,*args,**kwargs):
response = {"status_code": 200, 'msg': '更新成功!', 'data': ''}
query = models.Author.objects.filter(pk=pk).first()
ret = AuthorSerializer(instance=query, data=request.data)
if ret.is_valid():
obj = ret.save()
response['data'] = ret.data
else:
response['status_code'] = 201
response['msg'] = '更新失败!'
response['data'] = ret.errors
return Response(response)
pass
def delete(self,request , pk, *args, **kwargs):
response = {"status_code": 200, 'msg': '删除成功!', 'data': ''}
models.Author.objects.filter(pk=pk).first().delete()
return Response(response)
pass

ModelSerailizer总结: 在Serailizer的基础上进行了进一步的封装,主要体现在3个地方:

  1、在序列化类中定义字段不需要全部都自己定义映射关系,只需要配置class Meta 里的模型表model 和字段fields

  2、在存和修改的时候不需要在序列化类中实现父类的create和update方法,ModelSerailizer已经做了封装,当然,这是只针对单表的操作,如果涉及多表的操作,我们也可以自己重写create和update方法

  3、在校验数据成功后只需要通过ret.save()即可执行create操作,ret.update即可执行更新操作

这里的坑点:

其实在代码里也总结了,当我们在用SerailizerMethodField()时,可以通过定义方法序列化数据库的关联表数据,加上我们自己的逻辑并得到返回值,但是这样会带来一个问题,在反序列化的时候校验会把这些字段的数据过滤掉,导致create和update出现报错,当然我们可以通过将这些数据添加到validated_data中来达到目的,但这终究不是完美的解决办法,小编才疏学浅,还望有大神路过指点一二

rest_framework之序列化组件的更多相关文章

  1. django rest_framework Serializers 序列化组件

    为什么要用序列化组件 当我们做前后端分离的项目~~我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿 ...

  2. Django1.0和2.0中的rest_framework的序列化组件之超链接字段的处理

    大家看到这个标题是不是有点懵逼,其实我就是想要一个这样的效果 比如我get一条书籍的数据,在一对多的字段中我们显示一个url,看起来是不是很绚! 下面我们就来实现这么一个东西 首先我们一对多字段中的一 ...

  3. Django的rest_framework的序列化组件之serializers.ModelSerializer介绍

    这里的介绍的serializers.ModelSerializer就和我们之前学习的modelform一样 serializers.ModelSerializer如下几个功能 1.序列化queryse ...

  4. Django的rest_framework的序列化组件之序列化多表字段的方法

    首先,因为我们安装了restframework,所以我们需要在django的settings中引入restframework INSTALLED_APPS = [ 'django.contrib.ad ...

  5. 2 APIView与序列化组件

    1.入门 1.1 参考blog 官方文档:http://www.django-rest-framework.org/tutorial/quickstart/#quickstart yuan的Blog: ...

  6. DRF 序列化组件 模型层中参数补充

    一. DRF序列化 django自带有序列化组件,但是相比rest_framework的序列化较差,所以这就不提django自带的序列化组件了. 首先rest_framework的序列化组件使用同fr ...

  7. django rest_framework 序列化组件详解

    为什么要用序列化组件 当我们做前后端分离的项目,我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿到 ...

  8. rest_framework序列化组件

    一.Django自带的序列化组件  ==>对象序列化成json格式的字符串 from django.core import serializers from django.core import ...

  9. rest_framework之ModelViewSet、路由控制、序列化组件快速搭建项目雏形

    以UserInfo表登陆接口为例 ModelViewSet的用法十分简单,定义一个视图类,指定一个模型表,指定一个序列化类即可帮我们完成增删改查等功能 示例: # 视图层 from app01.MyS ...

随机推荐

  1. java 正则《转载》

    Java 正则表达式 正则表达式定义了字符串的模式. 正则表达式可以用来搜索.编辑或处理文本. 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别. 正则表达式实例 一个字符串其实就是一个简 ...

  2. HDU 6134 Battlestation Operational | 2017 Multi-University Training Contest 8

    破结论没听说过,上式推导到第三步的时候有了O(nlogn) 的做法(枚举倍数+1最后前缀和),并且这种做法可以直接应用到向上取整的计算中,详见forever97 但由于d(n)是积性函数,故可O(n) ...

  3. [Luogu] U18202 洞穴遇险

    https://www.luogu.org/problemnew/show/U18202 暴力搜索预期得分3030分左右. 状压预期得分7070分左右. 考虑费用流,将剩余不稳定度和最小转为消除不稳定 ...

  4. http接口测试工具 REST Client

    以下几个工具为常用rest测试工具 1.Postman, 可以下载客户端或者安装浏览器插件 2.Insomnia,window客户端 3.Apizza,在线极客专属的api协作管理工具 ...

  5. idea svn设置忽略提交文件

    1.找到版本控制位置 2.新建变动列表(装载忽略的文件内容) 3. 将默认的变动列表中需要忽略的文件拖入ignored列表下 4. 提交时,选择default即可. 设置完毕之后,可以在提交文件时将之 ...

  6. 查询Oracle正在执行的sql语句及kill被锁的表

    查询Oracle正在执行的sql语句及执行该语句的用户SELECT b.sid oracleID, b.username 登录Oracle用户名, b.serial#, spid 操作系统ID, pa ...

  7. 关于mysql数据库远程访问

    mysql数据库安装默认为只能本地访问,若需远程连接需根据不同的操作系统做一些操作 Windows: 新装的mysql本地无法登录,显示为1045错误 mysql#1045(1045Access de ...

  8. 重读APUE(13)-可靠信号

    在信号产生和传递之间有一段时间间隔,称为信号是未决的: 进程可以设置阻塞信号传递:如果进程产生了一个阻塞的信号,并且对该信号的动作是系统默认或者捕捉该信号,则该进程保持此信号为未决状态,直到该进程对此 ...

  9. OpenCV3.4.1快速集成到Android studio中,10分钟搞定

    OpenCV3.4.1快速集成到Android studio中,10分钟搞定     转载 https://blog.csdn.net/yu540135101/article/details/8259 ...

  10. ShapeDrawable

    形状的Drawable咯,定义基本的几何图形,如(矩形,圆形,线条等),根元素是<shape../> 节点比较多,相关的节点如下: ① <shape>: ~ visible:设 ...