Урок 36. SQLite. Подробнее про метод query. Условие, сортировка, группировка

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

Урок 36. SQLite. Подробнее про метод query. Условие, сортировка, группировка

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

В этом уроке:

- подробно разбираем метод чтения данных query
- используем сортировку, группировку, условия, having

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

ermek6
Сообщения: 4
Зарегистрирован: 28 май 2012, 00:37

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение ermek6 » 03 июн 2012, 16:31

Вопрос по организации кода.
Зачем получать курсор в каждом кейсе. Ведь переменные то мы и так установили все в null. Можно же один раз курсор получить после switch. Или же для этого были другие причины???

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

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение damager82 » 04 июн 2012, 10:51

ermek6 писал(а):Зачем получать курсор в каждом кейсе.
Только для большей наглядности. Чтоб читатель четко видел какие параметры в методе используются для каждого случая.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Quqush
Сообщения: 6
Зарегистрирован: 09 авг 2012, 19:07

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение Quqush » 11 авг 2012, 17:56

Здравствуйте.
Огромное спасибо за уроки.

Объясните, пожалуйста, эту конструкцию:
for (String cn : c.getColumnNames())

Quqush
Сообщения: 6
Зарегистрирован: 09 авг 2012, 19:07

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение Quqush » 11 авг 2012, 20:44

Еще вопрос.
Есть такой код:
btnAll = (Button) findViewById(R.id.btnAll);
btnAll.setOnClickListener(this);

я его пишу так:
((Button) findViewById(R.id.btnAll)).setOnClickListener(this);

Когда мы эмулируем нажатие кнопки то первый вариант отлично работает а второй нет, выбрасывается исключение: java.lang.NullPointerException
Но при клике второй вариант тоже отлично работает.
Кто сможет объяснить почему так?

math64
Сообщения: 235
Зарегистрирован: 16 июл 2012, 07:47

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение math64 » 11 авг 2012, 22:14

1. for (String cn : c.getColumnNames()) - это аналог foreach в C#. В java решили не вводить новое ключевое слово. Можно перебирать содержимое коллеции или массива.
2. ((Button) findViewById(R.id.btnAll)).setOnClickListener(this); можно упростить до findViewById(R.id.btnAll).setOnClickListener(this); - клик можно ставить на любой View, а не только на кнопки.
java.lang.NullPointerException может появиться в первоначальном варианте, если будет найдена не кнопка, в упрощёном - если ничего не найдено.

Quqush
Сообщения: 6
Зарегистрирован: 09 авг 2012, 19:07

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение Quqush » 12 авг 2012, 10:52

math64 писал(а):это аналог foreach в C#
Большое спасибо. :!:

Тем не менее 2 вопрос остается открытым.

math64
Сообщения: 235
Зарегистрирован: 16 июл 2012, 07:47

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение math64 » 12 авг 2012, 18:40

Т.е. ты хочешь упростить

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

btnAll = (Button) findViewById(R.id.btnAll);
btnAll.setOnClickListener(this);
...
onClick(btnAll);
из примера?
упрощается так:

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

View btnAll = findViewById(R.id.btnAll);
btnAll.setOnClickListener(this);
...
onClick(btnAll);
Объявление поля Button btnAll; из класса удаляется, как и остальных кнопок (для которых даже локальных переменных не нужно выделять) - эти поля нигде не используются.
Однако, если к кнопке нужно обращение из других методов, лучше найти её и запомнить в поле класса в метода onCreate - чтобы больше не искать.

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение rezak90 » 13 авг 2012, 10:27

java.lang.NullPointerException выскакивает из-за того что операция выполняется справа на лево, вот переменной сначала нету а ты уже вешаешь обработчик, вот оно и нулл выкидывает... если я не ошибаюсь, а то с утра могу и натупить =)
R.id.team
Политика на форуме запрещена

math64
Сообщения: 235
Зарегистрирован: 16 июл 2012, 07:47

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение math64 » 13 авг 2012, 10:53

rezak - нет, из-за того что убрали инициализацию поля класса btnAll, а затем используют неинициализируемую в onClick(btnAll). Поле класса нужно убрать, заменить на локальную переменную - тогда компилятор выдаст предупреждение. Поле класса по умолчанию иницализируется в null, а локальная переменная должна инициализироваться программистом.

Quqush
Сообщения: 6
Зарегистрирован: 09 авг 2012, 19:07

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение Quqush » 14 авг 2012, 14:58

math64 писал(а):rezak - нет, из-за того что убрали инициализацию поля класса btnAll, а затем используют неинициализируемую в onClick(btnAll). Поле класса нужно убрать, заменить на локальную переменную - тогда компилятор выдаст предупреждение. Поле класса по умолчанию иницализируется в null, а локальная переменная должна инициализироваться программистом.
Вот спасибо! Теперь ясно.

daiz123
Сообщения: 18
Зарегистрирован: 11 июн 2012, 15:42

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение daiz123 » 20 авг 2012, 13:18

do {
str = "";
for (String cn : c.getColumnNames()) {
str = str.concat(cn + " = "
+ c.getString(c.getColumnIndex(cn)) + "; ");
}
Log.d(LOG_TAG, str);

} while (c.moveToNext());
Не могли бы вы подробней описать этот код.
for (String cn : c.getColumnNames()) как работает этот цикл? что означает двоеточие тут?
str.concat что делает эта функция?

math64
Сообщения: 235
Зарегистрирован: 16 июл 2012, 07:47

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение math64 » 20 авг 2012, 14:05

Я уже обяснял выше в этой теме: for( v : collection) - это соответвует foreach в C#. ; двоеточие соответствует in. Перебирается содержимое коллекции.
concat() - конкатенация, вместо неё можно использовать + (точнее, все вызовы + для строк заменяются на вызов concat() ).

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение rezak90 » 20 авг 2012, 14:29

видно по форуму просто не все знакомы не то что с явой а и с шарпом =) ... так что трудно конечно им и возникают такие вот вопросы.
R.id.team
Политика на форуме запрещена

zavbak
Сообщения: 6
Зарегистрирован: 25 янв 2012, 02:25

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение zavbak » 21 авг 2012, 13:24

Добрый день. Подскажите как можно в качестве сравниваемого значение передать массив например region = {"Америка", "Азия"}. Именно список.

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение rezak90 » 21 авг 2012, 13:31

zavbak писал(а):Добрый день. Подскажите как можно в качестве сравниваемого значение передать массив например region = {"Америка", "Азия"}. Именно список.
куда передать? я так понял хотите сравнить значения в массиве со значениями в бд?
R.id.team
Политика на форуме запрещена

math64
Сообщения: 235
Зарегистрирован: 16 июл 2012, 07:47

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение math64 » 21 авг 2012, 13:49

zavbak писал(а):Добрый день. Подскажите как можно в качестве сравниваемого значение передать массив например region = {"Америка", "Азия"}. Именно список.
WHERE region IN ( 'Америка', 'Азия')
или создать таблицу Continents - тогда
WHERE region = Continents.name

http://www.sqlite.org/lang_expr.html

zavbak
Сообщения: 6
Зарегистрирован: 25 янв 2012, 02:25

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение zavbak » 22 авг 2012, 01:13

math64 писал(а):
zavbak писал(а):Добрый день. Подскажите как можно в качестве сравниваемого значение передать массив например region = {"Америка", "Азия"}. Именно список.
WHERE region IN ( 'Америка', 'Азия')
или создать таблицу Continents - тогда
WHERE region = Continents.name

http://www.sqlite.org/lang_expr.html


А массив в качестве параметра передать нельзя?

math64
Сообщения: 235
Зарегистрирован: 16 июл 2012, 07:47

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение math64 » 22 авг 2012, 07:42

zavbak писал(а):А массив в качестве параметра передать нельзя?
Нет, конечно. Параметр заменяет число или строку в SQL запросе. Если передадите массив, вызовется, полягаю, метод toString(), т.е. параметр будет заменён на хеш-код массива. А в SQL в Вашем случае нужно применть IN или JOIN со вспомогательной таблицей, которой будут записи 'Америка' и 'Азия':
Вот полные SQL:

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

SELECT field1, field2, region FROM table1 WHERE region IN ('Америка', 'Азия')
SELECT t.field1, t.field2, t.region FROM table1 AS t JOIN continents AS c ON t.region = c.name

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

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Сообщение KamiSempai » 22 авг 2012, 08:54

Второй вариант будет хорошь если записи уже имеются в базе. А если даже таблици такой нет или есть но нужны только те которые выбрал пользователь?
А первый вариант так и просит сделать ему SQL инъекцию :)

Я вот подумал, может такой вариант сойдет?

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

String paramString ="?";
for(i = 2; i < paramArray.size() - 1; i++)
  paramString = paramString + ",?";
String sqlString ="SELECT * FROM table WHERE region IN (" + paramString + ")";
Cursor cursor = db.rawQuery (sqlString, paramArray)
Работоспособность не проверял, вроде должно работать.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Ответить