设为首页 收藏本站
查看: 585|回复: 0

[经验分享] 初探PureMVC:使用PHP+MySQL+Flex结合PureMVC框架做了个Flex留言本

[复制链接]

尚未签到

发表于 2015-6-19 10:29:53 | 显示全部楼层 |阅读模式
  PureMVC框架听也听得多了,但自己一直没有着手去弄过。最近有必要学习它了,于是在各种搜索引擎找了一些资料,现在总算对这个框架有所了解。眼高手低是不行的,所以自己动手去实践一下了。OK!弄一个留言本试试看,然后自己再详细地分析了一下,希望对PureMVC框架有更深的一层了解。我写的不是教程哦,是总结。所以哪里写得不好,请原谅,也恳请您能指出哪里不好。下面只介绍了这个留言本在开始时从服务端获取数据的工作流程,先看下面那个流程图,接着奉上详细的代码以及注释,最后提供源文件下载。
DSC0000.png
  
Main.mxml
  





  •    
  •    
  •    
  •    
  •         .errorTip{
  •             fontSize:12;
  •         }
  •    
  •    
  •    
  •         
  •    
  •    
  •    
  •    
  •    
  •    
  •    
  •    

  
ApplicationFacade.as
  


  • package cn.riahome.guestbook.puremvc
  • {
  •     import cn.riahome.guestbook.puremvc.controller.StartupCommand;
  •    
  •     import org.puremvc.as3.interfaces.IFacade;
  •     import org.puremvc.as3.patterns.facade.Facade;

  •     public class ApplicationFacade extends Facade implements IFacade
  •     {
  •         /**
  •          *
  •          * 目前分析途径: Main.mxml -> ApplicationFacade.as
  •          * 完整分析途径: Main.mxml -> ApplicationFacade.as -> StartupCommand.as -> ListTopicProxy.as -> ListPanelMediator.as
  •          *
  •          * 来到这里, 有必要说一下 MVC, 即 Model, View, Controller:
  •          *
  •          * Model:
  •          *     model => 数据! 本人觉得在 pureMVC 里, model 里有两个主角: VO(Value Object) 和 Proxy(代理).
  •          *     VO 是数据的结构, 存储数据的容器. 一条留言(TopicVO)就有ID值(id), 留言时间(addTime), 昵称(username), 内容(content)
  •          *     Proxy 是负责获得数据的. 获得数据的方式有很多种, 可以获得本地数据(swf本身里的数据), 也可以从互联网上获得数据, 当然从服务器上获得数据也是常发生的事情.
  •          *           而从非本地获得数据可以是: http, remote...
  •          *
  •          * View:
  •          *     view => 显示! 顾名思义, view 就是显示的东西. 一切要显示的东西都在这里了. 通常, 它也会有两个主角: UI 和 Mediator(中介器)
  •          *     UI 就是那些要显示的东西, 例如一个显示留言的界面(就是一个component), 一个填写留言的界面(也是一个component)
  •          *     Mediator 最最最重要的任务是处理有关 UI 的逻辑. 比如说更新 UI 上显示的数据, 或者是提交数据, 又或者是验证用户输入的数据
  •          *
  •          * Controller:
  •          *     controller => 逻辑! controller, 里头都是一个命令(Command), 一些算法, 一些逻辑就在这里头完成.
  •          *     Model 的 Proxy 获得数据后, 可能需要把这些数据进行一些处理, 那就交由 Controller 里的那些 Command 处理吧.
  •          *     Model 的 Proxy 只负责着获得数据, 具体的数据处理交给 Controller 的 Command 吧
  •          *     例如: Proxy 获得的数据可能是 变量/值 配对格式的数据, 而我需要的是 xml 格式的, 那就需要实现转化了. 转化过程就交给 command 了.
  •          *
  •          * 总的来说:
  •          *     View 用于显示东西给用户看的, 显示的数据由 Model 提供. 有时候 Model 获得的数据不一定就合 View 的胃口,
  •          *     那么 Model 先把数据交给 Controller 处理好, 处理好后再交给 View 显示出来.
  •          *
  •          * 那么, Model 是在什么时候把数据交给 View 层呢? 又是怎样来交给 View 呢? 就是通过发布 "通知" 来实现的, 这个通知携带着数据. 这是 pureMVC 的消息机制.
  •          *
  •          * 无论您有没有弄懂以上所说的, 都请您先把它记住!
  •          *
  •          * 以下定义了一些通知, 当这个通知发布出去时, 对这个通知感兴趣的 Command 或者 Mediator 会接收这个通知.
  •          *
  •          **/
  •         public static const STARTUP:String = "startup";
  •       
  •         public static const GET_ALL_TOPIC_COMPLETE:String = "getAllTopicComplete"; // ListPanel 对这个通知感兴趣
  •         public static const SELECT_TOPIC:String = "selectTopic"; // DetailPanel 对这个通知感兴趣
  •         public static const INSERT_TOPIC_COMPLETE:String = "insertTopicComplete"; // ListPanel 对这个通知感兴趣
  •       
  •         /**
  •          * 以下这个函数是采用单例模式, 也就是整个 swf 就只有它一个
  •          **/
  •         public static function getInstance():ApplicationFacade
  •         {
  •             if( instance == null ) instance = new ApplicationFacade();
  •             return instance as ApplicationFacade;
  •         }
  •       
  •         /**
  •          * 下面就是启动整个 pureMVC 的函数
  •          * sendNotification() 函数用来发布通知的, 这份通知书里装着数据的.
  •          * 第一个参数是通知书的标题(是一个唯一的标识符), 第二个参数是携带的数据(是MVC三者之间传递的数据).
  •          **/
  •         public function startup( app:Object ):void
  •         {
  •             sendNotification( STARTUP, app );
  •         }
  •       
  •         /**
  •          * 重写这个函数, 您也看到了, 使用 registerCommand() 函数来用注册 command 的.
  •          * 何谓 "注册 Command" 呢? 就是使 "通知" 跟 command 对应起来.
  •          * 下面就是把通知名 STARTUP 跟 StartupCommand 对应起来.
  •          * 在任何时候任何地方, STARTUP 通知被发布了, StarupCommand 就会被执行.
  •          * 每一个 command 里头都有一个 execute() 函数的, execute() 函数的参数由谁来充当呢?
  •          * 就是通知所携带的数据, 也就是上面 sendNotification() 函数的第二个参数.
  •          *
  •          * 好了, 从 Main.mxml 文件里的 creationComplete="facade.startup( this )" 语句中走到这里了,
  •          * 现在得从 registerCommand( STARTUP,  StartupCommand ) 语句中走到 StartupCommand 里了.
  •          * 请您按着 Ctrl 键点击一下 StartupCommand.
  •          **/
  •         override protected function initializeController():void
  •         {
  •             super.initializeController(); // 先调用父类的 initializeController() 方法, 看 pureMVC 源代码可知, 调用这个方法会创建一个单例的 controller, 具体自己看了.
  •             registerCommand( STARTUP,  StartupCommand );
  •         }
  •       
  •     }
  • }
  
StartupCommand.as
  


  • package cn.riahome.guestbook.puremvc.controller
  • {
  •     import cn.riahome.guestbook.puremvc.model.InsertTopicProxy;
  •     import cn.riahome.guestbook.puremvc.model.ListTopicProxy;
  •     import cn.riahome.guestbook.puremvc.view.DetailPanelMediator;
  •     import cn.riahome.guestbook.puremvc.view.InsertPanelMediator;
  •     import cn.riahome.guestbook.puremvc.view.ListPanelMediator;
  •    
  •     import org.puremvc.as3.interfaces.ICommand;
  •     import org.puremvc.as3.interfaces.INotification;
  •     import org.puremvc.as3.patterns.command.SimpleCommand;
  •    
  •     /**
  •      *
  •      * 目前分析途径: Main.mxml -> ApplicationFacade.as -> StartupCommand.as
  •      * 完整分析途径: Main.mxml -> ApplicationFacade.as -> StartupCommand.as -> ListTopicProxy.as -> ListPanelMediator.as
  •      *
  •      * 一旦收到通知 STARTUP 后, 就会执行这个 StartupCommand.
  •      * 收到的通知里头携带着数据, 这个数据作为参数传递给下面那个 execute() 函数了.
  •      *
  •      * 在这里, 主要的功能是注册 Model 里的 Proxy(代理) 和 Controller 里的 Mediator(中介器)
  •      * 看看 execute() 函数里的代码, 无论是注册 Proxy 还是 Mediator, 都是由 facade 对象的 registerProxy() 方法或 registerMediator() 方法完成的
  •      * facade 对象是本类内部的一个家伙, 用来管理 Proxy 和 Mediator 的. 在后面的代码里, 想要重新获得 Proxy 或者 Mediator 都可以通过这个 facade 家伙.
  •      * 是不是对这个 facade 对象感到很奇怪呢!? 如果想知道更多, 就得看 pureMVC 框架的源代码了. 在这里简要说一下:
  •      *     facade 是一个单例对象, 也就是说整个 swf 只有孤独的它一个. 在你写的 Proxy, Mediator 以及 Command 里都会有它的存在. 用它来管理 Proxy 和 Mediator 的.
  •      *     就像最下面那行代码 ( facade.retrieveProxy( ListTopicProxy.NAME ) as ListTopicProxy ).getAllTopic();
  •      *     可以通过使用 retrieveProxy() 方法来找回相应的 Proxy, 要找回某个 Proxy, 就要传递那个 Proxy 的名字进去.
  •      *     类似地, 也有 retrieveMediator() 方法来找回 Mediator.
  •      *     在 facade 内部是使用数组来存放这些 Proxy 和 Mediator 的. 为什么能找到指定的 Proxy 或 Mediator 呢?
  •      *     那是因为每一个 Proxy 或 Mediator 都有它自己的一个名字, 那个数组存储 Proxy 或 Mediator 时, 是使用它们自身的名字来作为键(Key)进行存储的.
  •      *     要找到指定的 Proxy 或 Mediator, 只需知道它的名字就可以了.
  •      **/
  •    
  •     public class StartupCommand extends SimpleCommand implements ICommand
  •     {
  •         /**
  •          * 这个函数要重写啊.
  •          **/
  •         override public function execute(note:INotification):void
  •         {
  •             /**
  •              * 下面两个 Proxy 是用来与服务端通讯的. 它们负责着数据的 获取 或 提交.
  •              * InsertTopicProxy 是用来向服务端提交数据的, ListTopicProxy 是用来获取数据的.
  •              *
  •              * 您可以按着 Ctrl 键点击 ListTopicProxy, 看看它的内部如何
  •              **/
  •             facade.registerProxy( new InsertTopicProxy() );
  •             facade.registerProxy( new ListTopicProxy() );
  •            
  •            
  •             /**
  •              * 记住, Mediator 是负责 UI(就是那些 component)的逻辑部分.
  •              * 不管是数据验证, 更新 UI 所显示的数据, 还是其它乱七八糟的东西, 都由每块UI(就是每块 Component)所对应的 Mediator 来处理的.
  •              * 例如: InsertPanelMediator 负责把对应的 InsertPanel(这是一个 component) 里的数据进行检验(对用户输入的数据进行检验正确与否),
  •              *      检验无误后, 就把数据交给 InsertTopicProxy 写入数据库. 而 UI(一个component) 本身不进行任何的数据处理或逻辑分析等等.
  •              **/
  •             var app:Main = note.getBody() as Main;
  •             facade.registerMediator( new InsertPanelMediator( app.insertPanel ) );
  •            
  •             /**
  •              * 完整分析途径: Main.mxml -> ApplicationFacade.as -> StartupCommand.as -> ListTopicProxy.as -> ListPanelMediator.as
  •              * 先去分析 ListTopicProxy.as 再来看以下那个 ListPanelMediator.
  •              **/
  •             facade.registerMediator( new ListPanelMediator( app.listPanel ) );
  •            
  •             facade.registerMediator( new DetailPanelMediator( app.detailPanel ) );
  •            
  •             /**
  •              * 有些数据是在一开始的时候就需要的, 所以在这里就命令 ListTopicProxy 调用它的方法 getAllTopic() 来取得服务端上的数据.
  •              * 通过 facade 对象的 retrieveProxy() 方法来找回指定的 Proxy.
  •              * 在这里找回了 ListTopicProxy, 因为我把这个 ListTopicProxy 的名字作为参数传递进 retrieveProxy() 方法了.
  •              *
  •              * 以下代码可以拆分为:
  •              * var proxy:ListTopicProxy = facade.retrieveProxy( ListTopicProxy.NAME ) as ListTopicProxy;
  •              * proxy.getAllTopic();
  •              **/
  •             ( facade.retrieveProxy( ListTopicProxy.NAME ) as ListTopicProxy ).getAllTopic();
  •         }
  •     }
  • }
  
ListTopicProxy.as
  


  • package cn.riahome.guestbook.puremvc.model
  • {
  •     import cn.riahome.guestbook.puremvc.ApplicationFacade;
  •     import cn.riahome.guestbook.puremvc.model.vo.TopicVO;
  •    
  •     import flash.net.URLVariables;
  •    
  •     import mx.collections.ArrayCollection;
  •     import mx.controls.Alert;
  •     import mx.messaging.messages.HTTPRequestMessage;
  •     import mx.rpc.events.FaultEvent;
  •     import mx.rpc.events.ResultEvent;
  •     import mx.rpc.http.HTTPService;
  •    
  •     import org.puremvc.as3.interfaces.IProxy;
  •     import org.puremvc.as3.patterns.proxy.Proxy;

  •     public class ListTopicProxy extends Proxy implements IProxy
  •     {
  •         /**
  •          *
  •          * 目前分析途径: Main.mxml -> ApplicationFacade.as -> StartupCommand.as -> ListTopicProxy.as
  •          * 完整分析途径: Main.mxml -> ApplicationFacade.as -> StartupCommand.as -> ListTopicProxy.as -> ListPanelMediator.as
  •          *
  •          * 为这个 Proxy(这里为ListTopicProxy) 起一个名字. 这个名字是唯一的, 且应该定义为静态的常量.
  •          **/
  •         public static const NAME:String = "ListTopicProxy";
  •       
  •         private var httpService:HTTPService;
  •       
  •         public function ListTopicProxy()
  •         {
  •             /**
  •              * 每一个 Proxy 都有一个 data 属性, 用来存储需要传递的数据, 就是用来携带数据的.
  •              * 这里必须先调用父类的构造函数, 把自己的名字和携带的 数据/数据类型 传进父类的构造函数
  •              * 下面传递的第二个参数是一个 ArrayCollection, 当执行 super() 后, data(Object类型)属性就会变为一个 ArrayCollection.
  •              **/
  •             super(NAME, new ArrayCollection() );
  •            
  •             /**
  •              * 在每个 Proxy 里面, 一定要做的事情就是上面的两项: 为自己起一个名字 以及 先调用父类的构造函数
  •              * 然后具体要做的事情, 就根据需要而定了.
  •              * 这里要做的事是: 从服务端获取留言数据, 当获取数据完成后, 就发布一个通知来告诉大家:"我完成了向服务端获取留言数据了,我拥有这些数据".
  •              * 您看看下面的 onResult() 函数, 该函数里有一条语句: sendNotification( ApplicationFacade.GET_ALL_TOPIC_COMPLETE, data ).
  •              * 第一个参数就是通知消息, 以静态常量的方式在 ApplicationFacade 类里定义了.
  •              **/
  •            
  •             httpService = new HTTPService();
  •             httpService.method = mx.messaging.messages.HTTPRequestMessage.GET_METHOD;
  •             httpService.resultFormat = HTTPService.RESULT_FORMAT_XML;
  •             httpService.url = "php/listTopic.php"; // 这里的 url 根据您的虚拟目录不同而不同
  •             httpService.addEventListener( ResultEvent.RESULT, onResult );
  •             httpService.addEventListener( FaultEvent.FAULT, onFault);
  •         }
  •       
  •         private function onResult( event:ResultEvent ):void
  •         {
  •             var arr:ArrayCollection = new ArrayCollection();
  •             var result:XMLList = XML( event.result ).children();
  •            
  •             for( var i:uint = 0; i < result.children().length(); i++)
  •             {
  •                 var o:TopicVO = new TopicVO( result.@id, result.@addTime, result.@username, result );
  •                 arr.addItem( o );
  •             }
  •            
  •             data = arr;
  •             /**
  •              * 通知: 各单位注意, 我完成了向服务端获取留言数据了,我拥有这些数据, 有意者请接收通知!
  •              * 在这个例子里, 希望得到这些数据的当然是 ListPanel.mxml 了.
  •              * 但, 之前已经说过, 取得数据这类的工作并不用 UI(也说是component) 来完成, 这些工作由 UI 的中介器(Mediator)来完成.
  •              * 在这里, ListPanel.mxml 的中介器是 ListPanelMediator.
  •              * 现在, 请您打开 ListPanelMediator.as 文件, 或者在 "分析途经" 路线上退回上一级(也就是 StartupCommand.as 文件),
  •              * 然后找到 facade.registerMediator( new ListPanelMediator( app.listPanel ) ) 这一句,
  •              * 按着 Ctrl 键点击 ListPanelMediator, 进入去看看源码.
  •              *
  •              * 目前 分析途经: Main.mxml -> ApplicationFacade.as -> StartupCommand.as -> ListTopicProxy.as
  •              *
  •              **/
  •             sendNotification( ApplicationFacade.GET_ALL_TOPIC_COMPLETE, data );
  •         }
  •       
  •         private function onFault( event:FaultEvent ):void
  •         {
  •             Alert.show( event.message.toString(), "提示");
  •         }
  •       
  •         public function getAllTopic():void
  •         {
  •             httpService.send( new URLVariables("ran="+Math.random()) ); // 给一个随机参数, 避免缓存
  •         }
  •     }
  • }
  
ListPanelMediator.as
  


  • package cn.riahome.guestbook.puremvc.view
  • {
  •     import cn.riahome.guestbook.puremvc.ApplicationFacade;
  •     import cn.riahome.guestbook.puremvc.model.ListTopicProxy;
  •     import cn.riahome.guestbook.puremvc.view.UI.ListPanel;
  •    
  •     import mx.collections.ArrayCollection;
  •     import mx.events.ListEvent;
  •    
  •     import org.puremvc.as3.interfaces.IMediator;
  •     import org.puremvc.as3.interfaces.INotification;
  •     import org.puremvc.as3.patterns.mediator.Mediator;

  •     public class ListPanelMediator extends Mediator implements IMediator
  •     {
  •         /**
  •          *
  •          * 目前分析途经: Main.mxml -> ApplicationFacade.as -> StartupCommand.as -> ListTopicProxy.as -> ListPanelMediator.as
  •          * 完整分析途径: Main.mxml -> ApplicationFacade.as -> StartupCommand.as -> ListTopicProxy.as -> ListPanelMediator.as
  •          *
  •          * 以下是给自己一个唯一的名字, 通过 facade 对象的 registerMediator() 方法找回自己时, 就得用这个唯一的名字了.
  •          * **/
  •         public static const NAME:String = "ListPanelMediator";
  •       
  •         public function ListPanelMediator( viewComponent:Object )
  •         {
  •             /**
  •              * 调用父类的构造函数, 第一个参数传入自己的名字, 上面只是起了名字, 还没写入户口薄或身份证哩, 调用 super() 后才算是写入户口薄.
  •              * 如果您是按着 "分析途经" 看过来的话, 那您就应该在 StartupCommand.as 里看过, 应该知道每个 UI(component) 都有一个对应的 Mediator.
  •              * 在这里, 这个 ListPanelMediator 就是为那个 ListPanel.mxml 服务的. super() 函数的第二个参数就是指明为哪个 UI(component) 服务.
  •              * 那么参数 viewComponent 是在哪里开始传入的呢? 大家回顾 StartupCommand.as 文件, 在注册 ListPanelMediator 时就已经传入了 app.listPanel.
  •              * app 是 主文件(Main.mxml)的引用, listPanel 是 app 里的一个 UI(component).
  •              * 也就是说, 从一开始在 StartupCommand.as 里注册自己(ListPanelMediator)时, 就已经指明了自己是为哪个 UI(component) 服务的.
  •              *
  •              * 看 "分析途经", 上一级的 ListTopicProxy.as 成功获取服务端的数据后, ListPanel.mxml 急切地想得到那些数据,
  •              * 但 取得数据 这项工作是由它的中介器(就是本类 ListPanelMediator)来完成的.
  •              *
  •              * 上一级的 ListTopicProxy.as 成功获取服务端的数据后, 发布通知, 说已经成功获取数据了.
  •              * 然后到了这里, 在这里是怎样接收那个通知的呢? 又是怎样为对应的 UI(component) 完成上述工作的呢?
  •              * 请看下面的 listNotificationInterests()函数 和 handleNotification()函数. 第一个实现如何接收通知, 第二个实现相应工作.
  •              **/
  •             super( NAME, viewComponent );
  •            
  •             listPanel.dataGrid.addEventListener( ListEvent.ITEM_CLICK, onSelect );
  •         }
  •       
  •         // 通知: 各单位注意, 用户现已选择了一条留言, 需要接收通知的单位请马上接收.
  •         private function onSelect( event:ListEvent ):void
  •         {
  •             sendNotification( ApplicationFacade.SELECT_TOPIC, listPanel.dataGrid.selectedItem );
  •         }
  •       
  •         // 获得对应的 UI(component)
  •         public function get listPanel():ListPanel
  •         {
  •             return viewComponent as ListPanel;
  •         }
  •       
  •         /**
  •          * 在下面的函数里列出了所以感兴趣的通知, 包括: GET_ALL_TOPIC_COMPLETE 和 INSERT_TOPIC_COMPLETE.
  •          * 上一级的 ListTopicProxy.as 成功获取服务端的数据后, 发布这个通知: GET_ALL_TOPIC_COMPLETE.
  •          * 因为本类对这个通知感兴趣, 所以当通知(GET_ALL_TOPIC_COMPLETE)一旦被发布了(不管发布是谁), 本类马上接收了该通知,同时取得该通知所携带的数据.
  •          * 接收到通知后, 就进入最下面的 handleNotification() 函数了.
  •          *
  •          * (只要把感兴趣的通知放入下面函数的数组里, pureMVC 内部就会把通知从发布者送到接收者手上了. 有兴趣可以打开 pureMVC 的源代码看看内部机制)
  •          **/
  •         override public function listNotificationInterests():Array
  •         {
  •             return [
  •                     ApplicationFacade.GET_ALL_TOPIC_COMPLETE,
  •                     ApplicationFacade.INSERT_TOPIC_COMPLETE
  •                     ];
  •         }
  •       
  •         /**
  •          * 以下函数的参数 note 就是那个通知了. 姑且把那个通知叫做通知书, 所以在这个通知书里有两个重要信息: 通知书名称(通知类型) 和 通知书里的内容(通知书所携带的数据).
  •          * 如何分别取得通知(note)的类型和它所携带的数据呢? 可以这样:
  •          *     通知类型: note.getName()
  •          *     通知携带的数据: note.getBody()
  •          *
  •          * 以下函数就是根据接收到的通知类型而采取不同措施. 比如说, 接收到 ListTopicProxy 发布的 GET_ALL_TOPIC_COMPLETE 通知, 于是执行 switch 语句的第一个分支.
  •          * switch 语句的第一个分支的功能是: 更新对应的 UI(这里是 listPanel, 一个component) 里的数据.
  •          * 在 listPanel 里先定义好一个 topicData 变量, 给中介器操作.
  •          * 相当于在 UI 里提供一个接口给中介器操作, 这样就把 表现层(UI) 跟 逻辑层(Mediator) 分开了, 伟人说这是 松偶合 !
  •          *
  •          * 如何取得对应的 UI(component) 呢? 就在上面的那个 getter 函数取得: public function get listPanel():ListPanel{}
  •          *
  •          * 到此为止, 一个完整的 pureMVC 工作原理在 "分析途径" 上算是表现出来了.
  •          * 来到这里, 如果你通过本例子弄懂了 pureMVC 工作原理, 那恭喜您! 也恭喜我! 您是聪明的, 我也是聪明的:)
  •          *
  •          * 欢迎一起交流技术:
  •          *         My Blog : riaoo.com
  •          *         My Email: y_boy@126.com & riahome.cn@gmail.com
  •          **/
  •         override public function handleNotification(note:INotification):void
  •         {
  •             switch( note.getName() )
  •             {
  •                 case ApplicationFacade.GET_ALL_TOPIC_COMPLETE:
  •                     listPanel.topicData = note.getBody() as ArrayCollection;
  •                     break;
  •                
  •                 case ApplicationFacade.INSERT_TOPIC_COMPLETE:
  •                     ( facade.retrieveProxy( ListTopicProxy.NAME ) as ListTopicProxy ).getAllTopic();
  •                     break;
  •             }
  •         }
  •       
  •     }
  • }
  源文件下载:PureMVC_GuestBook.zip

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-78816-1-1.html 上篇帖子: MySQL学习_1--->输入查询 下篇帖子: MySQL定时器Events
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表