当前位置: 代码迷 >> 综合 >> 黑马Android76期学习笔记01基础--day03--数据库的创建、数据的增删改查、事务、ListView,arrayAdapter,完整地从数据库取值到listView
  详细解决方案

黑马Android76期学习笔记01基础--day03--数据库的创建、数据的增删改查、事务、ListView,arrayAdapter,完整地从数据库取值到listView

热度:61   发布时间:2024-02-12 04:34:21.0
1.数据库的创建

步骤

  • 定义一个类继承sqliteOpenHelper
  • 在构造方法中创建数据库对象
  • 创建这个类的实例(传入当前的context对象)
  • 执行数据库的创建操作getWritableDatabase()

1、创建继承自sqliteOpenHelper的MyOpenHelper类

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class MyOpenHelper extends SQLiteOpenHelper {public MyOpenHelper(Context context) {//第一个参数:context上下文//第二个参数:name:数据库名//第三个参数:factory:创建cursor对象(结果集对象)//第四个参数:数据库的版本super(context,"mydb.db",null,1);}//当数据库第一次创建的时候调用,因此特别时候做表结构的初始化,创建表就是些sql语句public void onCreate(SQLiteDatabase db){db.execSQL("create table info(_id integer primary key autoincrement," +"name varchar(20))");}@Override//数据库版本升级的时候执行public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {Log.d("TAG", "onUpgrade: database is upgrade!");db.execSQL("alter table info add phone varchar(20)");}
}

2、主Activity中创建类对象并执行getWritableDatabase()方法

import androidx.appcompat.app.AppCompatActivity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MyOpenHelper myOpenHelper=new MyOpenHelper(getApplicationContext());//打开或者创建数据库,如果是第一次就创建SQLiteDatabase sqLiteDatabase=myOpenHelper.getWritableDatabase();}
}
2.数据库的增删改查

1、创建自定义的MyOpenHelper 继承自SQLiteOpenHelper

package com.fengray.ex045;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;public class MyOpenHelper extends SQLiteOpenHelper {public MyOpenHelper(Context context) {//第一个参数:context上下文//第二个参数:name:数据库名//第三个参数:factory:创建cursor对象(结果集对象)//第四个参数:数据库的版本super(context,"mydb.db",null,4);}//当数据库第一次创建的时候调用,因此特别时候做表结构的初始化,创建表就是些sql语句public void onCreate(SQLiteDatabase db){db.execSQL("create table info(_id integer primary key autoincrement," +"name varchar(20))");}@Override//数据库版本升级的时候执行public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {Log.d("TAG", "onUpgrade: database is upgrade!");db.execSQL("alter table info add phone varchar(20)");}
}

2、主activity

package com.fengray.ex045;import androidx.appcompat.app.AppCompatActivity;import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import java.util.Objects;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button add,del,modi,query;private MyOpenHelper myOpenHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myOpenHelper=new MyOpenHelper(getApplicationContext());initData();}public void initData(){add=findViewById(R.id.add);del=findViewById(R.id.del);modi=findViewById(R.id.modi);query=findViewById(R.id.query);add.setOnClickListener(this);del.setOnClickListener(this);modi.setOnClickListener(this);query.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.add:addClick();break;case R.id.del:delClick();break;case R.id.modi:modiClick();break;case R.id.query:queryClick();break;default:break;}}//增加被点击public void addClick(){Log.d("TAG", "addClick: ");//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行增加一条sql语句database.execSQL("insert into info(name,phone) values('?','?')",new Object[]{"张三","13842478524"});//关闭数据库database.close();}//增加被点击public void delClick(){//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行增加一条sql语句database.execSQL("delete from info where name=?",new Object[]{"张三"});//关闭数据库database.close();}//增加被点击public void modiClick(){//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行增加一条sql语句database.execSQL("update info set phone=? where name=?",new Object[]{"李四","18618521248"});//关闭数据库database.close();}//增加被点击public void queryClick(){Log.d("TAG", "queryClick: ");//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行增加一条sql语句Cursor cursor= database.rawQuery("select * from info",null);if (cursor!=null && cursor.getCount()>0){while (cursor.moveToNext()){String name=cursor.getString(1);String phone=cursor.getString(2);Log.d("TAG", "queryClick: "+name+":"+phone);}}//关闭数据库database.close();}
}
3.使用谷歌封装好的API进行增删改查

多表查询的时候,不容易进行查询
1、创建MyOpenHelper类,继承制OpenHelper类

package com.fengray.ex045;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;public class MyOpenHelper extends SQLiteOpenHelper {public MyOpenHelper(Context context) {//第一个参数:context上下文//第二个参数:name:数据库名//第三个参数:factory:创建cursor对象(结果集对象)//第四个参数:数据库的版本super(context,"mydb.db",null,4);}//当数据库第一次创建的时候调用,因此特别时候做表结构的初始化,创建表就是些sql语句public void onCreate(SQLiteDatabase db){db.execSQL("create table info(_id integer primary key autoincrement," +"name varchar(20),phone varchar(20))");}@Override//数据库版本升级的时候执行public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {Log.d("TAG", "onUpgrade: database is upgrade!");//db.execSQL("alter table info add phone varchar(20)");}
}

2、主Activity类

import androidx.appcompat.app.AppCompatActivity;import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import java.util.Objects;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button add,del,modi,query;private MyOpenHelper myOpenHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myOpenHelper=new MyOpenHelper(getApplicationContext());initData();}public void initData(){add=findViewById(R.id.add);del=findViewById(R.id.del);modi=findViewById(R.id.modi);query=findViewById(R.id.query);add.setOnClickListener(this);del.setOnClickListener(this);modi.setOnClickListener(this);query.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.add:addClick();break;case R.id.del:delClick();break;case R.id.modi:modiClick();break;case R.id.query:queryClick();break;default:break;}}//增加被点击public void addClick(){Log.d("TAG", "addClick: ");//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行增加一条sql语句//database.execSQL("insert into info(name,phone) values('?','?')",new Object[]{"张三","13842478524"});//使用封装好的API,第一个参数是info,第二个参数可以为空,第三个参数是一个contentValues,应当让如一个mapContentValues values=new ContentValues();values.put("name","王老五");values.put("phone","138566127543");//返回值代表插入新行的idlong insert=database.insert("info",null, values);//关闭数据库database.close();if (insert>0){Toast.makeText(getApplicationContext(), "添加成功", Toast.LENGTH_SHORT).show();}else {Toast.makeText(getApplicationContext(), "添加失败", Toast.LENGTH_SHORT).show();}}//删除被点击public void delClick(){//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行增加一条sql语句//database.execSQL("delete from info where name=?",new Object[]{"张三"});int delete=database.delete("info","name=?",new String[]{"王老五"});//关闭数据库database.close();Toast.makeText(getApplicationContext(), "删除了"+delete+"行", Toast.LENGTH_SHORT).show();}//修改被点击public void modiClick(){//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行修改一条sql语句//database.execSQL("update info set phone=? where name=?",new Object[]{"李四","18618521248"});ContentValues values=new ContentValues();values.put("name","李四");int update=database.update("info",values,"name=?",new String[]{"王老五"});//关闭数据库database.close();Toast.makeText(getApplicationContext(), "更新了"+update+"行", Toast.LENGTH_SHORT).show();}//查询被点击public void queryClick(){Log.d("TAG", "queryClick: ");//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行一条查询sql语句//columns:代表要查询的列,需要一个字符串数组,null代表所有列//selection:根据什么查Cursor cursor =database.query("info", null,"name=?",new String[]{"李四"},null,null,null);//Cursor cursor= database.rawQuery("select * from info",null);if (cursor!=null && cursor.getCount()>0){while (cursor.moveToNext()){String name=cursor.getString(1);String phone=cursor.getString(2);Log.d("TAG", "queryClick: "+name+":"+phone);}}//关闭数据库database.close();}
}

在这里插入图片描述
输出:
2020-08-16 15:55:02.843 8250-8250/com.fengray.ex045 D/TAG: queryClick: 李四:138566127543
2020-08-16 15:55:02.843 8250-8250/com.fengray.ex045 D/TAG: queryClick: 李四:138566127543

4.使用事务

1.创建MyOpenHelper继承 SQLiteOpenHelper

package com.fengray.ex046;import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;import androidx.annotation.Nullable;public class MyOpenHelper extends SQLiteOpenHelper {public MyOpenHelper(@Nullable Context context) {super(context, "Account.db", null, 1);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("create table info(_id integer primary key autoincrement,name varchar(20),phone varchar(20),money varchar(20))");db.execSQL("insert into info('name','phone','money') values ('张三','1384512542','2000')");db.execSQL("insert into info('name','phone','money') values ('李四','1383454362','5000')");/**ContentValues values=new ContentValues();values.put("name","张三");values.put("phone","1381245657");values.put("money","2000");db.insert("info",null,values);values.put("name","李四");values.put("phone","1334456578");values.put("money","5000");db.insert("info",null,values);*/}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}

2、主activity类

package com.fengray.ex046;import androidx.appcompat.app.AppCompatActivity;import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import java.util.Objects;public class MainActivity extends AppCompatActivity {private Button mybtn;private  MyOpenHelper myOpenHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myOpenHelper=new MyOpenHelper(getApplicationContext());}//点击进行转账public void btnClick(View view){SQLiteDatabase database=myOpenHelper.getWritableDatabase();//使用事务进行转账database.beginTransaction();try {//实现转账逻辑,实际就是些sql语句database.execSQL("update info set money=money-100 where name=?",new Object[]{"张三"});int i=10/0;database.execSQL("update info set money=money+100 where name=?",new Object[]{"李四"});database.setTransactionSuccessful();}catch (Exception e){Toast.makeText(getApplicationContext(), "服务器忙,请稍后再转", Toast.LENGTH_SHORT).show();}finally {database.endTransaction();}Log.d("TAG", "btnClick: ");}
}
5.listView入门

1、定义listView布局
2、定义listView的数据适配器
3、实现baseAdapter的getCount方法和getView方法

import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {private ListView mylistView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mylistView=findViewById(R.id.listView);mylistView.setAdapter(new Myadapter());}public class Myadapter extends BaseAdapter {@Overridepublic int getCount() {return 6;}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {TextView textView=new TextView(MainActivity.this);textView.setText("这是一个基本的TextView"+position);return textView;}}}

在这里插入图片描述

5.listView优化

convertView:就是安卓的复用view(reuseview)

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {TextView textView;if (convertView==null){textView=new TextView(MainActivity.this);Log.d("TAG", "创建新的view对象"+position);}else{textView=(TextView) convertView;Log.d("TAG", "复用旧的view对象"+position);}textView.setText("这是一个基本的TextView"+position);return textView;}
6.listView打气筒inflate布局页面为view

使用inflate(打气筒)将复杂的xml布局页面转化为view对象
1、创建布局页面cell.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/myllroot"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:layout_width="50dp"android:layout_height="50dp"><ImageViewandroid:src="@drawable/l00t"android:id="@+id/myimg"android:layout_width="50dp"android:layout_height="50dp"/></LinearLayout><LinearLayoutandroid:orientation="vertical"android:layout_width="wrap_content"android:layout_height="50dp"><TextViewandroid:id="@+id/titleText"android:text="this is title"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:id="@+id/detailText"android:text="this is content title"android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout></LinearLayout>

2、主activity关键部分代码

 @Overridepublic View getView(int position, View convertView, ViewGroup parent) {View myView;if (convertView==null){//创建新的view,使用inflate直接将布局转化为viewmyView=View.inflate(getApplicationContext(),R.layout.cell,null);Log.d("TAG", "创建新的view对象"+position);}else{myView= convertView;Log.d("TAG", "复用旧的view对象"+position);}return myView;}

在这里插入图片描述

7.inflate的进阶方法2、3

上例的核心代码

myView=LayoutInflater.from(getApplicationContext()).inflate(R.layout.cell,null);
if (convertView==null){//创建新的view,使用inflate直接将布局转化为view myView=LayoutInflater.from(getApplicationContext()).inflate(R.layout.cell,null);
if (convertView==null){//创建新的view,使用inflate直接将布局转化为view//myView=View.inflate(getApplicationContext(),R.layout.cell,null);LayoutInflater layoutInflater=(LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);myView=layoutInflater.inflate(R.layout.cell,null);Log.d("TAG", "创建新的view对象"+position);
8.adapter的作用

adapter的作用就是讲数据展示到listView上

import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;public class MainActivity extends AppCompatActivity {private  String values[]={"张三","李四","王二","赵六","孙七","刘八"};private ArrayAdapter<String> adapter;private ListView mylistView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mylistView=findViewById(R.id.mylistView);adapter=new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,values);mylistView.setAdapter(adapter);}
}

在这里插入图片描述

9.从数据库里拿数据,适配adapter,显示在listView上

文档结构:

  • MyOpenHelper类(获取数据库)
  • Person类(模型类)
  • MainActivity类
  • contact.xml ListView的布局单元格

1、MyOpenHelper类

package com.fengray.ex045;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;public class MyOpenHelper extends SQLiteOpenHelper {public MyOpenHelper(Context context) {//第一个参数:context上下文//第二个参数:name:数据库名//第三个参数:factory:创建cursor对象(结果集对象)//第四个参数:数据库的版本super(context,"mydb.db",null,4);}//当数据库第一次创建的时候调用,因此特别时候做表结构的初始化,创建表就是些sql语句public void onCreate(SQLiteDatabase db){db.execSQL("create table info(_id integer primary key autoincrement," +"name varchar(20),phone varchar(20))");}@Override//数据库版本升级的时候执行public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {Log.d("TAG", "onUpgrade: database is upgrade!");//db.execSQL("alter table info add phone varchar(20)");}
}

2、Person类

package com.fengray.ex045;public class Person {private String name;private String phone;public Person(String name, String phone) {this.name = name;this.phone = 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、contact.xm

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/tvname"android:layout_width="50dp"android:layout_height="25dp"/><TextViewandroid:id="@+id/tvphone"android:layout_width="wrap_content"android:layout_height="25dp"/></LinearLayout>

4、MainActivity类

package com.fengray.ex045;import androidx.appcompat.app.AppCompatActivity;import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;import java.util.ArrayList;
import java.util.List;
import java.util.Objects;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button add,del,modi,query;private MyOpenHelper myOpenHelper;private ListView mylistView;private  int i = 0;List<Person> persons;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mylistView=findViewById(R.id.listView);myOpenHelper=new MyOpenHelper(getApplicationContext());//定义一个集合用来放类模型persons=new ArrayList<>();initData();}public void initData(){add=findViewById(R.id.add);del=findViewById(R.id.del);modi=findViewById(R.id.modi);query=findViewById(R.id.query);add.setOnClickListener(this);del.setOnClickListener(this);modi.setOnClickListener(this);query.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.add:addClick();break;case R.id.del:delClick();break;case R.id.modi:modiClick();break;case R.id.query:queryClick();break;default:break;}}//增加被点击public void addClick(){Log.d("TAG", "addClick: ");//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行增加一条sql语句//database.execSQL("insert into info(name,phone) values('?','?')",new Object[]{"张三","13842478524"});//使用封装好的API,第一个参数是info,第二个参数可以为空,第三个参数是一个contentValues,应当让如一个mapContentValues values=new ContentValues();values.put("name","王老五"+i);values.put("phone","138566127543");i++;//返回值代表插入新行的idlong insert=database.insert("info",null, values);//关闭数据库database.close();if (insert>0){Toast.makeText(getApplicationContext(), "添加成功", Toast.LENGTH_SHORT).show();}else {Toast.makeText(getApplicationContext(), "添加失败", Toast.LENGTH_SHORT).show();}}//删除被点击public void delClick(){//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行增加一条sql语句//database.execSQL("delete from info where name=?",new Object[]{"张三"});int delete=database.delete("info","name=?",new String[]{"王老五"});//关闭数据库database.close();Toast.makeText(getApplicationContext(), "删除了"+delete+"行", Toast.LENGTH_SHORT).show();}//修改被点击public void modiClick(){//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行修改一条sql语句//database.execSQL("update info set phone=? where name=?",new Object[]{"李四","18618521248"});ContentValues values=new ContentValues();values.put("name","李四");int update=database.update("info",values,"name=?",new String[]{"王老五"});//关闭数据库database.close();Toast.makeText(getApplicationContext(), "更新了"+update+"行", Toast.LENGTH_SHORT).show();}//查询被点击public void queryClick(){//Log.d("TAG", "queryClick: ");//打开或者创建数据库,如果是第一次就创建SQLiteDatabase database=myOpenHelper.getWritableDatabase();//执行一条查询sql语句//columns:代表要查询的列,需要一个字符串数组,null代表所有列//selection:根据什么查//Cursor cursor =database.query("info", null,"name=?",new String[]{"李四"},null,null,null);Cursor cursor= database.rawQuery("select * from info",null);if (cursor!=null && cursor.getCount()>0){while (cursor.moveToNext()){String name=cursor.getString(1);String phone=cursor.getString(2);//把数据封装到javabean中(实际就是封装到模型中)Person person=new Person(name,phone);//添加到集合中persons.add(person);}mylistView.setAdapter(new MyAdapter());}//关闭数据库database.close();}//定义listview的数据适配器class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {return persons.size();}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view;if (convertView==null){LayoutInflater layoutInflater =(LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);view=layoutInflater.inflate(R.layout.contact,null);}else{view=convertView;}//将拿到的数据库数据给控件赋值TextView tvname=view.findViewById(R.id.tvname);//这里从view布局里拿,而不是从主布局里拿,因为主布局里没有这个idTextView tvphone=view.findViewById(R.id.tvphone);/** Person person=persons.get(position);* String name=person.getName();* String phone=person.getPhone();* tvname.setText(name);* tvphone.setText(phone);* */tvname.setText(persons.get(position).getName());tvphone.setText(persons.get(position).getPhone());return view;}}}

在这里插入图片描述

  相关解决方案