SQLite是遵守ACID的关系数据库管理系统,广泛使用在终端设备上。
它包含在一个相对小的C库中。它是D.RichardHipp创建的公有领域项目。
不像常见的客户端/服务器结构范例,SQLite引擎不是个程序与之通信的独立进程,而是连接到程序中成为它的一个主要部分。所以主要的通信协议是在编程语言内的直接API调用。这在消耗总量、延迟时间和整体简单性上有积极的作用。整个数据库(定义、表、索引和数据本身)都在宿主主机上存储在一个单一的文件中。它的简单的设计是通过在开始一个事务的时候锁定整个数据文件而完成的。
SQLite支持事务,索引,还有触发器。它的常用功能我测试了一下,在下面做一个梳理。
1、建表
字段类型包括integer,varchar,date三个常用类型。唉,其实sqlite没数据类型的概念,都是number。create table t_shp_bill(billid integer primary key ,userid integer,dayid integer,itemtxt varchar(200),state integer,billsn integer,created datetime,modified datetime);
选择主键字段为billid,非联合主键。
2、插入数据
insert into t_shp_bill(billid,userid,dayid,itemtxt,state,billsn,created,modified)
values(110119,110110,20130924,'国内气节',0,1,datetime('2013-12-30 12:10:04'),datetime('2013-12-30 12:10:04.100'));
insert into t_shp_bill(billid,userid,dayid,itemtxt,state,billsn,created,modified)
values(110112,110110,strftime('%Y%m%d','now','localtime'),'国内气节',0,1,datetime('now','localtime'),datetime('now','localtime'));
insert into t_shp_bill(billid,userid,dayid,itemtxt,state,billsn,created,modified)
values(110117,110110,strftime('%Y%m%d','now','localtime'),'国及',0,1,datetime('2013-09-11 12:12:12','localtime'),datetime('now','localtime'));
3、介绍几个简单的日期转字符串函数
select strftime('%Y%m%d','now') as c1;
select strftime('%Y%m%d','now','localtime');
select strftime('%Y%m%d%H%M%S','now');
select strftime('%Y%m%d%H%M%S','now','localtime');
sqlite> select strftime('%Y%m%d','now') as c1;
20130924
sqlite>
sqlite> select strftime('%Y%m%d','now','localtime');
20130924
sqlite>
sqlite> select strftime('%Y%m%d%H%M%S','now');
20130924092216
sqlite>
sqlite> select strftime('%Y%m%d%H%M%S','now','localtime');
20130924172216
select strftime('%Y%m%d%H%M%S',datetime('2013-12-30 12:10:04'),'localtime');
sqlite> select strftime('%Y%m%d%H%M%S',datetime('2013-12-30 12:10:04'),'localtime');
20131230201004
sqlite> select strftime('%Y%m%d%H%M%S',datetime('2013-12-30 12:10:04'));
20131230121004
sqlite>
4、继续插入数据
insert into t_shp_bill(billid,userid,dayid,itemtxt,state,billsn,created,modified) values(replace(strftime('%Y%m%d%H%M%f','now','localtime'),'.','') ,110110,strftime('%Y%m%d','now','localtime'),'国及',0,1,datetime('2013-09-11 12:12:12','localtime'),datetime('now','localtime'));
select replace(strftime('%Y%m%d%H%M%f','now','localtime'),'.','')
使用精确到毫秒的时间值作为主键,嵌入式系统不可能在一个毫秒内插入两条记录,因此该主键的约束条件是成立的。
5、继续建表
drop table t_shp_bill;
create table t_shp_bill(billid integer,userid integer,dayid integer,itemtxt varchar(200),state integer,billsn integer,created datetime,modified datetime,constraint pk_shp_bill primary key (billid,userid));
考虑到数据会上传到服务器端,所以加上userid字段建立联合主键。
6、创建索引
create index ind_shp_bill_1 on t_shp_bill(dayid);
insert into t_shp_bill(billid,userid,dayid,itemtxt,state,billsn,created,modified) values(replace(strftime('%Y%m%d%H%M%f','now','localtime'),'.','') ,110112,strftime('%Y%m%d','now','localtime'),'国及',0,1,datetime('2013-09-11 12:12:12','localtime'),datetime('now','localtime'));
insert into t_shp_bill(billid,userid,dayid,itemtxt,state,billsn,created,modified) values(replace(strftime('%Y%m%d%H%M%f','now','localtime'),'.','') ,110112,strftime('%Y%m%d','now','-1 day','localtime'),'国及',0,1,datetime('2013-09-11 12:12:12','localtime'),datetime('now','localtime'));
select * from t_shp_bill where dayid=20130923;
7、使用分组函数
select count(*),dayid from t_shp_bill group by dayid order by dayid;
sqlite> .explain on
sqlite> .timer on
sqlite> select count(*),dayid from t_shp_bill group by dayid order by dayid;
coun dayid
---- -------------
1 20130923
24 20130924
CPU Time: user 0.000000 sys 0.000000
sqlite> select * from t_shp_bill where dayid=20130923;
bill userid dayi item stat billsn cr modified
---- ------------- ---- ---- ---- ------------- -- -------------
20130924173121781 110112 20130923 国及 0 1 2013-09-1
1 20:12:12 2013-09-24 17:31:21
CPU Time: user 0.000000 sys 0.000000
参考
http://www.tutorialspoint.com/sqlite/sqlite_date_time.htm
http://baike.baidu.com/view/19310.htm
TPKeyboardAvoidingScrollView用于在scrollview中实现自动上滚,避免键盘遮盖住了textfield,textview等控件。
使用方法:
将TPKeyboardAvoidingScrollView.h和TPKeyboardAvoidingScrollView.m add进工程中
在需要用键盘自动上滚的controller的xib文件中,找到view,修改其Class为TPKeyboardAvoidingScrollView就可以了
源码:http://download.csdn.net/detail/chaoyuan899/6309641
前段时间为了弄项目的布局,为了底部菜单一直固定在底部,用了tabhost,接着随着需求又用了activityGroup。activityGroup用得超不方便,没事还是少用为妙!!!为了往后更方便,我决定更改主布局,一想到整个项目要重新弄布局,想死的心也有了~~~用了一天的时间,把底部菜单全部换了radioButton了。
重点来了!!!为了让每个需要底部菜单的activity都能拥有底部菜单,我写了个公有布局main.xml和公用的BaseActivity。同时,为了退出功能的实现,我写了个AppManager类管理actiivty。
代码如下:
main_footer.xml:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:id="@+id/main_linearlayout_footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="@drawable/btm_bar_bg"
android:layout_alignParentBottom="true"
>
<RadioGroup
android:id="@+id/radiogroup_personal_condition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/homeRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2.0dip"
android:background="@drawable/radio_home"
android:button="@null"
android:layout_marginLeft="20dp"
android:layout_marginRight="30dp"
android:tag="1"
/>
<RadioButton
android:id="@+id/priceRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2.0dip"
android:background="@drawable/radio_price"
android:button="@null"
android:layout_marginLeft="20dp"
android:layout_marginRight="30dp"
android:tag="2"
/>
<RadioButton
android:id="@+id/calRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2.0dip"
android:background="@drawable/radio_cal"
android:button="@null"
android:layout_marginLeft="20dp"
android:layout_marginRight="30dp"
android:tag="3"
/>
<RadioButton
android:id="@+id/newsRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2.0dip"
android:background="@drawable/radio_news"
android:button="@null"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:tag="4"
/>
</RadioGroup>
</LinearLayout>
main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:orientation="vertical">
<LinearLayout
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/bottom"
android:layout_alignParentTop="true"
>
</LinearLayout>
<include android:id="@+id/bottom" layout="@layout/main_footer"/>
</RelativeLayout>
BaseActivity:
/**
* 继承于Activity用于以后方便管理
*
* @author coder
*
*/
public class BaseActivity extends Activity {
//固定的菜单栏radiobutton
private Button homeRadioButton;
private Button priceRadioButton;
private Button newsRadioButton;
private Button calRadioButton;
private LinearLayout ly_content;
// 内容区域的布局
private View contentView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
ly_content = (LinearLayout) findViewById(R.id.content);
homeRadioButton = (Button) findViewById(R.id.homeRadioButton);
priceRadioButton = (Button) findViewById(R.id.priceRadioButton);
newsRadioButton = (Button) findViewById(R.id.newsRadioButton);
calRadioButton = (Button) findViewById(R.id.calRadioButton);
homeRadioButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
Intent intent1 = new Intent(BaseActivity.this,HomeActivity.class);
startActivity(intent1);
}
});
priceRadioButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
Intent intent2 = new Intent(BaseActivity.this,PriceActivity.class);
startActivity(intent2);
}
});
calRadioButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
Intent intent3 = new Intent(BaseActivity.this,CalendarActivity.class);
startActivity(intent3);
}
});
newsRadioButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
Intent intent4 = new Intent(BaseActivity.this,NewsActivity.class);
startActivity(intent4);
}
});
}
/***
* 设置内容区域
*
* @param resId
* 资源文件ID
*/
public void setContentLayout(int resId) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
contentView = inflater.inflate(resId, null);
LayoutParams layoutParams = new LayoutParams();
contentView.setLayoutParams(layoutParams);
//contentView.setBackgroundDrawable(null);
if (null != ly_content)
{
ly_content.addView(contentView);
// 添加Activity到堆栈
AppManager.getAppManager().addActivity(this);
Log.v("AppManager", "AppManager 添加actiivty!!"+this.getLocalClassName());
}
}
/***
* 设置内容区域
*
* @param view
* View对象
*/
public void setContentLayout(View view) {
if (null != ly_content) {
ly_content.addView(view);
}
}
/**
* 得到内容的View
*
* @return
*/
public View getLyContentView() {
return contentView;
}
public BaseActivity()
{
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
/**
* 1. 如果不分组,就自定义为Menu.NONE 2. id: 这个很重要:onOptionsItemSelected(MenuItem
* item) 根据id来判断那个菜单被选中 3. 定义菜单的排列 3. 设置Title
*/
menu.add(Menu.NONE, 1, Menu.NONE, "退出");
menu.add(Menu.NONE, 2, Menu.NONE, "取消");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == 1)
{
//finish();
// System.exit(0);
//退出程序
AppManager.getAppManager().AppExit(BaseActivity.this);
}
else if(item.getItemId() == 2){
}
return super.onOptionsItemSelected(item);
}
public void onClick(View v) {
}
}
AppManager:
public class AppManager {
public static Activity context = null;
private static Stack<Activity> activityStack;
private static AppManager instance;
private AppManager(){}
/**
* 单一实例
*/
public static AppManager getAppManager(){
if(instance==null){
instance=new AppManager();
}
return instance;
}
/**
* 添加Activity到堆栈
*/
public void addActivity(Activity activity){
if(activityStack==null){
activityStack=new Stack<Activity>();
}
activityStack.add(activity);
}
/**
* 获取当前Activity(堆栈中最后一个压入的)
*/
public Activity currentActivity(){
Activity activity=activityStack.lastElement();
return activity;
}
/**
* 结束当前Activity(堆栈中最后一个压入的)
*/
public void finishActivity(){
Activity activity=activityStack.lastElement();
finishActivity(activity);
}
/**
* 结束指定的Activity
*/
public void finishActivity(Activity activity){
if(activity!=null){
activityStack.remove(activity);
activity.finish();
activity=null;
}
}
/**
* 结束指定类名的Activity
*/
public void finishActivity(Class<?> cls){
for (Activity activity : activityStack) {
if(activity.getClass().equals(cls) ){
finishActivity(activity);
}
}
}
/**
* 结束所有Activity
*/
public void finishAllActivity(){
for (int i = 0, size = activityStack.size(); i < size; i++){
if (null != activityStack.get(i)){
activityStack.get(i).finish();
}
}
activityStack.clear();
}
/**
* 退出应用程序
*/
public void AppExit(Context context) {
try {
finishAllActivity();
ActivityManager activityMgr= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
activityMgr.restartPackage(context.getPackageName());
System.exit(0);
} catch (Exception e) { }
}
}
例如HomeActivity继承baseActivity的关键代码:
@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.home); //调用baseactivity的方法
setContentLayout(R.layout.home); }