Урок 34. Хранение данных. SQLite

Обсуждение уроков
Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Урок 34. Хранение данных. SQLite

Сообщение damager82 » 17 ноя 2011, 03:00

В этом уроке:

- хранение данных с помощью SQLite

Click here to read this article!
Последний раз редактировалось damager82 01 май 2017, 16:39, всего редактировалось 14 раз.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 34. Хранение данных. SQLite

Сообщение damager82 » 09 янв 2012, 21:37

А как тестировать через junit данный коннект к базе? Как создать ограниченный контекст, который можно создать для тестирования provider content. Есть такая возможность? (что бы не портить основную базу эмулятора)

Код: Выделить всё

public class DBHelperTest extends AndroidTestCase {
public DBHelperTest() {
}

public void test() {
DBHelper db = new DBHelper( getContext());
db.close();
}

}
Вроде так заработало :) сейчас буду пробовать )
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 34. Хранение данных. SQLite

Сообщение damager82 » 09 янв 2012, 21:41

Можно ли создать сохранить базу на карте памяти, что бы потом без root-а скопировать её накомпьютер? Пробовал методы Androida openOrCreateDat abase, ноони в любом случае создают базу в data/date/your_package
У меня сработало.
Только надо добавить Permission - android.permission.WRITE_EXTERNAL_ STORAGE в манифест-файл.

Исходник:

Код: Выделить всё

void prepareBD() {
File sdCard = Environment.getExternalStor ageDirectory(); 
File directory = new File(sdCard.getAbsolutePath () + "/MyDB");
directory.mkdirs();
File dbFile = new File(directory, "database");
SQLiteDatabase db = SQLiteDatabase.openOrCreateDat abase(dbFile, null);
db.execSQL("drop table if exists mytab;");
db.execSQL("create table mytab (id integer primary key autoincrement, name text);");
db.execSQL("insert into mytab (name) values ('test');");
db.close();
}
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Урок 34. Хранение данных. SQLite

Сообщение Mikhail_dev » 14 янв 2012, 01:43

что за странный импорт ? Я так понимаю это опечатка.
import ru.startandroid.develop.p0341simpelsqlite.R;

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 34. Хранение данных. SQLite

Сообщение damager82 » 14 янв 2012, 18:37

no-- писал(а):что за странный импорт ? Я так понимаю это опечатка.
import ru.startandroid.develop.p0341simpelsqlite.R;
Да, очепятка. Я там с проектами немного намудрил, забыл пофиксить потом.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

george
Сообщения: 7
Зарегистрирован: 07 фев 2012, 18:46

Re: Урок 34. Хранение данных. SQLite

Сообщение george » 08 фев 2012, 00:29

Пытаюсь добавить к таблице еще один столбец.
Выдает сообщение: error code = 1, msg=table mytable has no colomn named tel.
Подскажите что я делаю не так.

package com.b3testapp;

import com.b3testapp.R;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class B3TestAppActivity extends Activity implements OnClickListener {

final String LOG_TAG = "myLogs";

Button btnAdd, btnRead, btnClear;
EditText etName, etEmail, etTel;

DBHelper dbHelper;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

btnAdd = (Button) findViewById(R.id.btnAdd);
btnAdd.setOnClickListener(this);

btnRead = (Button) findViewById(R.id.btnRead);
btnRead.setOnClickListener(this);

btnClear = (Button) findViewById(R.id.btnClear);
btnClear.setOnClickListener(this);

etName = (EditText) findViewById(R.id.etName);
etEmail = (EditText) findViewById(R.id.etEmail);
etTel = (EditText) findViewById(R.id.etTel);
// создаем объект для создания и управления версиями БД
dbHelper = new DBHelper(this);
}


@Override
public void onClick(View v) {

// создаем объект для данных
ContentValues cv = new ContentValues();

// получаем данные из полей ввода
String name = etName.getText().toString();
String email = etEmail.getText().toString();
String tel = etTel.getText().toString();
// подключаемся к БД
SQLiteDatabase db = dbHelper.getWritableDatabase();


switch (v.getId()) {
case R.id.btnAdd:
Log.d(LOG_TAG, "--- Insert in mytable: ---");
// подготовим данные для вставки в виде пар: наименование столбца - значение

cv.put("name", name);
cv.put("email", email);
cv.put("tel", tel);
// вставляем запись и получаем ее ID
long rowID = db.insert("mytable", null, cv);
Log.d(LOG_TAG, "row inserted, ID = " + rowID);
break;
case R.id.btnRead:
Log.d(LOG_TAG, "--- Rows in mytable: ---");
// делаем запрос всех данных из таблицы mytable, получаем Cursor
Cursor c = db.query("mytable", null, null, null, null, null, null);

// ставим позицию курсора на первую строку выборки
// если в выборке нет строк, вернется false
if (c.moveToFirst()) {

// определяем номера столбцов по имени в выборке
int idColIndex = c.getColumnIndex("id");
int nameColIndex = c.getColumnIndex("name");
int emailColIndex = c.getColumnIndex("email");
int telColIndex = c.getColumnIndex("tel");
do {
// получаем значения по номерам столбцов и пишем все в лог
Log.d(LOG_TAG,
"ID = " + c.getInt(idColIndex) +
", name = " + c.getString(nameColIndex) +
", email = " + c.getString(emailColIndex) + ", tel = " + c.getString(telColIndex));
// переход на следующую строку
// а если следующей нет (текущая - последняя), то false - выходим из цикла
} while (c.moveToNext());
} else
Log.d(LOG_TAG, "0 rows");
break;
case R.id.btnClear:
Log.d(LOG_TAG, "--- Clear mytable: ---");
// удаляем все записи
int clearCount = db.delete("mytable", null, null);
Log.d(LOG_TAG, "deleted rows count = " + clearCount);
break;
}
// закрываем подключение к БД
dbHelper.close();
}



class DBHelper extends SQLiteOpenHelper {

public DBHelper(Context context) {
// конструктор суперкласса
super(context, "myDB", null, 1);
}

@Override
public void onCreate(SQLiteDatabase db) {
Log.d(LOG_TAG, "--- onCreate database ---");
// создаем таблицу с полями
db.execSQL("create table mytable ("
+ "id integer primary key autoincrement,"
+ "name text,"
+ "email text, " + "tel text " + ");");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}
}
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp">
</TextView>
<EditText
android:id="@+id/etName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<requestFocus>
</requestFocus>
</EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp">
</TextView>
<EditText
android:id="@+id/etEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
</EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Telefon"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp">
</TextView>
<EditText
android:id="@+id/etTel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
</EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add">
</Button>
<Button
android:id="@+id/btnRead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Read">
</Button>
<Button
android:id="@+id/btnClear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear">
</Button>
</LinearLayout>
</LinearLayout>

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 34. Хранение данных. SQLite

Сообщение damager82 » 11 фев 2012, 21:56

А метод onCreate точно срабатывает?
Может пытаетесь в ранее созданную базу запись вставлять. Попробуйте удалить файл базы данных, пусть заново создаст.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

OctahedroN
Сообщения: 18
Зарегистрирован: 15 фев 2012, 20:14

Re: Урок 34. Хранение данных. SQLite

Сообщение OctahedroN » 15 фев 2012, 20:24

А можно ли из списка сделать массив? Например столбец name загнать в массив names[]?

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 34. Хранение данных. SQLite

Сообщение damager82 » 17 фев 2012, 12:58

OctahedroN писал(а):А можно ли из списка сделать массив? Например столбец name загнать в массив names[]?
В смысле из курсора вытащить все значения столбца name и поместить в массив?
Я не встречал такого метода.
Скорее всего только создание массива, перебор строк курсора и заполнение массива. Кода немного получается.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

OctahedroN
Сообщения: 18
Зарегистрирован: 15 фев 2012, 20:14

Re: Урок 34. Хранение данных. SQLite

Сообщение OctahedroN » 17 фев 2012, 16:05

case R.id.Button:
Cursor c1 = db.query("myt", null, null, null, null, null, null);
if (c1.moveToFirst()) {

int XColIndex = c1.getColumnIndex("X");
int i=0;

do {
X1=c1.getString(XColIndex);
i++;
} while (c1.moveToNext());
} else
Log.d(LOG_TAG, "0 rows");

Я только начинаю программировать и возможно я где то грубо ошибаюсь. Написал такой код, но при нажатии кнопки Button в приложении выскакивает ошибка. Можете сказать что я делаю не так?

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 34. Хранение данных. SQLite

Сообщение damager82 » 17 фев 2012, 21:50

OctahedroN писал(а): Я только начинаю программировать и возможно я где то грубо ошибаюсь. Написал такой код, но при нажатии кнопки Button в приложении выскакивает ошибка. Можете сказать что я делаю не так?
Вроде все верно ...
А массив X1 вы как объявляли?
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

OctahedroN
Сообщения: 18
Зарегистрирован: 15 фев 2012, 20:14

Re: Урок 34. Хранение данных. SQLite

Сообщение OctahedroN » 17 фев 2012, 23:46

damager82 писал(а):
OctahedroN писал(а): Вроде все верно ...
А массив X1 вы как объявляли?
final String LOG_TAG = "myLogs";
String X1[];

Больше я с ним ничего не делал...

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 34. Хранение данных. SQLite

Сообщение KamiSempai » 18 фев 2012, 17:01

OctahedroN, советую посмотреть в логи, там должна быть указана строка кода которая вызвала ошибку.
Скорее всего ошибку вызывает: X1=c1.getString(XColIndex);
Для присвоения элементу массива значения нужно этот массив создать.
Перед циклом напишите: X1= new String[c1.getCount()];
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

OctahedroN
Сообщения: 18
Зарегистрирован: 15 фев 2012, 20:14

Re: Урок 34. Хранение данных. SQLite

Сообщение OctahedroN » 19 фев 2012, 15:15

KamiSempai, damager82, спасибо, всё заработало)

kkkpppccc
Сообщения: 1
Зарегистрирован: 25 фев 2012, 00:32

Re: Урок 34. Хранение данных. SQLite

Сообщение kkkpppccc » 25 фев 2012, 00:40

Ребят скажите. После вызова

Код: Выделить всё

mydb.delete("mytable", null, null);
все строки удаляются,но вот нумерация id сохраняется. Так и должно быть? Или как то можно нумерацию id обнулить отдельно. В проекте приходится постоянно то добавлять то стирать все из таблицы, а счетчик все бежит

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 34. Хранение данных. SQLite

Сообщение damager82 » 27 фев 2012, 09:40

kkkpppccc писал(а):Так и должно быть? Или как то можно нумерацию id обнулить отдельно. В проекте приходится постоянно то добавлять то стирать все из таблицы, а счетчик все бежит
Да, так и должно быть. Но есть способ сбросить. Вот тут написано, что данные по счетчику лежат в таблице SQLITE_SEQUENCE

Попробуйте выполнить что-нить типа:
delete from sqlite_sequence where name='<имя вашей таблицы>';
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
MeTeOpA
Сообщения: 85
Зарегистрирован: 07 мар 2012, 12:50

Re: Урок 34. Хранение данных. SQLite

Сообщение MeTeOpA » 23 мар 2012, 22:36

Скажите... такой вопрос....
а как скажем отобразить всю базу не в логах а в виде таблицы?

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 34. Хранение данных. SQLite

Сообщение damager82 » 26 мар 2012, 09:40

Grid или TableLayout можно использовать
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
Xroft
Сообщения: 38
Зарегистрирован: 10 май 2012, 10:11

Re: Урок 34. Хранение данных. SQLite

Сообщение Xroft » 10 май 2012, 10:24

Доброго времени суток!
Во первых, огромное спасибо за написанные уроки!!!
Уже неделю не вылезаю с вашего сайта!!! ТАК ДЕРЖАТЬ!)

Теперь по теме.
После запуска 34го урока мой эмулятор не хочет запускать приложение, и матерится ошибкой:

The application P0341_SimpleSQLite (process ru.startandroid.develop.p0341simplesqlite) has stoppet unexpectedly. Please try again

P.S. После вставки кода был была одна ошибка на onClick(View v)
@Override
public void onClick(View v) {

// создаем объект для данных
ContentValues cv = new ContentValues();

// получаем данные из полей ввода
String name = etName.getText().toString();
String email = etEmail.getText().toString();


Просило " Remove '@Override' annotation " Что я сделал и запустил приложение.
Больше ошибок не было...

Помогите понять в чем проблема ... и вообще из-за чего возникает такая ошибка при запуске приложения на эмуляторе.

Заранее Спасибо!

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 34. Хранение данных. SQLite

Сообщение damager82 » 10 май 2012, 11:50

Xroft писал(а):Во первых, огромное спасибо за написанные уроки!!!
Уже неделю не вылезаю с вашего сайта!!! ТАК ДЕРЖАТЬ!)

Просило " Remove '@Override' annotation " Что я сделал и запустил приложение.
Спасибо )

У вас наверно 7-я версия Java, она ругается на Ovveride - viewtopic.php?f=3&t=117&p=149#p150
Я на шестой сижу, и иногда забываю удалять эту аннотацию из кода.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Ответить