四.SQL命令 1.创建表.create table create [temp|temporary] table table_name (column_definitios [,constaraints]); temp或temporary声明的是临时表,只存活于当前会话,连接断开时自动销毁. 方括号内是可选项. 管道符|表示2选1; 必须包含至少一个表和一个字段.table_name为表名,小括号内是字段名列表,字段之间以","分隔.每个字段由"名称 类型 约束条件(可选)"组成. 例如,如下创建了contacts表,其中_id是自增主键,name声明为text,约束不能为null,且排序不区分大小写.phone默认为UNKNOWN.表一级约束是unique,定义在name和phone上. CREATE TABLE contacts( _id integer primary key autoincrement, name text not null collate nocase, phone text not null default 'UNKNOWN', unique(name,phone) );
2.修改表.alter table可以修改表名或增加字段 alter table table_name {rename to new_table_name | add column colunm_def}; 大括号内表示可选项,只能2选1.语句中并不需要包含大括号. colunm_def为新增的列定义,与create table要求一致. 例如,如下新增一个列email. alter table contacts add column email text not null default ' '; 表还可以由select语句创建,这样在创建表结构的同时创建数据.
3.插入数据. insert into (1)插入单行 insert into table_name(column_list) values (value_list); insert into table_name values(value_list); 此形式中value_list中的值需要与创建表的字段一一对应. table_name为插入的表名. column_list表示需要插入的列列表,value_list是对应的值列表,它们都用","分隔.字段必须存在于表中.如 sqlite> insert into phone(contacts_id, data) values(2, 223); 在column_list不指定自增长的字段(primary key autoincrement),或指定了但value_list对应的值为null,则该字段会自动增长. (2)插入一组行 使用子查询添加: 在value_list中对某一个数据采用子查询的方式,得到一组值.如 insert into phone values(null, (select _id from contacts), null); 使用select形式的insert语句可以一次插入多行,只要数据字段匹配. sqlite> CREATE TABLE phone2 (_id integer primary key autoincrement, contacts_id integer); sqlite> insert into phone2 select phone._id,phone.contacts_id from phone; (3)插入多行数据 创建时插入数据.create table new_table_name as select * from table_name.这样将复制table_name一份数据到新到表new_table_name中. 如 sqlite> create table phone3 as select * from phone2; 但是,这种形式创建的新表,原约束及类型都不是旧表的类型.自增字段不会创建,索引也不会创建,unique也不会有.
4.更新数据. update update table_name set update_list where predicate; update_list是一个或多个赋值字段的列表,形式为:column1=value1,column2=value2,... where子句和select命令相同. 如: sqlite> update phone set data = 10087, contacts_id = 4 where _id == 3; update命令必须注意unique约束,如不能修改primary key的值为重复项,否则会报错.
5.删除记录 delete delete from table_name where predicate; where子句和select命令相同.不带where子句的语句将删除整个表. 注意: (1)delete语句删除后并不释放空间. (2)primary key autoincrement字段的最大值也不会恢复为0,会保留旧值,如需恢复,需要删除或更新sqlite_sequence下的值. sqlite> delete from phone where _id = 14;
5.查询数据库.select命令.select命令输出可作为另一个select的输入,如select name from (select * from contacts). select [distinct] heading from tables where predicate group by columns having predicate order by columns limit count offset count; 每个关键字如from,where,having,group by,order by,limit等都是一个单独的子句,每个子句由关键字和跟随的参数构成.后面的子句以前面子句产生的结果进行输入处理. distinct去掉重复. select distinct name from contacts;语句将列出name,所有行的name值都不一样. from子句是由逗号分隔的一个或多个表,视图.如果指定多个表,它们会组合形成单一的关系. where子句参数predicate由逻辑表达式组成,它们定义了行的选择标准. 如select * from contacts where _id < 3 and email != ' '; 逻辑表达式中,可以包由以下几种组成 (1)比较指定条件,如==(或=),!=(或<>),>,<,>=,<=,!<(不小于),!>(不大于). (2)逻辑运算符 AND 运算符允许在一个 SQL 语句的 WHERE 子句中的多个条件的存在. BETWEEN 运算符用于在给定最小值和最大值范围内的一系列值中搜索值. EXISTS 运算符用于在满足一定条件的指定表中搜索行的存在. IN 运算符用于把某个值与一系列指定列表的值进行比较. NOT IN 运算符的对立面,用于把某个值与不在一系列指定列表的值进行比较. LIKE 运算符用于把某个值与使用通配符运算符的相似值进行比较,不区分大小写.如 like '%h%' 将选出该值中包含h的. GLOB 运算符用于把某个值与使用通配符运算符的相似值进行比较,大小写敏感的即区分大小写。 NOT 运算符是所用的逻辑运算符的对立面。比如 NOT EXISTS、NOT BETWEEN、NOT IN,NOT LIKE等等。它是否定运算符。 OR 运算符用于结合一个 SQL 语句的 WHERE 子句中的多个条件。 IS NULL 运算符用于把某个值与 NULL 值进行比较。 IS 运算符与 = 相似。 IS NOT 运算符与 != 相似。 || 连接两个不同的字符串,得到一个新的字符串。 UNIQUE UNIQUE 运算符搜索指定表中的每一行,确保唯一性(无重复). 在LIKE和GLOB中,%可匹配0个或多个任意字符,_可匹配一个任意字符. (3)位运算符 & 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中. | 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中. ~ 二进制补码运算符是一元运算符,具有"翻转"位效应. << 二进制左移运算符。左操作数的值向左移动右操作数指定的位数. >> 二进制右移运算符。左操作数的值向右移动右操作数指定的位数. GROUP BY子句用于与 SELECT 语句一起使用,来对相同的数据进行分组. 产生的效果是,指定列不会出现两个重复的值.如name字段都含有"中国移动",则只会出现一个. 利用聚合函数,还可以对每个组的数据计算聚合值.如 select name,count(*) from contacts group by name;语句将显示不同的name出现的次数 HAVING 子句允许指定条件来过滤将出现在最终结果中的分组结果.例如,以下语句将选出字段name相同且个数大于2的数据. select * from contacts group by name having count(2) > 2; order by子名指定以某些列进行排序.asc升序(默认),desc降序.当第一个出现重复时,以后面第二,第三,...去排序. limit和offset限定大小和范围.limit指定返回的最大记录数量.offset指定偏移的记录数. limit和offset一起使用时,可以使用","代替offset.注意:limit 2,1表示的是limit 1 offset 2.
多级选择 语法:select ... from left_table_name join_type right_table_name on join_condition; 实例: sqlite> create table phone (_id integer primary key autoincrement, contacts_id integer, data text); sqlite> select contacts.name, phone.data from contacts,phone where contacts._id = phone.contacts_id; (1)内连接,找出同时存在于两个表中的元素. select ... from table_1 inner join table_2 on conditional_expression ...; sqlite> select * from contacts inner join phone on contacts._id = phone.contacts_id; (2)交叉连接,不需要连接条件,只是简单的组合在一起. SELECT ... FROM table_1 CROSS JOIN table2 ... sqlite> select * from contacts cross join phone; (3)外连接(OUTER JOIN)是内连接(INNER JOIN)的扩展.SQL标准定义了三种类型的外连接:LEFT\RIGHT\FULL,但SQLite只支持左外连接(LEFT OUTER JOIN). 左外连接 SELECT ... FROM table1 LEFT OUTER JOIN table2 ON conditional_expression ...; sqlite> select * from contacts left outer join phone on contacts._id = phone.contacts_id; 左外连接试图把所有contacts中_id与phone中contacts_id相同的所有行进行连接关系的匹配,找出所有匹配的行.但是contacts中没有匹配phone的行仍会出现在结果中,phone中没有提供相应的行,以null补充. (4)自然连接,通过表中共有的字段名将两个表连接起来.因此使用自然连接时,不用添加连接条件就能取得内连接的结果. 自然连接由于两个表的列改动而出现结果的不确定性,因此尽量不使用.
名称和别名. 连接表时,如果两个表中存有同样名称的字段时,如使用select _id就会产生歧义.因此可用 table_name.field 的方法避免. 另一种方式是使用别名.如select f._id, t._id from contacts f, phone t where f._id == t.contacts_id; 其中contacts 的别名是f,phone的别名是t.
条件结果. 第一种,接收静态值并列出各种情况下的case返回值. case value when x then value_x when y then value_y else default_value end sqlite> select name || '_' || case _id when 1 then 'a' else 'b' end description from contacts where length(description) > 6 order by _id; 其中||用于连接两个字符串,返回的值为description,where对description进行过滤. 第二种,允许when条件中有表达式. case when condition_1 then value_x when condition_2 then value_y else default_value end sqlite> select name || '_' || case when _id < 3 then 'a' else 'b' end description from contacts where length(description) > 6 order by _id;
函数. SQLite提供了多种内置函数和聚合,可以用在不同的子句中.函数包括:数学函数如abs,字符串格式函数,和大小写转换函数upper及lower. 聚合是一类特殊的函数,它从一组记录中计算聚合值.如sum,avg,count,min,max等 select _id,upper(name),length(name) from contacts; 以_id,upper(name),length(name)分别显示每行数据. select * from contacts where length(name) > 4; 选出name长度大小4的行 select count(*) from contacts; 计算所有行的数量. 聚合还可以把结果集分成多个组,然后计算每个组的聚合值.
处理 null值. null是缺失信息的占位符,本身不是值,也不是空字符串.简单的说,null就是null.NOT NULL 表示列总是接受给定数据类型的显式值,这意味着不能为null. (1)逻辑运算中的null. AND: true AND null = null. false AND null = false. null AND null = null. OR: true OR null = true. false OR null = null. null OR null = null. 其中true可用值为非0或非0的逻辑表达式代替,false用0或值为0的逻辑表达式代替. 可以使用select语句测试,如select null and 1; (2)可以通过 is null 或 is not null 检测null是否存在. (3)null不等于其它值,包括null.因此不能使用equal,greater than等函数进行比较. (4)coalesce函数: 返回非null的第一个值.如sqlite> select coalesce (null, 1, null, 8); 将返回1 (5)nullif函数: 如果两个数相等则返回null,否则返回1.如 sqlite> select nullif(1, 1); null sqlite> select nullif(1, 3); 1 (6)使用null,需要注意断言和聚合中引用可能存在null值字段的查询.否则可能报错.
五.约束 1.unique唯一性约束.要求一个或一组字段所有值互不相同. 如下表中,id在每行中都不能相同.name和phone不能同时相同. sqlite> create table phone5(id integer unique, name text not null default '', phone text not null default 'UNKNOWN', unique(name, phone)); 在sqlite中,null与null都不相同,因此可以同时放入两个null.
9.索引.索引是用来在某种条件下加速查询的结构.索引会增加数据库的大小;对表insert,update,delete修改时,也需要对相应的索引进行修改. 语法: create [unique] index index_name on table_name (columns); index_name是索引名称,columns是table_name中的字段,以","分隔. columns中也可以指定对列排序. unique要求索引中的所有值必须是唯一的.这会在insert或update时,要求相应的字段不能同时相同. 删除索引: drop index index_name; 查询表的索引: .schema table_name 或 .indices table_name 注意: 一定要在理由能确保索引可提高性能时才使用索引,以下几个情况都应该避免使用索引: 在较小的表上; 在有频繁的大批量的更新或插入操作的表上; 在含有大量的 NULL 值的列上; 在频繁操作的列上。
六.触发器.事件发生时,触发器负责启动SQL命令.当触发器相关联的表删除时,自动删除触发器 语法: create [temp|temporary] trigger trigger_name [before|after] [insert|update|update of columns] on table_name begin action end; before|after: 指定是在事件发生前还是发生后执行. insert|update|update of columns: 事件在表table_name中执行的命令. action:具体要回调执行的行为,由一系列的SQL命令组成. 如下例: CREATE TABLE foo(a integer primary key autoincrement, b text, c text, d text collate nocase); CREATE TRIGGER foo_insert after insert on foo begin update foo set c=b, d=b; end; 更新触发器,可以在表的某个字段上定义,这样在该字段有修改行为时,会自动触发相应的trigger. create trigger trigger_name [before|after] update of column on table begin action end; CREATE TRIGGER foo_update after update of b on foo begin update foo set c=b, d=b; end;
八.其它常见问题 1.自动主键增加到Long最大值时再添加数据会报错Error: database or disk is full. 在Android中会报异常,android.database.sqlite.SQLiteFullException: database or disk is full (code 13). 遇到这种情况下,需要在删除表的同时将自动主键的值进行重新设置. 如何将自增字段的值重新设置为1.字段带有primary key autoincrement约束的表,sqlite将为其创建一个隐藏的表sqlite_sequence. sqlite_sequence记录了当前数据库文件中所有表的自动主键的最大值.删除表后删掉该值或设置为0即可重置表的自动主键值. 如contacts2.db的信息如下表. sqlite> select * from sqlite_sequence; name seq ---------- ---------- mimetypes 20 directorie 1 accounts 8 raw_contac 1799 data 6425 contacts 2639 groups 12 agg_except 1122 data_usage 90 calls 620 photo_file 3 执行语句: sqlite> delete from calls; sqlite> update sqlite_sequence set seq = 0 where name == 'calls'; 或 delete from sqlite_sequence where name == 'calls';
2.Android中如何取得自增字段的最大值? select last_insert_rowid();语句在android中将返回0. 可用以下语句代替: select max(primary_key_column) from table_name;或 查询sqlite_sequence表.如 sqlite> select max(_id) from contacts; max(_id) 4 在Android中示例代码如下: public long getMaxId() { long id = 0; SQLiteDatabase db = null; try { db = mSqliteHelper.getWritableDatabase(); String sql; // sql = "select * from sqlite_sequence"; sql = "SELECT max(_id) as max_id FROM " + PersonSQLiteHelper.TABLE_NAME; Cursor cursor = db.rawQuery(sql, null); if (cursor != null) { if (cursor.moveToNext()) id = cursor.getLong(0); cursor.close(); } } finally { if (db != null) db.close(); } return id; }
原题链接:#136 Single Number
要求:
给定一个整型数组,其中除了一个元素之外,每个元素都出现两次。找出这个元素
注意:算法的时间复杂度应为O(n),最好不使用额外的内存空间
难度:中等
分析:
题目限定了线性的时间复杂度,同时不使用额外的空间,即要求只遍历数组一遍得出结果。由于异或运算 n XOR n = 0, n XOR 0 = n,故将数组中的每个元素进
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2281)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:
Velocity出现的目的用于简化基于MVC的web应用开发,用于替代JSP标签技术,那么Velocity如何访问Java代码.本篇继续以Velocity三http://bit1129.iteye.com/blog/2106142中的例子为基础,
POJO
package com.tom.servlets;
public
今天看org.jboss.netty.example.http.file.HttpStaticFileServerHandler.java
可以直接往channel里面写入一个FileRegion对象,而不需要相应的encoder:
//pipeline(没有诸如“FileRegionEncoder”的handler):
public ChannelPipeline ge
Zero Clipboard的实现原理
Zero Clipboard 利用透明的Flash让其漂浮在复制按钮之上,这样其实点击的不是按钮而是 Flash ,这样将需要的内容传入Flash,再通过Flash的复制功能把传入的内容复制到剪贴板。
Zero Clipboard的安装方法
首先需要下载 Zero Clipboard的压缩包,解压后把文件夹中两个文件:ZeroClipboard.js
4.1 @Order
Spring 4.2 利用@Order控制配置类的加载顺序
4.2 演示
两个演示bean
package com.wisely.spring4_2.order;
public class Demo1Service {
}
package com.wisely.spring4_2.order;
public class