引用请注明http://www.cnblogs.com/13590/archive/2013/03/14/2958735.html 

摘要:查询是数据库SQL语言的核心,本文介绍了通过iBatis.Net对数据库的简单查询、条件查询、动态查询和多表查询。

关键词:iBatis.Net;动态查询;多表查询;数据映射

查询是数据库SQL语言的核心,SQL语言只提供唯一一个用于数据库查询的语句,即SELECT语句。用于表达SQL查询的SELECT语句是功能最强也是最复杂的SQL语句。而在实际的项目开发过程中,查询占了一个很大的比重,通常衡量一个框架的好坏也很大程度上取决于该框架对查询的灵活性和效率。本节介绍在iBatis.Net中提供的数据库查询方式。

在上节建立的项目文件中新添加Maps/Test3.xml和Test3.aspx项,分别记录XML数据映射信息和相应的程序调用信息。

1、简单查询

获取一个表的内容,如获取DEAN.SYSUSER表的用户信息,XML数据映射配置信息为:

<selectid="SelectSysuser"resultMap="SysuserResult">

SELECT * FROM DEAN.SYSUSER

</select>

调用代码为:

protectedvoid Button1_Click(object sender, EventArgs e)

{

//简单查询

try

{

ISqlMapper mapper = Mapper.Instance(); //得到ISqlMapper实例

IList<iBatisTest.Domain.Sysuser> plist = mapper.QueryForList<iBatisTest.Domain.Sysuser>("Test3Map.SelectSysuser",null);//调用QueryForList方法

if (plist != null && plist.Count > 0)

{

GridView1.DataSource = plist;

GridView1.DataBind();

}

Label1.Text = "简单查询成功";

}

catch (Exception ex)

{

Label1.Text = ex.Message;

}

}

这种查询结果返回的是整张表的所有记录,无需传入查询参数,在调用QueryForList方法时把参数置为null。考虑到系统的效率,在实际开发中,对记录数少的小表才使用。

2、条件查询

根据条件来查询结果,条件可以是一个或者多个。这种方式在实际查询中被广泛使用,是应用最多的一种查询。如根据登录用户名查询该用户信息,数据映射配置信息为:

<selectid="SelectSysuserByUserName"parameterClass="string"resultMap="SysuserResult">

SELECT * FROM DEAN.SYSUSER WHERE LOGINNAME=#value#

</select>

iBatis.Net通过使用#或者$符号来占位,即标识参数。在XML数据映射文件的SQL语句中引入参数有2种方式,一种是内联参数方式,即使用parameterClass,如上面的配置就采用这种方式。一种是参数映射方式,使用parameterMap。采用内联方式时,允许我们把属性名称、属性类型、空置方式配置在SQL语句中。

使用内联参数方式时,传入的参数有3种类型,分别为:

(1)基本参数类型,很多SQL语句在查询时只接受一个参数,如int、string,使用#value#来引用,这个value是关键字,不可变,上面的示例就采用这种方式。也可以采用#keyName#来引用,keyName为键名,注意要区分大小写。

(2)字典类型参数,使用IDictionary类型的对象作为参数。通常可以使用Hashtable。如上面配置可修改为

<select id="SelectSysuserByUserName" parameterClass="System.Collections.IDictionary" resultMap="SysuserResult">

SELECT * FROM DEAN.SYSUSER WHERE LOGINNAME=#LOGINNAME#

</select>

(3)对象类型参数,可以是一个类或者是哈希表Hashtable,在使用哈希表时,某一个键值可以是一个列表List类型。

调用代码如下:

protectedvoid Button2_Click(object sender, EventArgs e)

{

//条件查询

try

{

string UserName = TextBox1.Text;//获取查询参数用户名

ISqlMapper mapper = Mapper.Instance(); //得到ISqlMapper实例

IList<iBatisTest.Domain.Sysuser> plist = mapper.QueryForList<iBatisTest.Domain.Sysuser>("Test3Map.SelectSysuserByUserName", UserName);//调用QueryForList方法

if (plist != null && plist.Count > 0)

{

GridView1.DataSource = plist;

GridView1.DataBind();

}

Label1.Text = "条件查询成功";

}

catch (Exception ex)

{

Label1.Text = ex.Message;

}

}

如果采用字典类型参数传入,只需要把调用中的参数修改为:

Hashtable hash = new Hashtable();//声明哈希表

hash.Add("LOGINNAME ", TextBox1.Text); //获取查询参数用户名

3、动态查询

iBatis.Net提供查询的灵活性主要体现在支持动态查询上,即可以动态的生成SQL语句。也只有掌握好动态查询,才能充分的感受iBatis框架所带来的便捷和高效。这也是很多软件公司和开发人员选择该框架的重要原因。

在开发中经常遇到这种查询,当用户没有输入查询条件时查询所有记录,如果用户输入了查询条件将根据查询条件进行查询。比如上面提到的条件查询,如果没有输入用户名信息将返回所有用户信息。这个时候就需要用到动态查询,根据参数值是否为空,生成两条不同的SQL语句。XML数据映射配置信息为:

<selectid="SelectSysuserDynamic1"parameterClass="System.Collections.IDictionary"resultMap="SysuserResult">

<![CDATA[ SELECT * FROM DEAN.SYSUSER ]]>

<dynamicprepend="WHERE">

<isNotEmptyprepend="AND"property="LOGINNAME">

<![CDATA[ LOGINNAME = #LOGINNAME# ]]>

</isNotEmpty>

</dynamic>

</select>

dynamic元素用来区分SQL语句的动态部分,dynamic是一个可选项,它中间可以包含任意数据的条件元素。上面的配置信息会根据输入参数LOGINNAME的值是否为空生成两条SQL语句。如果为空SELECT * FROM DEAN.SYSUSER,如果不为空SELECT * FROM DEAN.SYSUSER WHERE LOGINNAME = #LOGINNAME#。

调用程序代码为:

protectedvoid Button3_Click(object sender, EventArgs e)

{

//动态查询1

try

{

Hashtable hash = newHashtable();//声明哈希表

hash.Add("LOGINNAME", TextBox2.Text); //获取查询参数用户名

ISqlMapper mapper = Mapper.Instance(); //得到ISqlMapper实例

IList<iBatisTest.Domain.Sysuser> plist = mapper.QueryForList<iBatisTest.Domain.Sysuser>("Test3Map.SelectSysuserDynamic1", hash);//调用QueryForList方法

if (plist != null && plist.Count > 0)

{

GridView1.DataSource = plist;

GridView1.DataBind();

}

Label1.Text = "动态查询1成功";

}

catch (Exception ex)

{

Label1.Text = ex.Message;

}

}

}

在iBatis.Net中,动态查询的条件元素包含以下几种:二元条件元素、一元条件元素和其他条件元素:

3.1二元条件元素

将一个属性值和静态值或另一个属性值比较,如果条件为真,元素将被包容在查询SQL语句中。

二元条件元素的属性:

perpend——可被覆盖的SQL语句组成部分,添加在语句的前面,该属性为可选。

property——是比较的属性,该属性为必选。

compareProperty——另一个用于和前者比较的属性(必选或选择compareValue属性)

compareValue——用于比较的值(必选或选择compareProperty属性)

二元条件元素为:

<isEqual>

比较属性值和静态值或另一个属性值是否相等,如果相等则查询条件有效。如:

<isEqual prepend="AND" property="status" compareValue="Y">

MARRIED = 'TRUE'

</isEqual>

<isNotEqual>

比较属性值和静态值或另一个属性值是否不相等,如果不相等则查询条件有效。

<isGreaterThan>

比较属性值是否大于静态值或另一个属性值,如果大于则查询条件有效。如:

<isGreaterThan prepend="AND" property="age" compareValue="18">

ADOLESCENT = 'FALSE'

</isGreaterThan>

<isGreaterEqual>

比较属性值是否大于等于静态值或另一个属性值,如果相等等于则查询条件有效。

<isLessThan>

比较属性值是否小于静态值或另一个属性值,如果小于则查询条件有效。

<isLessEqual>

比较属性值是否小于等于静态值或另一个属性值。如:

<isLessEqual prepend="AND" property="age"              compareValue="18">
ADOLESCENT = 'TRUE'
</isLessEqual>

二元条件元素多用在数字的区间选择上,如年龄、价格、面积等选择上面,也可以用在日期、字符串等类型的比较。如只显示ID<=10的指定ID的用户信息,如果输入值大于10则显示全部用户信息。XML数据映射配置信息为:

<selectid="SelectSysuserDynamic2"parameterClass="System.Collections.IDictionary"resultMap="SysuserResult">

<![CDATA[ SELECT * FROM DEAN.SYSUSER ]]>

<dynamicprepend="WHERE">

<isLessEqualprepend="AND"property="USERID"compareValue="10">

USERID = #USERID#

</isLessEqual>

</dynamic>

</select>

调用代码为:

protectedvoid Button4_Click(object sender, EventArgs e)

{

//动态查询2:二元条件元素查询

try

{

Hashtable hash = newHashtable();//声明哈希表

int ID = 0;

if (!string.IsNullOrWhiteSpace(TextBox3.Text))

{

ID = Convert.ToInt32(TextBox3.Text);

}

hash.Add("USERID", ID); //获取查询参数

ISqlMapper mapper = Mapper.Instance(); //得到ISqlMapper实例

IList<iBatisTest.Domain.Sysuser> plist = mapper.QueryForList<iBatisTest.Domain.Sysuser>("Test3Map.SelectSysuserDynamic2", hash);//调用QueryForList方法

if (plist != null && plist.Count > 0)

{

GridView1.DataSource = plist;

GridView1.DataBind();

}

else

{

GridView1.DataSource = null;

GridView1.DataBind();

}

Label1.Text = "动态查询2成功";

}

catch (Exception ex)

{

Label1.Text = ex.Message;

}

}

3.2一元条件元素

一元条件元素检查属性的状态是否符合特定的条件。即检查属性值是否满足条件,如果满足则查询条件有效。

一元条件元素的属性和二元条件元素一样,具有prepend和property属性,其中property为必选属性。

一元条件元素为:

<isPropertyAvailable>

检查是否存在该属性。

<isNotPropertyAvailable>

检查是否不存在该属性。

<isNull>

检查属性是否为null。

<isNotNull>

检查属性是否不为null。

<isEmpty>

检查属性是否为空,属性的数据类型为Collection、String 时检查是否为null或空,即是否为""或size() < 1。如:

<isNotEmpty prepend="AND" property="firstName" >

FIRST_NAME=#firstName#

</isNotEmpty>

<isNotEmpty>

检查属性是否不为空,检查方式同上。

比如下面的配置例子:

<selectid="SelectSysuserDynamic3"resultMap="SysuserResult"parameterClass="System.Collections.IDictionary">

<![CDATA[ SELECT * FROM DEAN.SYSUSER ]]>

<dynamicprepend="WHERE">

<isPropertyAvailableproperty="SEX">

<isNotNullproperty="SEX"prepend="AND">

SEX=#SEX#

</isNotNull>

</isPropertyAvailable>

<isPropertyAvailableproperty="STATUS">

<isNotNullproperty="STATUS"prepend="AND">

STATUS=#STATUS#

</isNotNull>

</isPropertyAvailable>

</dynamic>

</select>

先判断传入参数集是否有SEX参数,如果没有则不执行SEX=#SEX#查询条件,再判断该参数是否为null,不为null才执行查询条件。isPropertyAvailable元素最大的好处是,如果输入的参数集不包括设置的参数时程序不会报错,直接跳过该元素设置内容。

3.3其他元素条件

其他元素条件有两个元素,一个为ParameterPresent,该元素检查参数对象是否存在,一个为Iterate,该元素为遍历整个集合。

(1) ParameterPresent

ParameterPresent元素属性只有prepend一个属性,表示可被覆盖的SQL语句组成部分,添加在语句的前面,为可选属性。

<isParameterPresent>

检查是否存在参数对象,即如果参数类不为NULL则查询条件有效。如:

<isParameterPresent prepend="AND">
  EMPLOYEE_TYPE = #empType#
</isParameterPresent>

<isNotParameterPresent>

检查是否不存在参数对象,如:

<isNotParameterPresent prepend="AND">
  EMPLOYEE_TYPE = 'DEFAULT'
</isNotParameterPresent>

(2) Iterate:遍历整个集合元素,为List集合中的元素重复元素体的内容。

Iterate的属性:

prepend——可被覆盖的SQL语句组成部分,添加在语句的前面,该属性为可选。

property——类型为List的用于遍历的元素属性,该属性为必选。

open——整个遍历内容体开始的字符串,用于定义括号,该属性为可选。

close ——整个遍历内容体结束的字符串,用于定义括号,该属性为可选。

conjunction——每次遍历内容之间的字符串,用于定义AND或OR,该属性为可选。

<iterate>

遍历类型为List的元素。如:

<iterate prepend="AND" property="UserNameList"

open="(" close=")" conjunction="OR">

username=#UserNameList[]#

</iterate>

注意:使用<iterate>时,在List元素名后面包括方括号[]非常重要,方括号[]将对象标记为List,以防解析器简单地将List输出成String。

Iterate元素在生成sql语句时,标签中的内容是循环生成的,如上面的例子将会生成语句:(username=xxx1 or username=xxx2 or username=xxx 3)。该元素也经常用来动态生成In查询条件,如id in (xx1,xx2,xx3,.....),括号中的(包括括号)都由该元素标签生成。

比如下面的配置例子:

<selectid="SelectSysuserDynamic4"resultMap="SysuserResult"parameterClass="System.Collections.IDictionary">

<![CDATA[ SELECT * FROM DEAN.SYSUSER ]]>

<dynamicprepend=" WHERE">

<isPropertyAvailableproperty="SEX">

<isNotNullproperty="SEX"prepend="AND">

SEX=#SEX#

</isNotNull>

</isPropertyAvailable>

<isNotNullprepend="And"property="USERIDLIST">

USERID in

<iterateproperty="USERIDLIST"open="("close=")"conjunction=",">

#USERIDLIST[]#

</iterate>

</isNotNull>

</dynamic>

</select>

调用代码为:

protectedvoid Button6_Click(object sender, EventArgs e)

{

//动态查询2:其它元素条件,Iterate

try

{

Hashtable hash = newHashtable();//声明哈希表

string sex = "男";

hash.Add("SEX", sex);

List<int> IDS = newList<int>();//声明List对象

IDS.Add(1);

IDS.Add(2);

IDS.Add(3);

hash.Add("USERIDLIST", IDS);

ISqlMapper mapper = Mapper.Instance(); //得到ISqlMapper实例

IList<iBatisTest.Domain.Sysuser> plist = mapper.QueryForList<iBatisTest.Domain.Sysuser>("Test3Map.SelectSysuserDynamic4", hash);//调用QueryForList方法

if (plist != null && plist.Count > 0)

{

GridView1.DataSource = plist;

GridView1.DataBind();

}

else

{

GridView1.DataSource = null;

GridView1.DataBind();

}

Label1.Text = "动态查询4成功";

}

catch (Exception ex)

{

Label1.Text = ex.Message;

}

}

系统会根据配置信息动态的生成In查询条件,最终动态生成的SQL语句为:SELECT * FROM DEAN.SYSUSER AND SEX='男' And USERID in (1,2,3)。

4、多表查询

前面讲到的示例都是从一个表中查询记录,获取的结果也是单个对象。事实上在程序开发中,经常需要对多个表进行组合查询,返回的结果也是复杂对象。如查询用户权限信息,就需要关联用户表和权限表。

向数据库添加系统权限表SysUserRight,脚本如下:

CREATE TABLE DEAN.SYSUSERRIGHT

(

ID NUMBER(10,0) NOT NULL ENABLE,

USERID NUMBER(10,0) NOT NULL ENABLE,

RIGHTID NUMBER(10,0) NOT NULL ENABLE,

constraint PK_SYSUSERRIGHT primary key (ID)

);

comment on column DEAN.SYSUSERRIGHT.ID is 'ID';

comment on column DEAN.SYSUSERRIGHT.USERID is '用户ID';

comment on column DEAN.SYSUSERRIGHT.RIGHTID is '权限ID';

有两种方式来处理这种多表查询,一种是参照单表查询,根据返回结果定制一个新类,或者直接设置返回参数为Hashtable表。如:

<selectid="MultiTable1"resultClass="Hashtable" >

SELECT A.*,B.RIGHTID FROM DEAN.SYSUSER A,DEAN.SYSUSERRIGHT B WHERE A.USERID=B.USERID

</select>

通过用户ID(USERID)关联用户表(SYSUSER)和系统权限表(SYSUSERRIGHT)查询出用户信息及对应的权限信息,直接返回一个Hashtable表,记录了相应的信息。

第二种方式是利用iBatis的复杂属性来实现,在Sysuser类新增一个属性:

///<summary>

///多表查询新增权限属性

///</summary>

privateint _rightid;

publicint Rightid

{

get { return _rightid; }

set {_rightid = value;}

}

修改配置文件信息,在resultMaps部分增加一个结果映射信息,唯一号为UserRightResult,它继承于Test3Map.SysuserResult结果映射,增加的配置信息如下:

<resultMapid="UserRightResult"class="Sysuser"extends="Test3Map.SysuserResult">

<resultproperty="<spansstyle="color:blue; Rightid"column="USERID=USERID"select="Test3Map.SelectSysuserRight" />

</resultMap>

在statements节加入如下信息:

<statementid="SelectSysuserRight"parameterClass="int"resultClass="int">

SELECT RIGHTID FROM DEAN.SYSUSERRIGHT WHERE USERID= #USERID#

</statement>

<selectid="MultiTable2"parameterClass="int"resultMap="UserRightResult">

SELECT * FROM DEAN.SYSUSER ORDER BY USERID

</select>

通过XML配置文件中resultMap的result使用"select"进行一种迭代查询,也就是将<result property="Rightid" column="USERID=USERID" select="Test3Map.SelectSysuserRight" />中column指定的一项或多项作为参数(USERID=USERID),传入并执行指定的select语句SelectSysuserRight,并将查询结果赋给property=" Rightid ",从而实现多表查询。

该例子中实现的是1:1的关系查询,如果是1:n的关系查询,只需要Sysuser类增加的属性修改为IList类型。Statements节点"SelectSysuserRight"的返回类修改为resultClass=" SysuserRightResult"。

通过iBatis复杂属性,可以非常方便的实现多表查询,但这个方法给我们带来便利的同时,也带来了两个问题。首先,创建包含大量对象的列表可能会消耗大量的内存。其次,这种方法会导致数据库的I/O问题,其原因就是所谓的"N+1"查询现象。对于主从表(也称为父子表)的查询,特别容易产生N+1查询问题,N+1查询问题是由于试图加载多个父记录(比如User)的子记录(Right)而引起的。在查询父记录时,只需要1条语句,假设返回N条记录,那么就需要再执行N条语句来查询子记录,引发所谓的"N+1查询"。

解决N+1查询问题可以通过延迟加载(lazy loading)来实现,它将加载过程打散为一些更小的过程。在父子表查询过程中,对子表的查询往往不需要和父表一起加载,例如,系统的用户管理,打开一个用户信息页面时显示的是用户信息列表,当点击一个用户时,才需要加载该用户的权限信息。这种情况就特别适合使用延迟加载,每次都仅查询一个列表。使用延迟加载的时候还需要特别注意,使用的动态代理的对象的所有方法和属性都必须是virtual类型。

要实现延迟加载,只需要在配置文件里面加入lazyLoad="true"属性就可以了。通过延迟加载,它能提高查询的效率,但并没有真正解决数据库I/O问题,在最坏的情况下,它对数据库的访问次数与非延迟加载的时候是一样的。如何真正解决N+1查询问题呢?iBatis提供了连接语句(join)方式来完全避免N+1查询的出现。

修改配置文件信息,在resultMaps部分增加如下配置:

<resultMapid="SysuserRightResult"class="SysuserRight">

<resultproperty="ID"column="ID"/>

<resultproperty="Userid"column="USERID" />

<resultproperty="Rightid"column="RIGHTID"/>

</resultMap>

<resultMapid="SysuserJoinResult"class="SysuserJoin"extends="Test3Map.SysuserResult"groupBy="Userid">

<resultproperty="RightList"resultMapping="Test3Map.SysuserRightResult" />

</resultMap>

这个配置使用了relultMap的resultMapping属性,该属性用在如果一个数据类的属性本身不是基元数据类型,而是一个复杂数据类型的场景。这个时候就不能用一个简单的result元素来表示,必须给他一个完整的resultMap。resultMapping的值指明RightList属性由结果映射集SysuserRightResult所表示的复杂数据类型表示。因为用户和权限信息是一对多的关系,在主表的结果映射上加入groupBy="Userid"属性。

注意用户类SysuserJoin的权限属性RightList的定义,它是由权限类SysuserRight组成的一个列表。RightList定义如下:

///多表查询新增权限列表属性

privateIList<SysuserRight> _rightlist;

publicIList <SysuserRight> RightList

{

get { return _rightlist; }

set { _rightlist = value; }

}

在statements节加入如下信息

<selectid="MultiTable3"resultMap="SysuserJoinResult" >

select A.*,B.* FROM DEAN.SYSUSER A LEFT JOIN DEAN.SYSUSERRIGHT B ON A.USERID=B.USERID </select>

再通过程序的调用,就不会出现N+1查询问题。

iBatis.Net(C#)数据库查询的更多相关文章

  1. ibatis 参数之模糊查询

    因项目需要最近使用ibatis,在使用查询语句的时候,想着通用性所以没有在配置文件里用N多的and 语句,而是如下: <select id="getUsersList" re ...

  2. [转载]Hibernate如何提升数据库查询的性能

    目录(?)[-] 数据库查询性能的提升也是涉及到开发中的各个阶段在开发中选用正确的查询方法无疑是最基础也最简单的 SQL语句的优化 使用正确的查询方法 使用正确的抓取策略 Hibernate的性能优化 ...

  3. 用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。

    最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变 ...

  4. [转]C#反射,根据反射将数据库查询数据和实体类绑定,并未实体类赋值

    本文来自:http://www.cnblogs.com/mrchenzh/archive/2010/05/31/1747937.html /****************************** ...

  5. 各数据库查询前N条记录的SQL语句

    sql在不同数据库查询前几条数据 1. ORACLE SELECT * FROM TABLE_NAME WHERE ROWNUM <= N;  HQL: from table_name t or ...

  6. Atitit  DbServiceV4qb9 数据库查询类库v4 新特性

    Atitit  DbServiceV4qb9 数据库查询类库v4 新特性     V4新特性 安全特性,屏蔽了executeUpdate,使用v2版 Sql异常转换,特别转换了DuplicateEnt ...

  7. C#与mysql做ASP.NET网页数据库查询速度测试

    两种方法是:1,使用mysql数据库的存储过程:2,C#编码,做网页后台与mysql数据库连接,前台测试显示测试过结果下面我将分别讲解两种方法的具体实现. 1,使用mysql数据库的存储过程插入万条大 ...

  8. 第九十九天上课 PHP TP框架 数据库查询和增加

    在Model文件夹下创建模型,文件命名规则 : 表名Model.class.php <?php namespace Home\Model; use Think\Model; class yong ...

  9. mysql数据库查询pdo的用法

    最早的php对mysql数据库查询是mysql和mysqli方法,后来php的新版本进一步封住了该方法,于是又pdo,抛开php框架,使用pdo查询数据,使用也是相当简便 <?php ini_s ...

随机推荐

  1. IOS 网络浅析-(三 NSURLConnection代理)

    对于现在的iOS开发,用法简单,最古老最经典最直接的NSURLConnection的作用不是很大,但是作为一名ios开发者,我们应该拥有一颗热爱学习的心,下面通过代码的实现简单介绍一下NSURLCon ...

  2. android学习笔记 activity生命周期&任务栈&activity启动模式

    activity生命周期 完整生命周期 oncreate->onstart->onresume->onpause->onstop->ondestory 使用场景:应用程序 ...

  3. CentOS6.5安装mysql5.1.73

    思路: 1.查看有无安装过mysql rpm -qa|grep mysql

  4. 开源项目go2o - golang版的o2o项目

    发一个github上唯一用golang实现的o2o项目 What's Go2o Golang combine simple o2o DDD domain-driven design realizati ...

  5. Effective Java 44 Write doc comments for all exposed API elements

    Principle You must precede every exported class, interface, constructor, method, and field declarati ...

  6. PS网页设计教程XXIV——从头设计一个漂亮的网站

    作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,“熟读唐诗三百首,不会作诗也会吟”. 本系列的教程来源于网上的PS教程,都是国外的,全英文的.本人尝试 ...

  7. oracle定时任务

    一.简介 当我们需要oracle数据库定时自动执行一些脚本,或进行数据库备份.数据库的性能优化,包括重建索引等工作是需要使用到定时任务. 定时任务可以使用以下两种完成. 1.操作系统级的定时任务,wi ...

  8. ubuntu创建、删除文件及文件夹方法

    mkdir 目录名         => 创建一个目录 rmdir 空目录名      => 删除一个空目录 rm 文件名 文件名   => 删除一个文件或多个文件 rm –rf 非 ...

  9. 2014 Super Training #1 F Passage 概率DP

    原题: HDU 3366   http://acm.hdu.edu.cn/showproblem.php?pid=3366 本来用贪心去做,怎么都WA,后来看网上原来是一个DP题. 首先按P/Q来做排 ...

  10. MySQL数据库学习笔记(五)----MySQL字符串函数、日期时间函数

    一.常见字符串函数: 1.CHAR_LENGTH  获取长度(字符为单位) 2.FORMAT  格式化 3.INSERT  替换的方式插入 4.INSTR  获取位置 5.LEFT/RIGHT  取左 ...