本项目是一个系列项目,最终的目的是开发出一个类似京东商城的网站。本文主要介绍后台管理中的区域管理,以及前端基于easyui插件的使用。本次增删改查因数据量少,因此采用模态对话框方式进行,关于数据量大采用跳转方式修改,详见博主后续博文。

后台界面展示:

地区管理包含省市县的管理。详见下文。

一、数据库设计

  1. class Province(Base):
  2. """

  3. """
  4. __tablename__ = 'province'
  5. nid = Column(Integer, primary_key=True)
  6. caption = Column(VARCHAR(16), index=True)
  7.  
  8. class City(Base):
  9. """

  10. """
  11. __tablename__ = 'city'
  12. nid = Column(Integer, primary_key=True)
  13. caption = Column(VARCHAR(16), index=True)
  14. province_id = Column(Integer, ForeignKey('province.nid'))
  15.  
  16. class County(Base):
  17. """
  18. 县(区)
  19. """
  20. __tablename__ = 'county'
  21. nid = Column(Integer, primary_key=True)
  22. caption = Column(VARCHAR(16), index=True)
  23. city_id = Column(Integer, ForeignKey('city.nid'))

  本次采用的是sqlAlchemy模块创建数据库,关于sqlAlchemy的数据库链接以及数据库创建本文不做介绍,详细见Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy(点击进入详细介绍)

表关系分析:上述表关系比较简单,市中有外键,代表这是市是属于哪个省;同理县中也有外键,代表这个县是属于哪个市。

二、目录结构

该目录结构在前面博文【tornado】系列项目(一)之基于领域驱动模型架构设计的京东用户管理后台 中有详细介绍,本博文不再赘述。

三、路由映射

  1.   (r"/ProvinceManager.html$", Region.ProvinceManagerHandler), #省份模板展示
  2. (r"/province.html$", Region.ProvinceHandler), #省份的增删改查
  3. (r"/CityManager.html$", Region.CityManagerHandler), #市模板展示
  4. (r"/City.html$", Region.CityHandler),  #市的增删改查
  5. (r"/CountyManager.html$", Region.CountyManagerHandler), #县的模板展示
  6. (r"/County.html$", Region.CountyHandler),#县的增删改查

四、后台模板展示Handler

#以省份为例进行介绍(市县类似):

数据获取Handler:

  1. class ProvinceManagerHandler(AdminRequestHandler):
  2.  
  3. def get(self, *args, **kwargs):
  4. # 打开页面,显示所有的省
  5. self.render('Region/ProvinceManager.html')

 本Handler主要用于从模板展示,默认如果只有这一个handler,用户看到的将是空页面。关于数据的增删改查,详见下文。

五、核心增删改查操作

再介绍增删改查之前,我们先介绍母板文件layout的前端html和继承该模板的ProvinceManager.html部分JavaScript代码:

母版layout html:

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <link rel="stylesheet" type="text/css" href="/Statics/Admin/Plugins/jquery-easyui/themes/default/easyui.css"> #导入easyui的css
  7. <link rel="stylesheet" type="text/css" href="/Statics/Admin/Plugins/jquery-easyui/themes/icon.css"> #导入easyui的图标
  8. <link rel="stylesheet" type="text/css" href="/Statics/Admin/Css/Common.css"> #自定义css
  9.  
  10. <script type="text/javascript" src="/Statics/Admin/Plugins/jquery-easyui/jquery.min.js"></script>   #导入jQuery
  11. <script type="text/javascript" src="/Statics/Admin/Plugins/jquery-easyui/jquery.easyui.min.js"></script>  #导入easyui的js
  12.  
  13. </head>
  14. <body class="easyui-layout">
  15.  
  16. <div data-options="region:'north'" style="height:50px">
  17.  
  18. </div>
  19. <div data-options="region:'south',split:true" style="height:30px;"></div>
  20. <div data-options="region:'west',split:true" title="后台管理" style="width:200px;">
  21. <div id="aa" class="easyui-accordion" data-options="fit:true,border:false">
  22. <div title="地区管理">  #easyui订制的左侧菜单
  23. <a id="jd_menu_province" class="jd-menu" href="/ProvinceManager.html"></a>
  24. <a id="jd_menu_city" class="jd-menu" href="/CityManager.html"></a>
  25. <a id="jd_menu_county" class="jd-menu" href="/CountyManager.html">县(区)</a>
  26. </div>
  27. <div title="用户管理">
  28. <a id="user" class="jd-menu" href="#">用户管理</a>
  29. <a id="jd_menu_merchant" class="jd-menu" href="/MerchantManager.html">商户管理</a>
  30. </div>
  31. <div title="JD自营">
  32. <a id="jd_menu_product" class="jd-menu" href="/ProductManager.html">产品管理</a>
  33. </div>
  34. </div>
  35. </div>
  36. <div data-options="region:'center'" title="{% block crumbs %} {% end %}"> #内容显示区
  37. {% block content %} {% end %}
  38. </div>
  39.  
  40. </body>
  41. </html>

  省份内容展示区html:

  1. <div>
  2. <table id="dg"></table>   #easyui订制table
  3.  
  4. <div id="dlg" class="easyui-dialog" style="width:400px;height:200px;padding:10px 20px" closed="true" buttons="#dlg-buttons"> #easyui订制模态对话框,默认关闭状态
  5. <form id="fm1">
  6. <div class="input-group clearfix">
  7. <div class="group-label" style="width: 80px;">
  8. <span>省份:</span>
  9. </div>
  10. <div class="group-input" style="width: 300px;">
  11. <input id="dlg_nid" style="width: 200px;display: none" name="nid"/>
  12. <input id="dlg_province" style="width: 200px" class="easyui-textbox" type="text" name="caption" data-options="required:true,missingMessage:'省份不能为空'" /> #easyui订制form验证+错误信息提示
  13. </div>
  14. </div>
  15. </form>
  16. </div>
  17. <div id="dlg-buttons">  #easyui订制按钮
  18. <span id="dlg_summary" style="color: red"></span>
  19. <a href="#" class="easyui-linkbutton" iconCls="icon-ok" onclick="Save()">保存</a>
  20. <a href="#" class="easyui-linkbutton" iconCls="icon-cancel" onclick="javascript:$('#dlg').dialog('close')">取消</a>
  21. </div>
  22. </div>

  JavaScript代码:

  1. $(function () {
  2. // 加载表格数据
  3. InitTable(); #初始化表格内容(即查询)
  4. InitPagination(); #初始化分页
  5. InitMenu(); #初始化左侧菜单
  6.  
  7. });

  首先介绍两个简单的js:

  1. /*
  2. 初始化左侧菜单
  3. */
  4. function InitMenu(){
  5. $('#aa').accordion('select',0); #easyui语法:选择左侧第0个标签
  6. $('#jd_menu_province').addClass('active'); #让省份默认选中
  7. }
  1. /*
  2. 初始化分页
  3. */
  4. function InitPagination(){
  5. var pager = $('#dg').datagrid('getPager');
  6. $(pager).pagination({
  7. beforePageText: '第',
  8. afterPageText: '页 共{pages}页',
  9. displayMsg: '当前显示{from}-{to}条记录 共{total}条数据'
  10.  
  11. })
  12. }

关键的表格数据初始化js(查询js):

  1. function InitTable(){
  2. $('#dg').datagrid({
  3. title: '省份列表',
  4. iconCls: 'icon-save',   #省份图标
  5. url: '/province.html', #获取数据的url
  6. method: 'get',   #获取方式
  7. //fitColumns: true,
  8. idField: 'nid', 
  9. singleSelect: true, #默认单选
  10. rownumbers: true, #显示行号
  11. striped: true, #奇数行与偶数行颜色有区别
  12. columns:[[    #每一列标题(easyui默认根据field将后端传来的数据按表格进行显示)
  13. {
  14. field:'ck',
  15. checkbox:true #显示checkbox
  16. },
  17. {
  18. field:'nid',  #从数据库获取的nid
  19. title:'ID', #显示名称为ID
  20. width:80, #宽度80px
  21. align:'center'  #居中显示
  22. },
  23. {
  24. field:'caption',
  25. title:'标题',
  26. width:180,
  27. align:'center'}
  28. ]],
  29. toolbar: [  #显示的按钮
  30. {
  31. text: '添加', #按钮名称
  32. iconCls: 'icon-add', #按钮图标
  33. handler: AddRow #点击按钮后执行的返回函数
  34. },{
  35. text:'删除',
  36. iconCls:'icon-remove',
  37. handler: RemoveRow
  38. },{
  39. text:'修改',
  40. iconCls:'icon-edit',
  41. handler: EditRow
  42. }
  43. ],
  44. pagePosition: 'both',  #上下均显示分页
  45. pagination:true, #显示分页
  46. pageSize:10, #默认每页显示的数据总数
  47. pageNumber: 1,  #默认第一页
  48. pageList: [10,20,50], #分页可选每页显示数量
  49. loadFilter: function(data){ #过滤函数
  50. return data;
  51.  
  52. }
  53. });
  54. }

  上述js代码即查询时的js代码,接下来我们先看查询的后端业务处理类:

  1. def get(self, *args, **kwargs):
  2. """
  3. 获取
  4. :param args:
  5. :param kwargs:
  6. :return:
  7. """
  8. if self.get_argument('type', None) == 'all': #如果是获取所有数据
  9. ret = {'status': True, 'rows': "",'summary':''}  #将来要返回给前端的字典,包含是否获取成功的状态、获取的数据、错误信息
  10. try:
  11. region_service = RegionService(RegionRepository())  #将数据库处理类的对象传入数据库业务协调类
  12. all_province_list = region_service.get_province() #获取所有省份
  13. ret['rows'] = all_province_list #将省份数据添加进返回前端的字典
  14. except Exception as e:
  15. ret['status'] = False
  16. ret['summary'] = str(e)
  17. self.write(json.dumps(ret)) #返回给前端
  18. else:  #如果是获取分页数据
  19. ret = {'status': True,'total': 0, 'rows': [], 'summary': ''}
  20. try:
  21. rows = int(self.get_argument('rows', 10))#每页显示10
  22. page = int(self.get_argument('page', 1)) #显示第一页
  23. start = (page-1)*rows 开始条数
  24.  
  25. region_service = RegionService(RegionRepository())
  26. row_list = region_service.get_province_by_page(start, rows) #根据分页获取省份数据
  27. row_count = region_service.get_province_count()  #获取省份总数
  28.  
  29. ret['total'] = row_count
  30. ret['rows'] = row_list
  31. except Exception as e:
  32. ret['status'] = False
  33. ret['summary'] = str(e)
  34.  
  35. self.write(json.dumps(ret)) #返回给前端

数据库业务协调处理类的对应操作:

  1. class RegionService:
  2. def __init__(self, region_repository):
  3. self.regionRepository = region_repository
  4.  
  5. def get_province_count(self):
  6. count = self.regionRepository.fetch_province_count() #获取省份总数
  7. return count
  8.  
  9. def get_province_by_page(self, start, offset): #根据分页获取省份
  10.  
  11. result = self.regionRepository.fetch_province_by_page(start, offset)
  12. return result
  13.  
  14. def get_province(self): #获取所有省份
  15. return self.regionRepository.fetch_province()

 数据库操作类相关操作:

  1. class RegionRepository(IRegionRepository):
  2.  
  3. def __init__(self):
  4. self.db_conn = DbConnection() #实例化数据库链接对象(只需创建一次对象,下面所有方法都不需要再创建)
  5.  
  6. def fetch_province(self): #获取所有省份
  7. cursor = self.db_conn.connect()
  8. sql = """select nid,caption from province order by nid desc """
  9. cursor.execute(sql)
  10. db_result = cursor.fetchall()
  11. self.db_conn.close()
  12. return db_result
  13.  
  14. def fetch_province_by_page(self, start, offset): #根据分页获取省份
  15. ret = None
  16. cursor = self.db_conn.connect()
  17. sql = """select nid,caption from province order by nid desc limit %s offset %s """
  18. cursor.execute(sql, (offset, start))
  19. db_result = cursor.fetchall()
  20. self.db_conn.close()
  21. return db_result
  22. def fetch_province_count(self): #获取省份总数
  23. cursor = self.db_conn.connect()
  24. sql = """select count(1) as count from province """
  25. cursor.execute(sql)
  26. db_result = cursor.fetchone()
  27. self.db_conn.close()
  28. return db_result['count']

  以上就是查询操作的所有过程。

增加:

js:

  1. /*
  2. 添加
  3. */
  4. function AddRow(){
  5. // 显示对话框,由于希望添加则将方法设置为POST
  6. $('#fm1').form('clear'); #清空上次form的内容
  7. $('#dlg').dialog('open').dialog('setTitle','创建省份'); #设置模态对话框标签是创建省份
  8. $('#dlg_summary').empty(); #清空错误信息
  9. METHOD = 'post';  #设置提交方式为post
  10. }

  增加操作实际上就做了一个操作:打开模态对话框。

前端页面展示:

 

当用户输入需要添加的省份,接下来点击保存按钮,数据将被写入数据库并在前端显示:

保存的js代码:

  1. /*
  2. 保存按钮
  3. */
  4. function Save(){
  5. var isValid = $('#fm1').form('validate');前端form验证
  6. if(isValid){
  7. $.ajax({
  8. url: '/province.html', #提交的url
  9. type: METHOD,  #根据之前定义的方法进行提交
  10. data: {caption: $('#dlg_province').val(),nid: $('#dlg_nid').val()}, #提交的数据
  11. dataType: 'json', #数据格式
  12. success: function(data){ #如果后端成功返回数据
  13. if(data.status){ #后端操作成功
  14. $('#fm1').form('clear'); #清空form内容
  15. $('#dlg').dialog('close'); #关闭模态对话框
  16. $('#dg').datagrid('reload'); #重新加载数据
  17. }else{
  18. $('#dlg_summary').text(data.summary); #否则显示错误信息
  19. }
  20. }
  21. })
  22. }else{
  23. // 前端验证通过
  24. }
  25. // $('#fm').form('clear');
  26. }

  增加对应的后端业务处理方法:

  1. def post(self, *args, **kwargs):
  2. """
  3. 添加
  4. :param args:
  5. :param kwargs:
  6. :return:
  7. """
  8. ret = {'status': False, 'summary': ''}
  9. caption = self.get_argument('caption', None)
  10. if not caption:
  11. ret['summary'] = '省份不能为空'
  12. else:
  13. try:
  14.  
  15. region_service = RegionService(RegionRepository())
  16. result = region_service.create_province(caption) #创建省份,如果省份已存在,返回None
  17. if not result:
  18. ret['summary'] = '省份已经存在'
  19. else:
  20. ret['status'] = True #操作成功
  21. except Exception as e:
  22. ret['summary'] = str(e)
  23.  
  24. self.write(json.dumps(ret)) #返回给前端

 数据库协调处理类对应的方法:

  1. def create_province(self, caption):
  2. exist = self.regionRepository.exist_province(caption)#先判断省份是否存在,如果存在,该方法返回值为None
  3. if not exist:
  4. self.regionRepository.add_province(caption) #创建省份
  5. return True

 数据库对应操作:

  1. def exist_province(self, caption): #省份是否存在
  2. cursor = self.db_conn.connect()
  3. sql = """select count(1) as count from province where caption=%s """
  4. cursor.execute(sql, (caption,))
  5. db_result = cursor.fetchone()
  6. self.db_conn.close()
  7.  
  8. return db_result['count']
  9.  
  10. def add_province(self, caption):  #创建省份
  11. cursor = self.db_conn.connect()
  12. sql = """insert into province (caption) values(%s)"""
  13. effect_rows = cursor.execute(sql, (caption,))
  14. self.db_conn.close()
  15. return effect_rows

  以上就是省份添加的全部过程。

修改:

实际上修改和添加基本上是一样的,接下来只介绍与添加不同的地方:

js:

  1. /*
  2. 修改
  3. */
  4. function EditRow(){
  5. // 显示对话框,由于希望修改则将方法设置为PUT
  6.  
  7. // 获取选中的值,将其赋值到页面上,然后ajax提交
  8. var row = $('#dg').datagrid('getSelected');
  9. $('#dlg_summary').empty();
  10. if(row){
  11. METHOD = 'put';
  12. $('#fm1').form('clear');
  13. $('#fm1').form('load',row);
  14. $('#dlg').dialog('open').dialog('setTitle','修改省份');
  15.  
  16. }else{
  17. $.messager.alert('警告', '请选择要修改的行', 'warning');
  18. }
  19.  
  20. }

  这里弹出模态对话框,与添加不同的是,修改需要将用户原有数据存放在input标签中,方便用户进行修改。同时,将提交方法修改为put。

修改模态对话框示例截图:

接下来用户修改完成后的点击保存,关于保存的js代码详见上文添加部分。

保存的后台业务处理handler方法:

  1. def put(self, *args, **kwargs):
  2. """
  3. 更新
  4. :param args:
  5. :param kwargs:
  6. :return:
  7. """
  8. ret = {'status': False, 'summary': ''}
  9. nid = self.get_argument('nid', None)
  10. caption = self.get_argument('caption', None)
  11. if not caption or not nid:
  12. ret['summary'] = '省份不能为空'
  13. else:
  14. try:
  15.  
  16. region_service = RegionService(RegionRepository())
  17. result = region_service.modify_province(nid, caption)
  18.  
  19. if not result:
  20. ret['summary'] = '省份已经存在'
  21. else:
  22. ret['status'] = True
  23. except Exception as e:
  24. ret['summary'] = str(e)
  25. self.write(json.dumps(ret))

  该方法与添加时的方法基本一致,这里不做过多介绍。

数据库协调处理类对应的方法:

  1. def modify_province(self, nid, caption):
  2. exist = self.regionRepository.exist_province(caption)
  3. if not exist:
  4. self.regionRepository.update_province(nid, caption) #更新省份
  5. return True

数据库操作对应类的方法:

  1. def update_province(self, nid, caption):#更新省份
  2. cursor = self.db_conn.connect()
  3. sql = """update province set caption=%s where nid=%s """
  4. effect_rows = cursor.execute(sql, (caption, nid,))
  5. self.db_conn.close()
  6. return effect_rows

  以上就是省份数据修改的全部过程。

删除:

js:

  1. /*
  2. 删除
  3. */
  4. function RemoveRow(){
  5. // 获取已经选中的行
  6. var rows = $('#dg').datagrid('getSelections');
  7. console.log(rows);
  8. if(rows.length<=0){
  9. // 警告框
  10. $.messager.alert('警告', '请选择要删除的行', 'warning');
  11. }else if(rows.length>1){
  12. $.messager.alert('警告', '不支持批量删除');
  13. }else{
  14. // 确认框
  15. $.messager.confirm('确定', '您确定要删除吗?', function (status) { #easyui订制的确认框
  16. if(status){
  17. // 点击确定
  18. // 获取当前选中行的值,Ajax发送到后台
  19. var row = rows[0];
  20. $.ajax({
  21. url: 'province.html',
  22. type: 'delete',
  23. data: {nid: row.nid},
  24. dataType: 'json',
  25. success: function (data) {
  26. if(data.status){
  27. //删除成功
  28. $.messager.show({ #easyui订制的messager框
  29. msg:'删除成功',
  30. showType:'slide', #淡出
  31. showSpeed: 500, #速度
  32. timeout: 5, #显示5秒
  33. style:{
  34. right:'',
  35. top:document.body.scrollTop+document.documentElement.scrollTop, #在屏幕上方显示
  36. bottom:''
  37. }
  38. });
  39. // 重新加载表格
  40. var rowIndex = $('#dg').datagrid('getRowIndex', row);
  41. $('#dg').datagrid('deleteRow',rowIndex);
  42. $('#dg').datagrid('reload');
  43.  
  44. // 删除指定行
  45. //var rowIndex = dt.datagrid('getRowIndex', row);
  46. //dt.datagrid('deleteRow',rowIndex);
  47.  
  48. }else{
  49. //删除失败
  50. // $.messager.alert('错误信息', data.summary ,'error');
  51. $.messager.show({ #显示错误信息
  52. icon: 'error',
  53. title:'错误信息',
  54. msg:data.summary,
  55. showType:'slide',
  56. timeout: 0,
  57. style:{
  58. right:'',
  59. top:document.body.scrollTop+document.documentElement.scrollTop,
  60. bottom:''
  61. }
  62. });
  63. }
  64. }
  65. });
  66. }
  67. })
  68. }
  69. }

  后台handler类对应方法:

  1. def delete(self, *args, **kwargs):
  2. """
  3. 删除
  4. :param args:
  5. :param kwargs:
  6. :return:
  7. """
  8. ret = {'status': False, 'summary': ''}
  9.  
  10. nid = self.get_argument('nid', None)
  11.  
  12. if not nid:
  13. ret['summary'] = '请选择要删除的省份'
  14. else:
  15. # 调用service去删除吧...
  16. # 如果删除失败,则显示错误信息
  17. try:
  18. region_service = RegionService(RegionRepository())
  19. region_service.delete_province(nid) #根据nid删除省份
  20. ret['status'] = True
  21. except Exception as e:
  22. ret['summary'] = str(e)
  23. self.write(json.dumps(ret))

  数据库业务协调处理类对应的方法:

  1. def delete_province(self, nid):
  2.  
  3. self.regionRepository.remove_province(nid)

  数据库操作类对应方法:

  1. def remove_province(self, nid):
  2. cursor = self.db_conn.connect()
  3. sql = """delete from province where nid=%s """
  4. effect_rows = cursor.execute(sql, (nid,))
  5. self.db_conn.close()
  6. return effect_rows

  以上就是删除的全部过程。

总结:本文主要以省份的增删改查为例介绍了前端easyui的使用,后端handler、数据库业务协调处理类、数据库操作类的整个流程。下节我们将介绍市县管理中与省份不同的部分,欢迎下次收看!如果本文对您有参考价值,欢迎帮博主点下文章下方的推荐,谢谢!

【tornado】系列项目(二)基于领域驱动模型的区域后台管理+前端easyui实现的更多相关文章

  1. 【tornado】系列项目(一)之基于领域驱动模型架构设计的京东用户管理后台

    本博文将一步步揭秘京东等大型网站的领域驱动模型,致力于让读者完全掌握这种网络架构中的“高富帅”. 一.预备知识: 1.接口: python中并没有类似java等其它语言中的接口类型,但是python中 ...

  2. 【Python之路】特别篇--基于领域驱动模型架构设计的京东用户管理后台

    一.预备知识: 1.接口: - URL形式 - 数据类型 (Python中不存在) a.类中的方法可以写任意个,想要对类中的方法进行约束就可以使用接口: b.定义一个接口,接口中定义一个方法f1: c ...

  3. 领域驱动模型DDD(二)——领域事件的订阅/发布实践

    前言 凭良心来说,<微服务架构设计模式>此书什么都好,就是选用的业务过于庞大而导致代码连贯性太差,我作为读者来说对于其中采用的自研框架看起来味同嚼蜡,需要花费的学习成本实在是过于庞大,不仅 ...

  4. 基于领域驱动设计(DDD)超轻量级快速开发架构(二)动态linq查询的实现方式

    -之动态查询,查询逻辑封装复用 基于领域驱动设计(DDD)超轻量级快速开发架构详细介绍请看 https://www.cnblogs.com/neozhu/p/13174234.html 需求 配合Ea ...

  5. CRL快速开发框架系列教程二(基于Lambda表达式查询)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  6. 基于领域驱动设计(DDD)超轻量级快速开发架构

    smartadmin.core.urf 这个项目是基于asp.net core 3.1(最新)基础上参照领域驱动设计(DDD)的理念,并参考目前最为了流行的abp架构开发的一套轻量级的快速开发web ...

  7. 领域驱动模型DDD(一)——服务拆分策略

    前言 领域驱动模型设计在业界也喊了几年口号了,但是对于很多"务实"的程序员来说,纸上谈"术"远比敲代码难得太多太多.本人能力有限,在拜读相关作品时既要隐忍书中晦 ...

  8. vue-小爱ADMIN系列文章(二):微信微博等分享,国际化,前端性能优化,nginx服务器部署

    最近在做我的小爱ADMIN后台管理系统,结合当前市场后台管理系统对相关功能的需求,我又开始新增了一些新的功能和组件,如分享功能组件,项目国际化功能:项目完成后,部署在nginx服务器,发现首次访问的速 ...

  9. 并发系列(二)----Java内存模型

    一 简介 在并发编程中,两个线程(A.B)同时操作一个普通变量的时候会出现线程A在操作变量时线程B也将变量操作了,此时线程A是无法感知变量发生变化的,造成变量改变错误.更据以上例子我们需要解决的问题就 ...

随机推荐

  1. 构建自己的 Linux 发行版

    如何用 SUSE Studio 构建 Linux 发行版? (1) 进入到 www.susestudio.com,设立一个帐户 (2) 为你的设备(发行版)选择一个基本模板 -软件和软件包选择 (1) ...

  2. ORB-SLAM(四)追踪

    最近在读ORB-SLAM的代码,虽然代码注释算比较多了,但各种类和变量互相引用,看起来有点痛苦.索性总结了一下Tracking部分的代码结构,希望能抓住主要思路,不掉坑里. 追踪 追踪部分的主要思路是 ...

  3. ETL基础1(概念)

    抽取(Extract): 一般抽取过程需要连接到不同的数据源,以便为随后的步骤提供数据.这一部分看上去简单而琐碎,实际上它是 ETL 解决方案的成功实施的一个主要障碍. 转换(Transform): ...

  4. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

  5. java分析源码-ReentrantLock

    一.前言 在分析了 AbstractQueuedSynchronier 源码后,接着分析ReentrantLock源码,其实在 AbstractQueuedSynchronizer 的分析中,已经提到 ...

  6. Kakfa重连测试

    在Kafak已启动的情况下: 发送端首次连接大概耗时400毫秒.后续消息发送都在1毫秒以下. 接收端首次连接大概耗时400-7000毫秒.后续消息接收都在1毫秒以下.(具体时间与topic中存留的消息 ...

  7. [Unity3D]添加音效说明

    添加音效组件并添加音乐资源 其中Pitch用来提高和降低音调的,比如可以和赛车游戏的轮胎绑定,当轮胎越快,则音调越高 2D/3D音效:2D音效和摄影家的距离无关,可以看做是一个背景音乐:而3D音效则是 ...

  8. 关于linux asp.net MVC网站中 httpHandlers配置无效的处理方法

    近期有Jexus用户反映,在Linux ASP.NET MVC网站的Web.config中添加 httpHandlers 配置用于处理自定义类型,但是在运行中并没有产生预期的效果,服务器返回了404( ...

  9. storyboard传值方式

    通过segue传值 在storyboard设置segue的Identifier   segue是连接两个视图控制器交互的线 sender是触发这个方法执行的对象,比如是单击tableView上的cel ...

  10. Filter体现职责链模式

    1. 前言 Filter—Filter 技术是servlet2.3 新增加的功能.完成的流程:对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后 ...