android_day03

1.数据库介绍
    sqlite
    问:什么情况下用数据库 有大量相似结构的数据需要存储的时候
    
2.数据库的创建
    定义一个类继承sqliteOpenHelper,代码如下:
    
        public class MyOpenHelper extends SQLiteOpenHelper {

            /**
             * @param context
             *            上下文 name 数据库的名字 factory 目的创建cursor对象 version 数据库的版本 从1开始
             */
            public MyOpenHelper(Context context) {
                super(context, "itheima.db", null, 3);
            }

            /**
             * Called when the database is created for the first time. 当数据库第一次创建的时候调用
             * 那么这个方法特别适合做表结构的初始化 创建表就是写sql语句
             */
            @Override
            public void onCreate(SQLiteDatabase db) {
                // id 一般以_id
                db.execSQL("create table info(_id integer  primary key autoincrement,name varchar(20),phone varchar(20))");

            }

            /**
             * Called when the database needs to be upgraded 当数据库版本升级的时候调用
             * 
             * 这个方法适合做 表结构的更新
             */
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                System.out.println("旧版本:" + oldVersion + ",新版本:" + newVersion);
                db.execSQL("alter table info add phone2 varchar(20)");

            }

        }

    
3.数据库的onCreate和onUpgrade方法
    [1]使用SQLise Expert Professional这个工具可以打开我们创建的数据库
    [2]需要提前安装SQLite Expert Professional这个工具  和  安装QQ一样
    onCreate方法:当数据库第一次创建的时候调用  特别适合做表结构的初始化
    onUpgrade方法:当数据库版本进行更新的时候调用
    
4.使用sql语句对数据库进行增删改查
    缺点:    1.sql语句容易写错
            2.执行sql语句没有返回值  不容易进行判断
            
    优点:多表查询容易
    
        //增加
        public void click1(View v){
            //1.获取数据库对象
            SQLiteDatabase db = myOpenHelper.getWritableDatabase();
            //2.执行增加一条的sql语句
            db.execSQL("insert into info(name,phone) values(?,?)",new Object[]{"张三","138888"});
            //3.数据库用完需要关闭
            db.close();
        }
        //删除
        public void click2(View v){
            SQLiteDatabase db = myOpenHelper.getWritableDatabase();
            db.execSQL("delete from info where name=?",new Object[]{"张三"});
            db.close();
        }
        //修改
        public void click3(View v){
            SQLiteDatabase db = myOpenHelper.getWritableDatabase();
            db.execSQL("update info set phone=? where name=?", new Object[]{"111111","张三"});
            db.close();
        }
        //查询
        public void click4(View v){
            SQLiteDatabase db = myOpenHelper.getReadableDatabase();
            Cursor cursor = db.rawQuery("select * from info", null);
            if(cursor!=null&&cursor.getCount()>0){
                while(cursor.moveToNext()){
                    //columnIndex代表列的索引
                    String name = cursor.getString(1);
                    String phone = cursor.getString(2);
                    System.out.println("name:"+name+"---,phone:"+phone);
                }
            }
            
        }
            
4.1 [1]使用命令行工具  sqlite3可以打开数据库
        使用命令行工具 sqlite3可以打开数据库(到指定的目录,打开数据库文件 ):
        sqlite3 itheima.db
    [2]改变dos的编码方式    chcp 936:改变成gbk编码方式,如果改成utf-8,chcp 65001
    
    
5.使用谷歌封装好的api对数据库增删改查
    优点:    [1]写法简单  不需要写复杂的sql语句  不容易写错
            [2]有返回值方便开发者进行开发
            
    缺点:如果有多张表,使用谷歌封装的api不容易进行查询
    
        //增加
        public void click1(View v){
            //1.获取数据库对象
            SQLiteDatabase db = myOpenHelper.getWritableDatabase();
            //2.执行增加一条的sql语句
            //db.execSQL("insert into info(name,phone) values(?,?)",new Object[]{"张三","138888"});
            /**
             * table 表名
             * ContentValues 内部封装了一个map  key:对应列的名字  value:对应的值
             */
            ContentValues values=new ContentValues();
            values.put("name", "王五");
            values.put("phone", "110");
            //返回值代表插入新行的id
            long insert = db.insert("info", null, values);//底层在组拼sql语句
            //3.数据库用完需要关闭
            db.close();
            
            if(insert>0){
                Toast.makeText(getApplicationContext(), "添加成功", 1).show();
            }else{
                Toast.makeText(getApplicationContext(), "添加失败", 1).show();
            }
            
        }
        //删除
        public void click2(View v){
            SQLiteDatabase db = myOpenHelper.getWritableDatabase();
            //db.execSQL("delete from info where name=?",new Object[]{"张三"});
            //返回值代表影响的行数
            int delete = db.delete("info", "name=?", new String[]{"王五"});
            db.close();
            
            Toast.makeText(getApplicationContext(), "删除了"+delete+"行", 0).show();
        }
        //修改
        public void click3(View v){
            SQLiteDatabase db = myOpenHelper.getWritableDatabase();
            //db.execSQL("update info set phone=? where name=?", new Object[]{"111111","张三"});
            ContentValues values=new ContentValues();
            values.put("phone", "114");
            //代表更新了多少行
            int update = db.update("info", values, "name=?", new String[]{"王五"});
            db.close();
            
            Toast.makeText(getApplicationContext(), "更新了"+update+"行", 0).show();
        }
        //查询
        public void click4(View v){
            SQLiteDatabase db = myOpenHelper.getReadableDatabase();
            /**
             * columns 代表你要查询的列
             * selection 根据什么查询
             */
            //根据name为王五查询  只要name和phone列
            //Cursor cursor = db.query("info", new String[]{"name","phone"}, "name=?", new String[]{"王五"}, null, null, null);
            
            Cursor cursor = db.query("info", null, null, null, null, null, null);
            
            //Cursor cursor = db.rawQuery("select * from info", null);
            if(cursor!=null&&cursor.getCount()>0){
                while(cursor.moveToNext()){
                    //columnIndex代表列的索引
                    String name = cursor.getString(1);
                    String phone = cursor.getString(2);
                    System.out.println("name:"+name+"---,phone:"+phone);                    
                }
                
            }
        
        }
    
6.2种增删改查的优缺点(上面已经提及)

7.Android种数据库的事务介绍
    事务:执行一段逻辑,要么同时成功要么失败  银行转账
        SQLiteDatabase db = myOpenHelper.getReadableDatabase();
        //使用事务进行转账
        db.beginTransaction();//开启事务
        try {
            db.execSQL("update info set money=money-100 where name=?",new Object[]{"张三"});
            
            //int i=10/0;
            
            db.execSQL("update info set money=money+100 where name=?",new Object[]{"李四"});
            
            //给当前事务设置一个成功标志
            db.setTransactionSuccessful();
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), "服务器忙,请稍后再转账", 1).show();
        }finally{
            db.endTransaction();
        }
        

8.listview入门
    [1]定义listview在布局中
    [2]定义listview的数据适配器
    [3]实现baseAdapter的getCount和getView方法
    
    [1]activity_main.xml代码:
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity" >

            <ListView
                android:id="@+id/lv"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fastScrollEnabled="true"
                 >
            </ListView>
            
        </RelativeLayout>
    
    [2]MainActivity代码:
        public class MainActivity extends ActionBarActivity {

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                //1.找到我们关心的控件
                ListView lv=(ListView) findViewById(R.id.lv);
                
                //2.显示数据  和其他普通控件textview 有点区别 数据来源于数据适配器
                lv.setAdapter(new MyListAdapter());
                
            }

            
            //3.定义listview的数据适配器
            private class MyListAdapter extends BaseAdapter{

                //一共有多少条数据需要展示
                @Override
                public int getCount() {
                    return 1000000000;
                }

                //返回指定position位置对应的对象
                @Override
                public Object getItem(int position) {
                    return null;
                }
                
                //返回position位置对应id
                @Override
                public long getItemId(int position) {
                    return 0;
                }

                /**
                 * 获取一个view  用来显示listview的数据  会作为listview的一个条目出现
                 * 
                 * convertView 历史缓存对象
                 */
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    TextView tv;
                    if(convertView==null){
                        //创建新的view对象
                        tv=new TextView(MainActivity.this);
                        System.out.println("创建新的view对象--"+position);
                    }else{
                        System.out.println("复用历史缓存对象--"+position);
                        tv=(TextView) convertView;
                    }
                    
                    tv.setText("哈哈哈"+position);
                    return tv;
                }
                
            }

        }


9.listview的优化(getView)
    TextView tv;
    if(convertView==null){
        //创建新的view对象
        tv=new TextView(MainActivity.this);
        System.out.println("创建新的view对象--"+position);
    }else{
        System.out.println("复用历史缓存对象--"+position);
        tv=(TextView) convertView;
    }
    
    tv.setText("哈哈哈"+position);
    return tv;
    

10.listview显示数据的原理:
    mvc
    javaweb:
    m:mode 数据(javabean)
    v:view 视图 jsp
    c:controller  servlet
    
    Android:
    m:mode 数据(javabean)
    v:view listview
    c:adapter
    
【补充】listview的奇怪现象
    以后再使用listview高的时候使用 填充父窗体
    不管是什么adapter,作用就是把数据展示到listview
    

11.listview显示复杂的页面
    线性布局  相对布局都继承自ViewGroup  listview也继承ViewGroup,可以有自己的孩子
    通过一个打气筒 inflate  可以把一个布局转化成一个view对象
    【重点】BaseAdapter的getView方法中参数ViewGroup parent就是listview(即adapter中引用了listview)
    

12.获取打气筒常用api
    [1]view=View.inflate(getApplicationContext(), R.layout.item, null);
    [2]view=LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
    [3]LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        view=inflater.inflate(R.layout.item, null);
        
13.arrayAdapter使用
    String objects[]={"老张","老方","老黎","老毕","老刘","老韩","agjksd","sdgsdg"};
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //1.找到我们关心的控件
        ListView lv=(ListView) findViewById(R.id.lv);
        
        
        
        //2.创建一个arrayAdapter
        //ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,R.layout.item, objects);
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, R.layout.item1, R.id.tv_name, objects);
        
        
        //设置数据适配器  要会触类旁通
        lv.setAdapter(adapter);
        
    }
    
【补充】权重的概念
    只在LinearLayout和TableLayout中使用(其他的不行),android:layout_weight="2",用来分宽度。
    比如有一行有两个textview,一个是weight为2,一个weight为1,那么2的那个宽度是父类的三分之二

14.simpleAdapter使用

    //2.设置数据适配器 resource 我们定义的布局文件
    //from map集合的键,即第四个参数:是第二参数元素的map里面的键   data数据类型是 List<? extends Map<String, ?>> data
    SimpleAdapter adapter=new SimpleAdapter(getApplicationContext(), data,R.layout.item,new String[]{"name","phone"},new int[]{R.id.tv_name,R.id.tv_phone} );
    
    //3.设置数据适配器
    lv.setAdapter(adapter);


15.把数据库里面的数据查询出来展示到listview上
    [1]activity_main.xml中代码:
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            tools:context=".MainActivity" >

            <Button
                android:id="@+id/button1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="click1"
                android:text="add" />

            <Button
                android:id="@+id/button2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="click2"
                android:text="delete" />

            <Button
                android:id="@+id/button3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="click3"
                android:text="update" />

            <Button
                android:id="@+id/button4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="click4"
                android:text="find" />

            <ListView
                android:id="@+id/lv"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >
            </ListView>

        </LinearLayout>
    
    [2]Person(javabean)代码:
        public class Person {
            private String name;
            private String phone;
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public String getPhone() {
                return phone;
            }
            public void setPhone(String phone) {
                this.phone = phone;
            }
            
            
        }
    
    [3]MyOpenHelper代码:
        public class MyOpenHelper extends SQLiteOpenHelper{
            /**
             * @param context 上下文
             * name 数据库的名字
             * factory 目的创建cursor对象
             * version 数据库的版本  从1开始
             */
            public MyOpenHelper(Context context) {
                super(context, "itheima.db", null, 3);
            }
            
            /**
             * Called when the database is created for the first time.
             * 当数据库第一次创建的时候调用
             * 那么这个方法特别适合做表结构的初始化  创建表就是写sql语句
             */
            @Override
            public void onCreate(SQLiteDatabase db) {
                //id 一般以_id
                db.execSQL("create table info(_id integer  primary key autoincrement,name varchar(20),phone varchar(20))");
                
            }
            /**
             * Called when the database needs to be upgraded
             * 当数据库版本升级的时候调用
             * 
             * 这个方法适合做 表结构的更新
             */
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                System.out.println("旧版本:"+oldVersion+",新版本:"+newVersion);
                db.execSQL("alter table info add phone2 varchar(20)");
                
            }            
        }
    
    [4]MainActivity代码:
        public class MainActivity extends ActionBarActivity {
            private MyOpenHelper myOpenHelper;
            private ListView lv;
            private List<Person> lists;
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                
                lv = (ListView) findViewById(R.id.lv);
                
                myOpenHelper = new MyOpenHelper(getApplicationContext());
                
                lists = new ArrayList<Person>();
                
                //打开或者创建数据库  如果是第一次就是创建
                SQLiteDatabase writableDatabase = myOpenHelper.getWritableDatabase();
                //打开或者创建数据库  如果是第一次就是创建  如果磁盘满了  返回只读的
                SQLiteDatabase readableDatabase = myOpenHelper.getReadableDatabase();
                
            }
            
            //增加
            public void click1(View v){
                //1.获取数据库对象
                SQLiteDatabase db = myOpenHelper.getWritableDatabase();
                //2.执行增加一条的sql语句
                //db.execSQL("insert into info(name,phone) values(?,?)",new Object[]{"张三","138888"});
                /**
                 * table 表名
                 * ContentValues 内部封装了一个map  key:对应列的名字  value:对应的值
                 */
                ContentValues values=new ContentValues();
                values.put("name", "王五");
                values.put("phone", "110");
                //返回值代表插入新行的id
                long insert = db.insert("info", null, values);//底层在组拼sql语句
                //3.数据库用完需要关闭
                db.close();
                
                if(insert>0){
                    Toast.makeText(getApplicationContext(), "添加成功", 1).show();
                }else{
                    Toast.makeText(getApplicationContext(), "添加失败", 1).show();
                }
                
            }
            //删除
            public void click2(View v){
                SQLiteDatabase db = myOpenHelper.getWritableDatabase();
                //db.execSQL("delete from info where name=?",new Object[]{"张三"});
                //返回值代表影响的行数
                int delete = db.delete("info", "name=?", new String[]{"王五"});
                db.close();
                
                Toast.makeText(getApplicationContext(), "删除了"+delete+"行", 0).show();
            }
            //修改
            public void click3(View v){
                SQLiteDatabase db = myOpenHelper.getWritableDatabase();
                //db.execSQL("update info set phone=? where name=?", new Object[]{"111111","张三"});
                ContentValues values=new ContentValues();
                values.put("phone", "114");
                //代表更新了多少行
                int update = db.update("info", values, "name=?", new String[]{"王五"});
                db.close();
                
                Toast.makeText(getApplicationContext(), "更新了"+update+"行", 0).show();
            }
            //查询
            public void click4(View v){
                SQLiteDatabase db = myOpenHelper.getReadableDatabase();
                /**
                 * columns 代表你要查询的列
                 * selection 根据什么查询
                 */
                //根据name为王五查询  只要name和phone列
                //Cursor cursor = db.query("info", new String[]{"name","phone"}, "name=?", new String[]{"王五"}, null, null, null);
                
                Cursor cursor = db.query("info", null, null, null, null, null, null);
                
                //Cursor cursor = db.rawQuery("select * from info", null);
                if(cursor!=null&&cursor.getCount()>0){
                    while(cursor.moveToNext()){
                        //columnIndex代表列的索引
                        String name = cursor.getString(1);
                        String phone = cursor.getString(2);
                        System.out.println("name:"+name+"---,phone:"+phone);
                        
                        //把数据封装到javabean
                        Person person=new Person();
                        person.setName(name);
                        person.setPhone(phone);
                        
                        //把javabean对象加入到集合中
                        lists.add(person);
                        
                    }
                    
                    lv.setAdapter(new MyAdapter());                    
                }                                
            }
                        
            //定义listview的数据适配器
            private class MyAdapter extends BaseAdapter{

                @Override
                public int getCount() {
                    return lists.size();
                }

                @Override
                public Object getItem(int arg0) {
                    return null;
                }

                @Override
                public long getItemId(int arg0) {
                    return 0;
                }

                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    View view;
                    if(convertView==null){
                        //创建新的view对象
                        view=View.inflate(getApplicationContext(), R.layout.item, null);
                    }else {
                        view=convertView;
                    }
                    
                    //找到控件用来显示数据
                    TextView tv_name=(TextView) view.findViewById(R.id.tv_name);
                    TextView tv_phone=(TextView) view.findViewById(R.id.tv_phone);
                    
                    //如何显示数据
                    Person person=lists.get(position);
                    tv_name.setText(person.getName());
                    tv_phone.setText(person.getPhone());
                    
                    return view;
                }
                
            }
            
        }


16.使用了sqlite数据库后,会在data/data/com.itheima.sqlite(自己项目的package)下,
    多出一个目录databases,里面有文件itheima.db(自己代码里命名的),权限是-rw-rw----

17.进入手机端,sqlite3查看数据库
    [1]adb shell  (连接手机端)
    [2]ls  (列出目录)
    [3]cd data    (到data目录)
    [4]ls
    [5]cd data
    [6]ls
    [7]cd com.itheima.sqlite
    [8]ls
    [9]cd databases
    [10]ls
    [11]sqlite3 itheima.db
    [12](sqlite>) select * from info; 
    [13](发现乱码)(ctrl+c退出sqlite模式及adb)
    [13]chcp 65001(改成utf-8)
    [14]重复1-12步骤
                
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值