web随性笔记01

来源:互联网 发布:php小型博客开源框架 编辑:程序博客网 时间:2024/06/04 19:00
一,Window于Document区别:
         
    不要混淆Window对象的location属性和Document对象的location属性。前者引用一个Location对象,而后者只是一个只读字符串,并不具有Location对象的任何特性。document.location与document.URL是同义的,后者在 JavaScript1.1中是该属性的首选名称(因为这样避免了潜在的混淆)。在大多数情况下,document.location和 location.href是相同的。但是,当存在服务器重定向时,document.location包含的是已经装载的URL,而 location.href包含的则是原始请求的文档的URL。

二,asp.NET脚本跳出对话框:
      <p>对话框有三种</p>
<p>1:只是提醒,不能对脚本产生任何改变;</p>
<p>2:一般用于确认,返回 true 或者 false ,所以可以轻松用于 ifelse判断 </p>
<p>3: 一个带输入的对话框,可以返回用户填入的字符串,常见于某些留言本或者论坛输入内容那里的 插入UBB格式图片 </p>
<p>下面我们分别演示:</p>
<p>演示一:提醒 对话框</p>
<p>
  <input type="submit" name="Submit" value="提交" onclick="ale()" />
</p>
<p>演示二 :确认对话框 </p>
<p>
  <input type="submit" name="Submit2" value="提交" onclick="firm()" />
</p>
<p>演示三 :要求用户输入,然后给个结果</p>
<p>
  <input type="submit" name="Submit3" value="提交" onclick="prom()" />
</p>
</body>
</html>

三,ASP.Net页面生命周期描述

下面是ASP.NET页面初始的过程:
1. Page_Init();
2. Load ViewState;
3. Load Postback data;
4. Page_Load();
5. Handle control events;
6. Page_PreRender();
7. Page_Render();
8. Unload event;
9. Dispose method called; 
下面对其中的一些过程作下描述:
1. Page_Init();
这个过程主要是初始化控件,每次页面载入执行这个初始过程,包括第一次和以后的Postback(这里说下Postback,其实就可以简单理解成用户点击 SUBMIT按钮之类的,把表单<Form>提交给服务器,这就是一次postback),在这里面可以访问控件,但是这里面的控件值不是我们期待的控件里面的值,他只是一个控件的初始值(默认值),举例: 比如一个TextBox1,我们填入了"哈哈",在点击SUBMIT提交了页面后,在Page_Init()里面,我们访问到的 TextBox1.Text不是我们的"哈哈",而是开始的""空字符串,如果TextBox1在我们设计的时候提供了默认值,这里访问到的也就是提供的默认值,为什么呢,这就要看下一个过程了.

对应的事件Page.Init

2. Load ViewState
这个过程是载入VIEWSTATE和Postback数据,比如我们上面的TextBox1,这时就赋了"哈哈",所以,在Post_Init()对控件赋值是无意义的,它都会在这个过程里被改写,当然第一次页面载入例外,因为没有VIEWSTATE数据。

没有对应的事件

3.Load Postback data;
上面说了,Postback可以理解成用户提交表单数据,所以这里就是处理表单数据,当然这里要设计到控件的设计,一般情况不会要我们自己处理这个过程,我们暂且略过.

没有对应的事件
4. Page_Load();
这个过程也是每次页面载入时一定会执行的,但是注意和Page_Init的区别,上面已经涉及了,这里注意的是一般都会用到Page.IsPostBack,该值指示该页是否正为响应客户端回发而加载,或者它是否正被首次加载和访问。
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
  //第一次执行的CODE HERE
}
else
{
  //用户提交FORM(即Postback)CODE HERE
}

//每次这里的都会执行CODE HERE
}

对应的事件Page.Load

5. Handle control events;
这个过程里,相应具体的控件事件,比如private void ListBox1_SelectedIndexChanged(object sender, System.EventArgs e)事件等等

没有对应的事件(我们自己的事件函数都包括在这个过程里比如上面的ListBox1_SelectedIndexChanged)

6. Page_PreRender();
预先呈递对象,这里是在向用户程序呈现数据的倒数第二步,提供这个过程的意义,就是在这里能对控件属性等等要呈现给用户的数据进行修改,这也是最后的修改, 以前的修改(比如在Page_Init里面)都可能被覆盖.做完这了还会进行一个操作就是保存状态,即SaveViewState.

对应的事件时Page.PreRender

7. Page_Render();
可以在浏览器里View->Source查看到,每个页面都有一个隐藏的<input>,其中的"__VIEWSTATE"就是服务器写回来的页面状态信息,在这个之前,服务器要呈现页面(也就是构造HTML格式的文件),就是从这个"__VIEWSTATE"里面获取的数据,当然也会注意到,这里有个Page.Render事件,可以添加自己的处理代码,也就是说在这里又可以更改数据,不推荐在这里修改,既然提供了PreRender, 就应该在里面做最后的修改,当然这不是必须的,只是推荐!

对应的事件Page.Render

8. Unload event;
当向服务器请求一个对象的时候,会在内存里生成一个继承页面对象,也就是页面的类,它继承自System.Web.UI.Page.
当页面对象从内存中卸载时发生,将触发该事件.

对应的事件Page.Unload

9. Dispose method called;
销毁所有的对象.当从内存释放Page时发生,这是生存期的最后阶段。可能第8和9似乎有些模糊,不过我也没怎么搞清楚,待研究!

对应的事件Dispose

以上就是ASP.NET页面周期的描述。


四,ibatis执行insert返回主键的设置方法:
    在<insert id="Insert" parameterClass="SysAuthUsers">
      </insert>里添加<selectKey resultClass="int" type="post" property="Id" >
                select @@IDENTITY as value
            </selectKey>
    需要注意的地方:<selectKey>里的property的值必须跟
<resultMaps>
        <resultMap id="FullResultMap" class="SysAuthUsers">
            <result property="Id" column="ID" dbType="Int"/>
            <result property="Code" column="Code" dbType="NVarChar"/>
            <result property="Username" column="UserName" dbType="NVarChar"/>
            <result property="Password" column="PassWord" dbType="NVarChar"/>
            <result property="Roles" column="Roles" dbType="NVarChar"/>
            <result property="Depid" column="DepID" dbType="NVarChar"/>
            <result property="Typeid" column="TypeID" dbType="NVarChar"/>
            <result property="Dutyid" column="DutyID" dbType="NVarChar"/>
            <result property="Issys" column="IsSys" dbType="Bit"/>
            <result property="Ulock" column="ULock" dbType="Bit"/>
        </resultMap>
    </resultMaps>里的property同名,ibatis是区分大小写的。

五,ibatis执行insert语句判断是否执行成功的两种方法:
   (1)通过执行return sqlMap.Insert(NAME_SPACE + "Insert", userRntity);判断返回的数据库主键,如果返回的是null表示insert失败,否则insert成功,因为主键有int和string等多种类型所以返回值是object类型。
   (2)执行调用sqlMaps[i].Update(statementName, parameterObject);方法,虽然调用的是update方法,但是却是执行的insert语句,注意xml文件的节点写法:(因为是用id属性所以有两个<update>没有关系)。
     <update id="Insert" parameterClass="SysAuthUsers">
            INSERT INTO [dbo].[sys_auth_Users] (
              [Code]
            , [UserName]
            , [PassWord]
            , [Roles]
            , [DepID]
            , [TypeID]
            , [DutyID]
            , [IsSys]
            , [ULock]
            ) VALUES (
              #Code,dbType=NVarChar#
            , #Username,dbType=NVarChar#
            , #Password,dbType=NVarChar#
            , #Roles,dbType=NVarChar#
            , #Depid,dbType=NVarChar#
            , #Typeid,dbType=NVarChar#
            , #Dutyid,dbType=NVarChar#
            , #Issys,dbType=Bit#
            , #Ulock,dbType=Bit#
            )
      </update>

        <update id="Update" parameterClass="SysAuthUsers">
            UPDATE [dbo].[sys_auth_Users] SET
            [Code] = #Code,dbType=NVarChar#
            , [UserName] = #Username,dbType=NVarChar#
            , [PassWord] = #Password,dbType=NVarChar#
            , [Roles] = #Roles,dbType=NVarChar#
            , [DepID] = #Depid,dbType=NVarChar#
            , [TypeID] = #Typeid,dbType=NVarChar#
            , [DutyID] = #Dutyid,dbType=NVarChar#
            , [IsSys] = #Issys,dbType=Bit#
            , [ULock] = #Ulock,dbType=Bit#
            WHERE
            ([ID] = #Id,dbType=Int#)
        </update>

六,Ibatis.net里的缓存解决方案:
        IBatis.Net学习笔记四--数据库的缓存模式

在IBatis中提供了数据库缓存的模式,可以提高访问效率。对于一些不常更新的表可以直接利用IBatis的缓存方式。

要使用IBatis的数据库缓存,只要利用配置文件就可以了,实现起来比较简单:
        <select id="GetCachedAccountsViaResultMap"
                    resultMap="account-result"
                    cacheModel="account-cache" >
            select *
            from Accounts
            order by Account_ID
        </select>
最主要的就是cacheModel="account-cache",指定缓存的方式,如下,是具体配置缓存的地方:
    <cacheModels>
        <cacheModel id="account-cache" implementation="MEMORY" >
            <flushInterval hours="24"/>
            <flushOnExecute  statement="UpdateAccountViaInlineParameters"/>
            <flushOnExecute  statement="UpdateAccountViaParameterMap"/>
      <flushOnExecute  statement="InsertAccountViaParameterMap"/>
      <property name="Type" value="Weak"/>
        </cacheModel>        
    </cacheModels>

其中:implementation="MEMORY"是设置缓存的实现方式,可以指定LRU、FIFO等,有点类似于内存的页替换策略。MEMORY是最常使用的一种方式。

flushOnExecute设置的是当执行了这些语句时更新缓存。

配置好之后我进行了一个简单的测试,基本上是可以的,但也有一点问题:
1、第一次查询结果是4条记录,当我手工往数据库中插入一条记录时,第二次查询还是4条记录
2、当我把系统时间改成第二天(24小时后),再查,得到的结果是5条记录
3、当我执行了InsertAccountViaParameterMap语句插入一条记录时,再查询得到的是6条记录

也就是说:当系统中的表从不进行手工维护,也不由第三方程序修改时,可以使用数据库缓存的方式提高效率。



七,ibatis下用memocache替换掉ibatis自身的缓存解决方案:momocache的优点参见八,momocache的优点
    近有个项目, 使用Ibatis.net需要部署在负载均衡的环境下, 显然Ibatis.net的内置缓存方式, 是不能适用的.

多个Web服务器之间的缓存不能进行同步是问题的关键. 于是决定扩展他的缓存策略, 使用MemCached.

Ibatis.net现有的缓存方式有: MEMORY, LRU, FIFO, 我们扩展一个叫MemCached的方式.

1. 实现一个ICacheController类, 先要下载一个MemCaced的客户端,

我使用的是enyim.com memcached 1.2.0.2的客户端.

    /// <summary>
    /// 使用MemCached做分布式缓存
    /// </summary>
    public class MemCachedController : ICacheController
    {
        MemcachedClient _mc = null;
        private int _cacheSize = 0;
        private IList _keyList = null;

        /// <summary>
        ///
        /// </summary>
        public MemCachedController()
        {
            _mc = new MemcachedClient();
            _cacheSize = 100;
            _keyList = ArrayList.Synchronized(new ArrayList());
        }

        #region ICacheController Members
        /// <summary>
        ///
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object this[object key]
        {
            get
            {
                _keyList.Remove(key);
                _keyList.Add(key);
                return _mc.Get(key.ToString());
            }
            set
            {
                _mc.Store(StoreMode.Set, key.ToString(), value);
                _keyList.Add(key);
                if (_keyList.Count > _cacheSize)
                {
                    object oldestKey = _keyList[0];
                    _keyList.Remove(0);
                    _mc.Remove(oldestKey.ToString());
                }
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object Remove(object key)
        {
            //object o = _mc.Get(key.ToString());
            _keyList.Remove(key);
            _mc.Remove(key.ToString());
            return null;
        }

        /// <summary>
        ///
        /// </summary>
        public void Flush()
        {
            //_mc.FlushAll();
            foreach (object arr in _keyList)
            {
                _mc.Remove(arr.ToString());
            }
            _keyList.Clear();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="properties"></param>
        public void Configure(System.Collections.IDictionary properties)
        {
            string size = (string)properties["CacheSize"];
            if (size != null)
            {
                _cacheSize = Convert.ToInt32(size);
            }       
        }

        #endregion
    }

如上, 比较简单.

 

2. 第二步在DomSqlMapBuilder类中注册我们的新缓存类型.

            // xionglx添加的使用MemCached

            cacheAlias = new TypeAlias(typeof(MemCachedController));

            cacheAlias.Name = "MEMCACHED";

            _configScope.SqlMapper.TypeHandlerFactory.AddTypeAlias(cacheAlias.Name, cacheAlias);

 

3. 在SqlMap.xsd配置文件中注册新的类型,

<xs:simpleType>

       <xs:restriction base="xs:NMTOKEN">

                <xs:enumeration value="LRU"/>

                <xs:enumeration value="MEMORY"/>

                <xs:enumeration value="FIFO"/>

                <xs:enumeration value="MEMCACHED"/>

        </xs:restriction>

</xs:simpleType>

 

4. Web.Config中添加配置.

        <!--memcached-->
        <sectionGroup name="enyim.com">
            <section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
        </sectionGroup>

<enyim.com>
        <memcached>
            <servers>
                <add address="127.0.0.1" port="11211" />
                <!--<add address="127.0.0.1" port="20004" />-->
            </servers>
            <socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:10:00" deadTimeout="00:02:00" />
        </memcached>
    </enyim.com>

 

经过测试, 可以正常的访问MemeCached服务端,  并且缓存正常.

需要注意的是, 实体类需要标记为可序列化.  在Map文件的缓存策略中,

<cacheModels>
        <cacheModel id="ModuleCache"  implementation="MEMCACHED"  readOnly="false">
            <flushInterval hours="24"/>
            <flushOnExecute  statement="Module.Insert"/>
            <flushOnExecute  statement="Module.Update"/>
            <flushOnExecute  statement="Module.Delete"/>
            <property name="CacheSize" value="100"/>
        </cacheModel>
    </cacheModels>

不能使用serialize="true", 反序列化的时候会出错, 我还没仔细查原因. 这里readOnly="false"是说, 这个对象是

会发生更改的, 只有那些系统初始化后, 不会发生变化的数据,才设置成readOnly="true".



八,momocache的优点于却缺点:
   Memcached 是“分布式”的内存对象缓存系统,那么就是说,那些不需要“分布”的,不需要共享的,或者干脆规模小到只有一台服务器的应用,memcached不会带来任何好处,相反还会拖慢系统效率,因为网络连接同样需要资源,即使是UNIX本地连接也一样。在我之前的测试数据中显示,memcached本地读写速度要比直接PHP内存数组慢几十倍,而APC、共享内存方式都和直接数组差不多。可见,如果只是本地级缓存,使用memcached是非常不划算的。

  使用方法:
  Memcached的使用
一 Memcached服务器端的安装 (此处将其作为系统服务安装)
  下载文件:memcached 1.2.1 for Win32 binaries (Dec 23, 2006)
   1 解压缩文件到c:/memcached
   2 命令行输入 'c:/memcached/memcached.exe -d install' 
   3 命令行输入 'c:/memcached/memcached.exe -d start' ,该命令启动 Memcached ,默认监听端口为 11211
  通过 memcached.exe -h 可以查看其帮助
0 0