Android
Android
datos SQLite
Hemos visto hasta ahora dos modos de almacenar datos en forma permanente (archivos de
texto y la clase SharedPreferences), ahora veremos otra herramienta nativa de Android para
almacenar datos en una base de datos llamada SQLite.
SQLite es una base de datos Open Source, es muy popular en muchos dispositivos
pequeos, como Android.
Las ventajas que presenta utilizar SQLite es que no requiere configuracin, no tiene un
servidor de base de datos ejecutndose en un proceso separado y es relativamente simple su
empleo.
Problema:
Confeccionar un programa que permita almacenar los datos de articulos. Crear la tabla
articulos y definir los campos codigo, descripcin del articulo y precio.
El programa debe permitir:
1
2
3
4
4
Carga de articulo.
Consulta por el codigo.
Consulta por la descripcin.
Borrado de un articulo ingresando su cdigo.
Modificacin de la descripcin y el precio.
Lo primero que haremos es crear una clase que herede de SQLiteOpenHelper. Esta clase
nos permite crear la base de datos y actualizar la estructura de tablas y datos iniciales.
Para crear una nueva clase desde Android Studio procedemos a presionar el botn derecho
del mouse sobre la carpeta que contienen todos los archivo java del proyecto y
seleccionamos New - > Java Class:
Ahora tenemos que codificar esta clase que tiene por objetivo administrar la base de datos
que crearemos. Primero hacemos que nuestra clase herede de la clase SQLiteOpenHelper:
package ar.com.tutorialesya.proyecto019;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by diego on 16/04/2016.
*/
public class AdminSQLiteOpenHelper extends SQLiteOpenHelper{
}
Pero todava nos marca un error ya que la clase padre SQLiteOpenHelper implementa
constructores que tienen parmetros, entonces tenemos que definir el constructor en esta
clase, para ello estando el cursor sobre el nombre de la clase "AdminSQLiteOpenHelper"
presionamos nuevamente las teclas "ALT" y "Enter" y en el men contectual que aparece
seleccionamos "Create constructor matching super". Aparece un dilogo con todos los
constructores que implementa la clase padre (seleccionammos el que tiene tres parmetros):
Hemos codificado en el mtodo onCreate la creacin de la tabla articulos con los campos
codigo (que es entero y clave primaria), descripcion que es de tipo texto y precio es un
valor real. El mtodo onCreate se ejecutar una nica vez (Eventualmente si uno quiere
modificar la estructura de la tabla debemos hacerlo en el mtodo onUpgrade).
Ahora implementemos la interfaz visual para resolver nuestro problema. Debemos crear en
nuestro archivo activity_main.xml la siguiente interfaz:
android.content.ContentValues;
android.database.Cursor;
android.database.sqlite.SQLiteDatabase;
android.support.v7.app.AppCompatActivity;
android.os.Bundle;
android.view.View;
android.widget.EditText;
android.widget.Toast;
et1=(EditText)findViewById(R.id.editText);
et2=(EditText)findViewById(R.id.editText2);
et3=(EditText)findViewById(R.id.editText3);
et3.setText(fila.getString(1));
} else
Toast.makeText(this, "No existe un artculo con dicho
cdigo",
}
Toast.LENGTH_SHORT).show();
bd.close();
bd.close();
if (cant == 1)
Toast.makeText(this, "se modificaron los datos",
Toast.LENGTH_SHORT)
.show();
else
Toast.makeText(this, "no existe un artculo con el cdigo
ingresado",
Toast.LENGTH_SHORT).show();
}
}
Recordar de inicializar la propiedad onClick de cada botn para enlazarlo con el mtodo
respectivo: "alta","consultaporcodigo","consultapordescripcion","bajaporcodigo" y
"modificacion".
1 - Alta de datos.
Cuando se presiona el botn "ALTA" se ejecuta el mtodo "alta" recordemos inicializar la
propiedad "onClick" del botn desde la ventana de visualizacin del archivo XML.
Lo primero que hacemos en este mtodo es crear un objeto de la clase que planteamos
anteriormente y le pasamos al constructor this (referencia del Activity actual),
"administracion" (es el nombre de la base de datos que crearemos en el caso que no exista)
luego pasamos null y un uno indicando que es la primer versin de la base de datos (en caso
que cambiemos la estructura o agreguemos tablas por ejemplo podemos pasar un dos en
lugar de un uno para que se ejecute el mtodo onUpgrade donde indicamos la nuestra
estructura de la base de datos)
Luego de crear un objeto de la clase AdminSqLiteOpenHelper procedemos a crear un
objeto de la clase SQLiteDataBase llamando al mtodo getWritableDatabase (la base de
datos se abre en modo lectura y escritura).
Creamos un objeto de la clase ContentValues y mediante el mtodo put inicializamos todos
tos campos a cargar.
Seguidamente llamamos al mtodo insert de la clase SQLiteDatabase pasando en el primer
parmetro el nombre de la tabla, como segundo parmetro un null y por ltimo el objeto de
la clase ContentValues ya inicializado (este mtodo es el que provoca que se inserte una
nueva fila en la tabla articulos en la base de datos llamada administracion)
Borramos seguidamente los EditText y mostramos un mensaje para que conozca el
operador que el alta de datos se efectu en forma correcta:
public void alta(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod = et1.getText().toString();
String descri = et2.getText().toString();
String pre = et3.getText().toString();
Esto es obligatorio para los campos de tipo text (en este caso descripcion es de tipo text)
4 - Baja o borrado de datos.
Para borrar uno o ms registros la clase SQLiteDatabase tiene un mtodo que le pasamos en
el primer parmetro el nombre de la tabla y en el segundo la condicin que debe cumplirse
para que se borre la fila de la tabla. El mtodo delete retorna un entero que indica la
cantidad de registros borrados:
public void bajaporcodigo(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod= et1.getText().toString();
int cant = bd.delete("articulos", "codigo=" + cod, null);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
if (cant == 1)
Toast.makeText(this, "Se borr el artculo con dicho
cdigo",
Toast.LENGTH_SHORT).show();
else
cdigo",
Toast.LENGTH_SHORT).show();
5 - Modificacin de datos.
En la modificacin de datos debemos crear un objeto de la clase ContentValues y mediante
el mtodo put almacenar los valores para cada campo que ser modificado. Luego se llama
al mtodo update de la clase SQLiteDatabase pasando el nombre de la tabla, el objeto de la
clase ContentValues y la condicin del where (el cuanto parmetro en este ejemplo no se lo
emplea)
public void modificacion(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod = et1.getText().toString();
String descri = et2.getText().toString();
String pre = et3.getText().toString();
ContentValues registro = new ContentValues();
registro.put("codigo", cod);
registro.put("descripcion", descri);
registro.put("precio", pre);
int cant = bd.update("articulos", registro, "codigo=" + cod,
null);
bd.close();
if (cant == 1)
Toast.makeText(this, "se modificaron los datos",
Toast.LENGTH_SHORT)
.show();
else
Toast.makeText(this, "no existe un artculo con el cdigo
ingresado",
Toast.LENGTH_SHORT).show();
}
Continuando con nuestros tutoriales de desarrollo android, en esta ocasin veremos cmo
usar bases de datos en SQLite para no perder la informacin de nuestras aplicaciones
Android.
A medida que vayamos avanzando veremos la utilidad de clases como SQLiteOpenHelper,
SQLiteDatabase, Cursor, CursorAdapter y de Herramientas como sqlite3 y SQLite
Browser.
Con el fin de facilitar tu aprendizaje usaremos un ejemplo de gua, que te permitir ir la
prctica en paralelo a las teoras y conceptos estudiados. Puedes descargar los recursos
desde aqu:
Descargar Cdigo
Apyanos con una seal en tu red social favorita y consigue el cdigo completo.
Qu es SQLite?
Es un ligero motor de bases de datos de cdigo abierto, que se caracteriza por mantener el
almacenamiento de informacin persistente de forma sencilla. A diferencia de otros SGBD
como MySQL, SQL Server y Oracle DB, SQLite tiene las siguientes ventajas:
Es por eso que SQLite es una tecnologa cmoda para los dispositivos mviles. Su
simplicidad, rapidez y usabilididad permiten un desarrollo muy amigable.
SQLite tiene ciertas limitaciones en algunas operaciones. Por ejemplo, no se puede
implementar las clausulas FULL OUTER JOIN y RIGHT OUTER JOIN. Aunque en la mayora
de casos esto no afectar, siempre habrn otras alternativas como JavaDB o MongoDB.
Para comenzar a probar nuestras bases de datos, quisiera explicarte un poco ms sobre el
ejemplo prctico que vamos a desarrollar. Se trata de una aplicacin llamada Quotilius.
Cuyo objetivo es guardar una lista de frases celebres.
Debemos almacenar el cuerpo de la frase y el autor que la trajo al mundo. El siguiente sera
un bosquejo rpido de como se vera la tabla de frases:
_id
body
author
Aristteles
Jorge Luis
Borges
Albert
Einstein
Benjamin
Franklin
Mahatma
Gandhi
La comunicacin entre ambas actividades se realiza a travs de un Intent explicito. Este nos
permite obtener los datos que el usuario ingres en Form para poder usarlos en Main e
ingresarlos en la base de datos y al mismo tiempo actualizar nuestro ListView.
Lo primero que hars ser enviar un Intent para ejecutar la actividad Form a travs de un
canal de comunicacin:
//Cdigo de envo
public final static int ADD_REQUEST_CODE = 1;
...
//Iniciando la actividad Form
Intent intent = new Intent(this, Form.class);
//Inicio de la actividad esperando un resultado
startActivityForResult(intent, ADD_REQUEST_CODE);
Una vez el usuario este en la actividad y haya presionado el botn de Guardar, devuelves
los valores de texto los EditTexts por el mismo canal hacia Main:
//Obtener los datos de los campos
EditText quoteField = (EditText) findViewById(R.id.quoteField);
EditText authorField = (EditText) findViewById(R.id.authorField);
Luego recibes los datos con el mtodo onActivityResult() y realizas las operaciones
necesarias para guardar los datos en la base de datos:
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
//Insertar registro en la base de datos
}
}
super(context,
DATABASE_NAME,//String name
null,//factory
DATABASE_VERSION//int version
);
}
@Override
public void onCreate(SQLiteDatabase db) {
//Crear la base de datos
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
//Actualizar la base de datos
}
}
Recibe el contexto con el cual se relacionar el helper. Luego invoca a super , donde se
enva el contexto y 3 parmetros adicionales:
name: String que representa el nombre del archivo con extensin .db
previa.
onCreate()
onUpgrade()
Es ejecutado si se identific que el usuario tiene una versin antigua de la base de datos. En
su interior estableceremos instrucciones para modificar el esquema de la base de datos,
como por ejemplo eliminar todo el esquema y recrearlo, agregar una nueva tabla, aadir
una nueva columna, etc. Recibe tres parmetros:
base de datos.
datos.
Como ves, es una clase muy completa que nos proporcionar flexibilidad al realizar
operaciones sobre la base de datos. Estas declaraciones facilitan la adaptacin del esquema
si en algn momento cambian los datos de las tablas o columnas.
Adicional a todas estas definiciones tenemos dos variables privadas: openHelper y
database. Ambas las usaremos en el constructor para acceder a la base de datos con el
mtodo getWritableDatabase(), el cual retorna en una instancia de SQLiteDatabase que
nos permitir leer y modificar la informacin de la base de datos directamente.
Lo primero que hicimos fue crear atributos de clase para el nombre de la base de datos y la
versin. Para crear la tabla Quotes llamamos al mtodo execSQL() de SQLiteDataBase.
Este mtodo ejecuta una sola sentencia SQL que no retorne en filas. Por lo que el comando
SELECT no es posible usarlo dentro de l.
Evita ejecutar mltiples sentencias en una sola invocacin del mtodo execSQL(). Puede
que se ejecute la primera, pero las otras no surtirn efecto.
Ahora solo queda por instancear un objeto QuotesDataSource en Main para que se cree
nuestra base de datos:
//Crear nuevo objeto QuotesDataSource
Al ejecutar la aplicacin se supone que la base de datos habr sido creada con xito en el
sistema de archivos de Android. Pero Cmo comprobar que as fue?la respuesta la
encontramos en el uso de las siguientes herramientas.
La Herramienta sqlite3
sqlite3 es una herramienta de administracin para nuestras bases de datos SQLite a travs
de la lnea de comandos. Normalmente puedes descargarla de la pgina oficial de SQLite,
pero tanto como la distribucin de Android y Android Studio ya la traen consigo.
Antes de ejecutarla en el dispositivo, primero usaremos la herramienta DDMS (Dalvik
Debug Monitor Server) de Android SDK, la cual permite visualizar las caractersticas del
dispositivo que se est ejecutando. En ella podemos visualizar estadsticas de rendimiento,
monitorear recursos y navegar por el sistema de archivos.
Si deseas ejecutarla solo presiona el siguiente icono en Android Studio:
Como ves, se visualizan todos los directorios que se encuentran en el dispositivo. As que
para ver si existe nuestro archivo de base de datos, iremos a la ruta de la cual hablamos al
inicio /data/data/<paquete>/databases/Quotes.db
Si todo sali bien, veremos nuestro archivo Quotes.db. Procede a gurdalo con el botn de
la parte superior derecha denominado Pull a file from the device. En la siguiente seccin
veremos algo interesante con l.
Ya que hemos comprobado que existe nuestra base de datos, iniciaremos sqlite3 dentro del
dispositivo. Sigue los siguientes pasos:
Paso #1
Paso #2
Navega hasta el directorio platform-tools del SDK de Android. En mi caso la direccin es:
C:/Users/James/AppDataLocal/Android/android-studio/sdk/platform-tools. Recuerda que
para navegar a travs de carpetas en DOS se utiliza el comando cd.
Paso #3
Este comando conecta remotamente la consola de comandos del dispositivo Android con tu
consola local. Cuando ya ests conectado a la consola del AVD, vers en el terminal algo
como esto:
root@android:/ #
Paso #4
La anterior instruccin accede a sqlite3 y al mismo tiempo le pide que abra la base de datos
expuesta en el directorio especificado. Si accedi a la base de datos vers los siguientes
mensajes:
SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>
Paso #5
Usa el comando .schema de sqlite3 para ver el resumen del esquema de la base de datos
Quotes:
CREATE TABLE Quotes(_id integer primary key autoincrement,body text not
null,author text not null);
CREATE TABLE android_metadata (locale TEXT);
El Esquema muestra que nuestra tabla Quotes ha sido creada correctamente. La tabla
llamada android_metadata es parte de la metainformacin de la base de datos, por lo que
siempre la encontrars.
Otra forma de comprobar el esquema de nuestra base de datos es usar sqlite3.exe en nuestro
equipo local.
Ve a la ruta para encontrar la carpeta platform-tools del SDK de Android y ejecuta la
aplicacin.
Luego usa .open para abrir el archivo en una ruta especificada o copia y pega el archivo
Quotes.db en la carpeta:
sqlite>.open Quotes.db
SQLite Browser
Si deseas conocer una herramienta ms visual, entonces SQLite Browser es una opcin que
te gustara considerar. Se trata de un editor para archivos de bases de datos SQLite de
cdigo abierto y sper sencillo de usar.
Solo basta con iniciarlo en tu pc y arrastrar el archivo Quotes.db a su editor.
Inmediatamente nos mostrar el esquema en forma de tablas con interfaz grfica de usuario,
adems de permitirnos editar la estructura y ejecutar sentencias SQL dentro de ella.
El mtodo cuya funcionalidad es aadir filas a nuestras tablas se llama insert(). Veamos
un ejemplo:
//Nuestro contenedor de valores
ContentValues values = new ContentValues();
//Seteando body y author
values.put(QuotesDataSource.ColumnQuotes.BODY_QUOTES,"Nueva Frase");
values.put(QuotesDataSource.ColumnQuotes.AUTHOR_QUOTES,"Nuevo Autor");
//Insertando en la base de datos
database.insert(QUOTES_TABLE_NAME,null,values);
Lo primero que tenemos que hacer es crear un objeto del tipo ContentValues, el cual
permite almacenar una serie de datos(Valores) relacionados a una llave(Nombre de la
columna). Donde cada elemento es aadido con el mtodo put().
Luego invocamos a insert() a travs de la instancia de la base de datos. El primer
parmetro que recibe es el nombre de la tabla. El segundo parmetro establece que si el
objeto que contiene los valores est vaco, entonces no se debe insertar el registro en la base
de datos. Y el tercer parmetro es nuestro objeto ContentValues.
Con esta informacin ya puedes crear un mtodo de guardado en la clase
QuotesDataSource para aislar la complejidad de la actividad Main. A dicho mtodo le
llamars saveQuoteRow() y recibir el cuerpo de la frase y su autor:
public void saveQuoteRow(String body,String author){
//Nuestro contenedor de valores
ContentValues values = new ContentValues();
//Seteando body y author
values.put(QuotesDataSource.ColumnQuotes.BODY_QUOTES,body);
values.put(QuotesDataSource.ColumnQuotes.AUTHOR_QUOTES,author);
Podras usar el comando execSQL() para ejecutar una sentencia INSERT, pero como ests
recibiendo datos externos, es mejor usar insert() para evitar inyecciones SQL.
Consultar Registros en SQLite
Por ejemplo, si quisiramos consultar todos los datos de la tabla Quotes usaramos el
siguiente cdigo:
Cursor c = db.query(
"Quotes", //Nombre de la tabla
null, //Lista de Columnas a consultar
null, //Columnas para la clausula WHERE
null, //Valores a comparar con las columnas del WHERE
null, //Agrupar con GROUP BY
null, //Condicin HAVING para GROUP BY
null //Clausula ORDER BY
);
Este mtodo te ayuda a aadir todas las partes posibles de las cuales se podra componer
una consulta, adems que te protege de inyecciones SQL, separando las clausulas de los
argumentos. Ahora veamos el propsito de los parmetros:
que la necesitas.
Se usa el parmetro selection para asignarle el nombre de la columna del cuerpo de la frase
y luego en el parmetro selectionArgs relacionas el valor a comparar.
Aprender ms sobre la clausula WHERE
Ahora, existe otro mtodo alternativo para realizar consultas llamado rawQuery(). Con l
debes crear un String que contenga todo el cdigo SQL de la consulta y lo pasamos como
parmetro.
Veamos:
database.rawQuery("select * from " + QUOTES_TABLE_NAME, null);
Si deseas crear una consulta generalizada usa el placeholder ? en la clausula WHERE. Luego
asignamos los valores a cada incgnita en el segundo parmetro:
String query = "select * from " + QUOTES_TABLE_NAME + "WHERE _id=?";
database.rawQuery(query, new String[]{"3"});
Tanto query() como rawQuery() retornan un objeto de tipo Cursor. Este objeto es un
Como ves, usamos mtodos get para obtener el valor de cada columna a travs del
nombre o clave. Por ejemplo, al obtener el cuerpo de la frase usamos getString() debido
a que su tipo en la tabla es text. Si fueses a obtener el cdigo, entonces usas getInt().
Puedes aprovechar este nuevo concepto e implementar un nuevo mtodo en la clase
QuotesDataSource llamado getAllQuotes(). Su objetivo es retornar en un cursor todas
las filas de la tabla Quotes, lo que asla la complejidad de la operacin sobre la base de
datos de la actividad Main:
public Cursor getAllQuotes(){
//Seleccionamos todas las filas de la tabla Quotes
return database.rawQuery(
"select * from " + QUOTES_TABLE_NAME, null);
}
Al igual que saveQuoteRow() y getAllQuotes(), puedes crear otros mtodos
para borrar,
Eliminar registros es muy sencillo, solo tenemos que usar el mtodo delete(). Recibe
como parmetros el nombre de la tabla, el estilo de la seleccin de la clausula WHERE y los
valores de comparacin para determinar que filas borrar.
En este caso usaremos el mtodo update(). Es exactamente el mismo estilo de uso que los
anteriores mtodos. Especificaremos el nombre de la tabla, los valores nuevos que vamos a
usar y luego pondremos las cadenas de la instruccin where y sus argumentos
comparativos:
//Nuestro contenedor de valores
ContentValues values = new ContentValues();
//Seteando body y author
values.put(QuotesDataSource.ColumnQuotes.BODY_QUOTES,"Nueva Frase");
values.put(QuotesDataSource.ColumnQuotes.AUTHOR_QUOTES,"Nuevo Autor");
//Clausula WHERE
String selection = ColumnQuotes.BODY_QUOTES + " = ?";
String[] selectionArgs = { "3" };
//Actualizando
database.update(QUOTES_TABLE_NAME, values, selection, selectionArgs);
La Clase CursorAdapter
Existe un adaptador especial para el manejo de bases de datos llamado CursorAdapter.
Esta clase permite poblar una lista a travs de un cursor. Es decir, el origen de datos no ser
una lista ni un arreglo, si no un cursor.
es una clase abstracta de la cual se ha de crear tu adaptador personalizado.
Con ArrayAdapter tenamos que sobrescribir el mtodo getView() para inflar nuestras
filas con los datos de la lista. Pero no es el caso con CursorAdapter. Esta vez debemos
sobrescribir dos mtodos aislados llamados bindView() y newView().
CursorAdapter
Ahora solo debemos cargar nuestra actividad principal e instancear nuestro adaptador con
un cursor que apunte a todos los registros de nuestra tabla Quotes.
adapter = new QuotesAdapter(this, sourceData.getAllQuotes());
setAdapter(adapter);
Por razones de compatibilidad en los procesos de manipulacin de datos CursorAdapter
exige que uses en todas tus tablas una llave fornea cuya etiqueta sea _id, si no lo haces
se generar un error en tiempo de ejecucin.
La Clase SimpleCursorAdapter
Si el diseo de las filas de tu lista es sencillo, entonces la clase SimpleCursorAdapter
podra ahorrarte tiempo de desarrollo. Esta clase es una extensin de CursorAdapter que
posee una implementacin completa para los desarrolladores. Con ella no tenemos que
sobrescribir mtodos ni tampoco crear un archivo de diseo, ya que permite usar layouts
del sistema.
Nuestra aplicacin Quotilius tiene elementos sencillos, por qu slo usamos dos text views
para mostrar el cuerpo de la frase y el autor. Por esta razn podemos usar el layout del
sistema two_line_list_item. Fjate como sera la creacin de un nuevo adaptador:
//Iniciando el nuevo Adaptador
adapter = new SimpleCursorAdapter(
this,//Context context
android.R.layout.two_line_list_item,//int layout
dataSource.getAllQuotes(),//Cursor c
new String[]
{ColumnQuotes.BODY_QUOTES,ColumnQuotes.AUTHOR_QUOTES},//String[] from
new int[]{android.R.id.text1, android.R.id.text2},//int[] to
SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER//int flags
);
setListAdapter(adapter);
misma actividad.
layout: Es el layour que usaremos para inflar los elementos de cada fila.
to: Es un arreglo de enteros con las referencias directas de los text views
}
}
Conclusin
Hasta aqu ya tienes claro cmo usar una base de datos SQLite sencilla en Android.
Viste como usar una clase tipo contrato para estandarizar la estructura de las tablas y
columnas.
Adems aprendiste a usar sqlite3 y SQLite Browser para editar y visualizar tu modelo de
datos.
Incluso viste adaptadores especializados para alimentar listas desde cursores.
Ahora solo queda seguir aumentando el nivel de implementacin. Es necesario que
aprendas a cubrir una base de datos con mltiples tablas y a proteger los datos con un
ContentProvider.
Tambin es recomendado emplear las clases AsyncTask o IntentService para aislar las
operaciones sobre la base de datos a un segundo plano. Operar la base de datos
directamente sobre el hilo de UI puede producir problemas de rendimiento y visualizacin.
Ah, y si vas a usar el nuevo RecyclerView con un Cursor en la creacin de una lista
alimentada desde SQLite, observa el siguiente artculo: RecyclerView Con Cursor En
Android.
Artculos Relacionados
JL
Hola James!
He creado nuevas columnas en mi base de datos y quiero que se actualice
automaticamente de la antigua version a la nueva. Como puedo ejecutar el mtodo
onUpgrade para que se creen esas nuevas columnas en esa misma tabla y se inserten
los valores correspondientes? Me da diferentes errores, que si la tabla ya existe y no
puede volverse a crear o que si hay ms valores que tablas en INSERT. Gracias!
El cdigo:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.delete(DataSource, null, null);
db.execSQL(DataBase.INSERT_SCRIPT);
}
o
Hola JL, ests usando el comando UPDATE, recuerda que con este se
aaden nuevas columnas a las tablas ya existentes. No uses delete si deseas
conservar los datos.
JL
Hola James.
He editado el comentario porque ya he solucionado el problema,
pero he encontrado otro relacionado.
Cuando ejecuto mi app o tu cdigo de ejemplo en versiones de Sqlite
menores a la 3.7.11 (Android 4.0 o menos) me salta el siguiente
error:
android.database.sqlite.SQLiteException: near ,: syntax error:
insert into DATABASE
values(null,a,a,a,a,a,a,b,c,
He estado buscando en Internet y creo que he encontrado la solucin,
pero no se como aplicarla. Es la siguiente:
http://stackoverflow.com/questions/15966165/sqlite-with-ios-5-issue
A tu cdigo como se le aplicaria?
Gracias.
D.Castt
Saludos!
Miguel Rivera
Muy buen tutorial, soy nuevo en android, y queria consultar, como se maneja la
base de datos cuando quieres que la aplicacin se ejecute de manera local solo en el
dipositivo sin conexion a internet, y donde podria encontrar algun tutorial, para
exportar esa data guardada en la base de datos hacia un archivo excel.
saludos.
Luis Pea
Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieses algn consejo o algn link.
Luis Pea
Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieses algn consejo o algn link.
Luis Pea
Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieses algn consejo o algn link.
Estoy pensando tambin en apuntarme a uno de vuestros cursos.
victor
Hola James!
Como siempre una pasada el tutorial, pero quera comentarte una cosa que estoy
viendo bastante en android que es que no se trabaja casi con clases de definicin o
como se llamen(disculpa pero no he estudiado informtica y no se muy bien como
nombrarlo), es decir, cuando trabajo por ejemplo en php, en MVC, en el modelo me
traigo la informacin que necesito de BD, y digamos que informo al objeto de una
clase, como puede ser la clase Usuario con las variables fecha_de_nacimiento,
corre, etc, y lo guardo en un array de Usuarios para trabajar con dicha clase. Claro
aqu me pregunto porque utilizas los datos directamente y no pueblas por ejemplo la
clase Quotes(abra que crearla primero con sus getters i setters), con los parametros
id, autor y frase, y los almacenas en un array de Quotess? No s si en Android no se
trabaja igual, o no lo s.
Tambin ya que te hablo de php, como segunda pregunta, quera preguntar si el
tema del login en android funciona de forma similar a php, es decir, cuando haces
login en android, existe una SESSION o algo similar, para diferencias por ejemplo
algunos mens o caractersticas de la app entre usuarios que no estas registrados y
usuarios que si lo estn? Es decir, que una opcin o botn sea solo visible para
usuarios registrados(logueados). Porque lo que he visto que realizas en el tutorial de
sincronizacin con php, requiere como una conexin constante, y la idea de la app
que estoy haciendo (un tutorial offline) tengan partes para usuarios registrados y
otras ocultas para usuarios no registrados. Y la idea que tengo es traerme datos a la
BD local del movil y hacer el login en local(que no se s es muy seguro) o tambin
como otra posible idea, es que el primer login sea con Internet, y luego quede
marcada la app con alguna SESSION o algo como en php, que ese usuario siga
logueado sin necesidad de comprobarlo nuevamente con el servidor. Claro, la idea
es que si esa persona se da de baja, deje de tener acceso a los apartados de solo
usuarios registrados(cosa que se comprobara cada X tiempo si tiene internet). Pero
bueno, no tiene porque ser est la lgica, pero supongo que ms o menos ves por
donde quiero llegar.
Disculpa por el carro que te he soltado, pero as aclaro un poco mis ideas jejej, pero
ms que nada no s si son ideas de funcionamiento muy disparatadas, y me gustara
escucharte a ti, para tener una referencia de un experto en android y no estar
buscando soluciones en google que me llevan a golpearme contra el muro.
Muchas gracias por todo James y por tu tiempo, espero no tener que molestarte
mucho ms.
Un saludo!
Vctor.
o
victor
Buena tardes primero quiero decir que es un buen tutorial muy completo, quisiera
hacerle una pregunta si yo quiero guardar los datos que obtengo del acelerometro
del celular como podria hacerlo.
Estare atenta a cualquier dato que puedas regalarme gracias
Leo
Pocas veces uno encuentra en la red tutoriales tan completos y claros. Mis
felicitaciones. Soy un programador que se inicia en android, y mis primeros pasos
sern desde aqu. Le reitero mis felicitaciones.
o
Que bien Leo, me alegra que sea de utilidad para ti. Si quieres ahondar ms
sobre sqlite, te dejo este link para crear una db con varias tablas:
http://www.hermosaprogramacion.com/2016/01/base-de-datos-sqlite-enandroid-con-multiples-tablas/
Saludos!
jesus
Jhury
hola.. quisiera saber como cargar una base de datos ya existente creada en sqlite, a
android studio para poder actualizar y agregar nuevos registros a las diferentes
tablas de mi base de datos.
Martin (Argentina)
nada mas felicitarlo por hacer tan buenos tutoriales, y por la abundancia de detalles,
algo que nunca debera de faltar en este mbito, xitos!
o
Gracias compaero! :)
Cristian
hola que tal , el codigo de esta app como puedo abrirlo en ANDROID STUDO?
erick
erick
erick
no la cree yo !
erick
Pablo
Hola Pablo. Manten las dos tablas, SQLite es relacional, de modo que no
tenemos porque restringirnos de esas cualidades.
Lo nico adicional es que debes aadir la nueva tabla como una clase
esttica al contrato o script de la base de datos en tu app.
SQLite soporta la restriccin FOREIGN KEY, pero tiene limitaciones en su
uso. Sin embargo sin esta clausula tambin es posible manejar las relaciones
con solo lgica de programacin.
Creo que voy a hacer un artculo sobre esta cuestin.
Pablo
Primero que nada te agradezco por tu tiempo y te felicit por tu pgina, tengo una
consulta, tengo ya desarrollada una aplicacin que usa base de datos, pero me
gustara agregarle que se sincronicen los datos de esta, por si se pierde el dispositivo
o es robado poder acceder los datos nuevamente, hay algn otra alternativa al de
MySQL?
o
Hola Alejandro.
Cuando hablas otra alternativa a Mysql te refieres a otro gestor de bases de
datos o a otro mtodo que no tenga que ver con bases de datos?.
Hola James.
Lo siento no me di a explicar bien, me refera a la manera de poder
respaldar esos datos en mi base de datos sqlite en android, me
interesa eso que comentas del backup en google drive de los datos y
con la cuenta de google puedas recuperarlos nuevamente. Tendrs
fuentes o informacin que me puedas proporcionar para implementar
eso? Te agradezco mucho, mi aplicacin es una sencilla app de de
hacer notas pero me gustara implementar poder recuperar esa
informacin. Saludos
Dejo el Link
https://www.dropbox.com/s/f9xcxf4hmfrs0sm/Notas.apk?
dl=0&oref=e
Aniel Cisneros
Hola Aniel.
Hablas de sincronizar los datos?
Claro, aqu hay uno con Mysql y Sqlite:
http://www.hermosaprogramacion.com/2015/07/como-sincronizar-sqlitecon-mysql-en-android/
Diego A. Juchani S.
Hola Tengo dudas cuando hago consultas cuando no hay registros en la tabla me
sale un error y se cierra la app. como puedo controlar o saber si existe la tabla y la
base de datos. por favor le pido que me ayude.
o
Hola Diego.
Me imagino que sucede cuando intentas recorrer el Cursor.
Asegrate de que el cursor no sea null con una sentencia IF antes de obtener
sus datos.
o
san
bueno creo que aveces obtienes un cursor no nulo pero con 0 entradas como
resultado.. podrias asegurarte haciendo algo asi: if (cursor != null) { if
(cursor.length > 0) { // se obtuvo un resultado con mas de una fila } // se
obtuvo un cursor con 0 filas entrantes }
San
Buenas soy algo nuevo en esto, MUCHAS GRACIAS por el tutorial muy bueno.
Estoy liado con una app android y ya he conseguido trabajar localmente con la base
de datos SQLITE. Pero mi pregunta es Solo sirve para trabajar localmente cierto?
como se sincroniza con los demas dispositivos que tengan tambin su propia local?
. supongo que habria que conectar la base de datos SQLite local con alguna base
de datos de algun servidor externo no? algun consejo?
James Revelo
Hola San.
Si, a mi parecer la solucin mas viable sera usar un servidor. La idea sera
tener una base de datos remota para que haya una sincronizacin entre los
dispositivos.
Pronto publicar un tutorial sobre sicronizacin, creo que puede darte
algunas ideas.
san
Luis Mario
Juan Carlos
Hola, muy bueno el tutorial. Tengo una pregunta, Cada vez que la aplicacin se
ejecuta se crea una nueva base de datos, o android advierte que ya existe la base de
datos con la misma versin y no la crea?.
o
James Revelo
Hola Juan.
Si solo se crea una vez. Si se desea cambiar para actualizarla debes usar
onUpgrade() para gestionar un cambio de versin.
memo
es bueno solo flataria una descricion de cada codigo sobre el manejo de la creacion
de tablas, comapos y la base de datos.. :) muy buena :) :33
Denisb
Esta bueno el tutorial, pero le hace falta un poco mas, en la clase QuotesAdapter
muestra error al setear los EditText y entre otros errores, e igual al descargar el
cdigo no viene la clase QuotesAdapter.
James Revelo
Gracias por tus apreciaciones Denisb. Voy a revisar los archivos para montar
el proyecto completo y mejorado.
Saludos amigo :D
http://www.hermosaprogramacion.com/android/
id: INTEGER
Nombre: Text
Apellido: Text
Telefono: Text // Tambin puede ser de tipo INTEGER
E-Mail: Text
El objetivo de esta app ser conectarse a la Base de Datos creada en SQLite y
realizar las siguientes operaciones con los datos:
1.- Insertar Datos
2.- Consulta y Muestra de Datos
3.- Eliminar Uno o Todos los Datos
Para no hacer tan largo el post por el momento slo vamos a conectar con la
base de datos e insertar los datos.
En el primer ActivityMain creamos los botones para realizar la operaciones en
otros Activities de la sigueinte manera:
Despus creamos el Activity para Insertar los Datos, para crear otro activity en
Android Studio nos vamos al archivo AndroidManifest.xml, damos click derecho
y en new- acitivity. En la siguiente ventana Blank, despus siguiente, damos
nombre y finalizar.
Ya esta creado el segundo activity, el cual debe tener 4 text large, 4 editText y
2 botones de la siguiente manera:
Ahora hacemos la funcin para pasar al segundo activity, es decir pasar del
Principal al segundo Activity, nos vamos al MainActivity.java que es el que hace
referencia al activity_main.xml:
public void pasaSegundo(View view) {
Intent i = new Intent(this, MainActivity2.class ); //MainActivity
2 es el nombre del .java
//Del segundo Activity
startActivity(i);
}
cdigo completo:
package com.bd.bdapp.app;
import
import
import
import
import
import
import
import
import
android.app.AlertDialog;
android.content.DialogInterface;
android.content.Intent;
android.support.v7.app.ActionBarActivity;
android.os.Bundle;
android.view.Menu;
android.view.MenuItem;
android.view.View;
android.widget.EditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is p
resent.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
@Override
public void onCreate(SQLiteDatabase db) {
//Ejecuta query para crear la tabla
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i2) {
db.execSQL("DROP TABLE IF EXISTS personas");
//Se crea la nueva versin de la tabla
db.execSQL(query);
}
}
Ahora crearemos otra clase para acceder a la base de datos y manejar los
datos de sta, vamos a empezar con el mtodo de para inserta, le vamos a
llamar ConexionBD:
package com.bd.bdapp.app;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import java.util.List;
/**
* Created by root on 19/04/14.
*/
public class ConexionBD {
private SQLiteDatabase db;
private Context nContext;
private BD objBD;
//Constructor de la Clase
//Recibe como parmetro una variable de Tipo contexto
// Esto debido a que Para acceder o crear la BD lo pide la Clase SQLi
teOpenHelper
public ConexionBD(Context c){
nContext=c;
}
public void abrirConexion(){
objBD =new BD(nContext,"BDAgenda",null,1 );
db=objBD.getWritableDatabase();
}
public void cerrarConexion(){
db.close();
}
public boolean insertar(String nombre, String apellido,String telefon
o,String email){
boolean resultado=false;
try{
String query="INSERT INTO personas(Nombre, Apellido, Telefono
, Email) VALUES('"+nombre+"','"+apellido+"','"+
telefono+"','"+email+"')";
db.execSQL(query);
resultado=true;
return resultado;
}
catch (Exception e){
resultado=false;
return resultado;
}
}
}
toast.show();
}
Cerramos Conexin
ObjCnx.cerrarConexion();
}
android.app.AlertDialog;
android.app.Dialog;
android.content.DialogInterface;
android.database.Cursor;
android.database.sqlite.SQLiteDatabase;
android.support.v7.app.ActionBarActivity;
android.os.Bundle;
android.view.Menu;
android.view.MenuItem;
android.view.View;
android.widget.EditText;
android.widget.TextView;
android.widget.Toast;
import java.util.List;
public class MainActivity2 extends ActionBarActivity {
private EditText nombre,apellido,telefono,email;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
nombre=(EditText)findViewById(R.id.editText);
apellido=(EditText)findViewById(R.id.editText2);
telefono=(EditText)findViewById(R.id.editText3);
email=(EditText)findViewById(R.id.editText4);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is p
resent.
getMenuInflater().inflate(R.menu.main_activity2, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void limpiar(View view){
nombre.setText("");
apellido.setText("");
telefono.setText("");
email.setText("");
}
public void agregar(View view){
String nombre,apellido,telefono,email;
nombre=this.nombre.getText().toString();
apellido=this.apellido.getText().toString();
telefono=this.telefono.getText().toString();
email=this.email.getText().toString();
ConexionBD ObjCnx = new ConexionBD(this);
ObjCnx.abrirConexion();
if(ObjCnx.insertar(nombre,apellido,telefono,email)==true){
String texto ="Elemento Agregado Corectamente";
Toast toast = Toast.makeText(this, texto, Toast.LENGTH_LONG);
toast.show();
}
else{
String texto ="Error al Agregar Elemento";
Toast toast = Toast.makeText(this, texto, Toast.LENGTH_LONG);
toast.show();
}
ObjCnx.cerrarConexion();
}
}
06/06/2014
Podemos ver en la imagen de abajo, la base de datos que vamos a utilizar en el ejemplo,
con los campos de la tabla que vamos a crear:
[...]
2
3
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
6
7
[...]
Tras crear el proyecto, se definen en nuestra Clase MainActivity los Controles necesarios
para la lgica de la aplicacin:
[...]
/ / Declaramos los controles nece
private EditText edProducto;
private EditText edCantidad;
1 [...]
2 //Declaramos los controles necesarios para la lgica de la aplicacin
3 private EditText edProducto;
4 private EditText edCantidad;
5 private EditText edId;
6 private Spinner spnSeccion;
7
8 //Declaramos la clase encargada de crear y actualizar la Base de Datos
9 MiBaseDatos basedatos;
1 [...]
0
1
[...]
1
1
2 //Enlazamos los controles definidos con sus recursos a nivel de layout
1 edProducto = (EditText)findViewById(R.id.edProducto);
3
edCantidad = (EditText)findViewById(R.id.edCantidad);
1
4 spnSeccion = (Spinner)findViewById(R.id.spinnerSeccion);
1 edId = (EditText)findViewById(R.id.edIdentificador);
5
1 //Creamos un Array de String con las secciones de una ferretera
6
String[] secciones =
1 {"Electricidad","Fontanera","Cerrajera","Jardinera","Tornillera","Vestimenta
7 "};
1 spnSeccion.setAdapter(new ArrayAdapter<String>(this,
8 android.R.layout.simple_spinner_item, secciones));
1
9
2
0
2
1
2
[...]
2
2
3
2
4
Adems se han definido cuatro botones encargados de lanzar los eventos On Click para las
operaciones CRUD (Create-Read-Update-Delete):
Ruta:StockFerreteria/com.academiaandroid.stockferreteria/MainActivity.java
En la imagen de abajo vemos la interfaz de nuestra aplicacin, con los botones para
realizar las operaciones CRUD:
Guardar un Registro:
[...]
/ / Evento On Click para guardar
public void guardarProducto(V
1 [...]
2 //Evento On Click para guardar un producto en la tabla Ventas
3
0
2
1
2
2
2
3
2
4
2
5
1 [...]
2
3 //Evento On Click para buscar un producto en la tabla Ventas por nombre
4
6
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
};
1
6
//Orden de los resultados devueltos por Producto, de forma Descendente
1
alfabticamente
7
String ordenSalida = Estructura.COLUMN_NAME_PRODUCTO + "DESC";
1
8
1 [...]
9
2
0 [...]
2
1 //Ejecuta la sentencia devolviendo los resultados de los parmetros pasados
2 de tabla, columnas, producto y orden de los resultados obtenidos.
2
1
3
2
3
3
3
4
3
5
3
6
3
7
1 [...]
2 //Evento On Click para eliminar un producto de la tabla Ventas por el nombre
3
7
8
1
0
[...]
1
1
1
2
[...]
//Se especifica en la clusula WHERE el campo Producto y el producto
1
3
1
4
1
5
1
6
1
7
1 introducido en el campo de texto a eliminar
8
String consulta = Estructura.COLUMN_NAME_PRODUCTO + " LIKE '" +
1 producto_eliminar + "'";
9
//Se borra el producto indicado en el campo de texto
2
sqlite.delete(Estructura.TABLE_NAME, consulta, null);
0
2
1 [...]
2
2
2
3
[...]
//Se cierra la conexin abierta a la Base de Datos
sqlite.close();
2
4 [...]
2
5
2
6
2
7
2
8
2
9
[...]
/ / Evento On Click para modifica
public void modificarProducto
1 [...]
2
3 //Evento On Click para modificar un producto de la tabla Ventas. Todos los
campos son modificables, excepto el campo _id
4
public void modificarProducto(View view)
5
{
6
//Se inicializa la clase.
7
basedatos = new MiBaseDatos(this);
8
9
1
0
1
1
[...]
1
2
[...]
1
3 ContentValues content = new ContentValues();
1
4
content.put(Estructura.COLUMN_NAME_SECCION, seccion_modificar);
1 [...]
8
1
9 [...]
2
2
1
2
8 [...]
2
9
3
0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
3
8
3
9
4
0
[...]
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Identificador:" />
7
8
<EditText
android:id="@+id/edIdentificador"
10
android:layout_width="match_parent"
11
android:layout_height="wrap_content" />
12
13
<TextView
14
android:id="@+id/txtProducto"
15
android:layout_width="wrap_content"
16
android:layout_height="wrap_content"
17
android:layout_marginTop="32dp"
18
android:text="Producto:" />
19
20
<EditText
21
android:id="@+id/edProducto"
22
android:layout_width="wrap_content"
23
android:layout_height="wrap_content"
24
android:ems="10" >
25
26
27
<requestFocus />
</EditText>
28
29
<TextView
30
android:id="@+id/textView2"
31
android:layout_width="wrap_content"
32
android:layout_height="wrap_content"
33
android:layout_marginTop="34dp"
34
android:text="Seccin:" />
35
36
<Spinner
37
android:id="@+id/spinnerSeccion"
38
android:layout_width="wrap_content"
39
android:layout_height="wrap_content"
40
android:layout_marginTop="24dp" />
41
42
<TextView
43
android:id="@+id/textView3"
44
android:layout_width="wrap_content"
45
android:layout_height="wrap_content"
46
android:layout_marginTop="35dp"
47
android:text="Total:" />
48
49
<EditText
50
android:id="@+id/edCantidad"
51
android:layout_width="wrap_content"
52
android:layout_height="wrap_content"
53
android:layout_marginRight="56dp"
54
android:ems="10" />
55
56
[...]
57
[...]
58
59
<Button
60
android:id="@+id/btnGuardar"
61
android:layout_width="wrap_content"
62
android:layout_height="wrap_content"
63
android:layout_alignParentRight="true"
64
android:layout_alignTop="@+id/linearLayout1"
65
android:onClick="guardarRegistro"
66
android:text="Guardar" />
67
68
<Button
69
android:id="@+id/btnEliminar"
70
android:layout_width="wrap_content"
71
android:layout_height="wrap_content"
72
android:layout_alignRight="@+id/btnGuardar"
73
android:layout_below="@+id/btnGuardar"
74
android:layout_marginTop="25dp"
75
android:onClick="borrarProducto"
76
android:text="Eliminar" />
77
78
79
<Button
android:id="@+id/btnModificar"
80
android:layout_width="wrap_content"
81
android:layout_height="wrap_content"
82
android:layout_alignRight="@+id/btnEliminar"
83
android:layout_below="@+id/btnEliminar"
84
android:layout_marginTop="28dp"
85
android:onClick="modificarProducto"
86
android:text="Modificar" />
87
88
89
<Button
android:id="@+id/btnBuscar"
90
android:layout_width="wrap_content"
91
android:layout_height="wrap_content"
92
android:layout_alignLeft="@+id/btnGuardar"
93
android:layout_below="@+id/btnModificar"
94
android:layout_marginTop="28dp"
95
android:onClick="buscarProducto"
96
android:text="Buscar" />
97
98
99
[...]
[...]
public static abstract c
{
public static final St
[...]
9
10
[...]
[...]
public class MiBaseDatos exte
/ / Se declaran e inicializan las va
1 [...]
2
3
2
1 private static final String SQL_DELETE_ENTRIES =
3
"DROP TABLE IF EXISTS " + Estructura.TABLE_NAME;
1
public static final int DATABASE_VERSION = 1;
4
public static final String DATABASE_NAME = "Ferreteria.sqlite";
1
5
1 [...]
6
[...]
1
7 //Mtodo para crear la Tabla que recibe la consulta Transact-SQL
1 @Override
8 public void onCreate(SQLiteDatabase db) {
1 db.execSQL(SQL_CREATE_ENTRIES);
9
}
2
0
2 //Mtodo que elimina la tabla y vuelve a llamar al mtodo que la crea
1
@Override
2
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
2
db.execSQL(SQL_DELETE_ENTRIES);
2
3 onCreate(db);
2 }
4
[...]
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
base de datosSQLite
1.
josu
12/06/2015 a las 11:15 pm
1.
Administrador
16/06/2015 a las 10:35 am
2.
Josue Castillo
15/09/2015 a las 12:13 am
1.
Academia Android
15/09/2015 a las 1:31 pm
Hola Josue,
vamos a cambiar el modo de descargarlo. Debe estar solucionado en una
media hora.
Saludos
Responder
3.
Mario
29/01/2016 a las 8:08 pm
Hola Muchas gracias por la informacin, tengo la siguiente duda, me gustara que al
seleccionar el checkbox se vea en una base de datos, como lo puedo hacer, gracias.
Responder
1.
Academia Android
30/01/2016 a las 10:01 am
4.
Ricardo
01/02/2016 a las 2:28 am
1.
Academia Android
01/02/2016 a las 1:26 pm
5.
Ruben
07/04/2016 a las 9:15 pm
disculpa si en ves de hacerlo con los spinner lo quiero hacer con radiobutton y
checkbox como lo podria hacer para guardarlos en la base de datos y luego
recuperarlos ???
Responder
1.
Academia Android
15/04/2016 a las 1:40 pm
Correo electrnico *
Web
Para evitar robots, por favor completa esta sencilla operacin *
Para poder crear bases de datos en nuestra aplicacin debemos usar las clases
hijas de "SQLiteOpenHelper". Que nos pide crear un constructor y sobreescribir
dos mtodos:
"onCreate(SQLiteDatabase db)"
"onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)"
El primero se encargara de crear las tablas si no existen y el segundo las
actualizara si nos es necesario (imaginemos que creamos una tabla con 2
columnas y mas adelante nos hace falta aadir mas columnas, con este
mtodo podramos hacerlo pasndole como parmetro la versin de la tabla
antigua y la versin de la nueva tabla).
Dentro de una base de datos podemos crear tantas tablas como nos sea
necesario, su estructura y la que usaremos en el ejemplo tendr la siguiente
forma:
id
nombre
telefono
Pedro
111111111
Sandra
111111111
Maria
111111111
Daniel
111111111
// CONSTRUCTOR de la clase
public MiBaseDatos(Context context) {
super(context, NOMBRE_BASEDATOS, null, VERSION_BASEDATOS);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLA_CONTACTOS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLA_CONTACTOS);
onCreate(db);
}
}
Como vemos en el ejemplo, en muy pocas lineas de cdigo podemos crear una
tabla en nuestro archivo de base de datos.
Lo primero que hacemos es crear tres variables:
SQLiteDatabase db = getWritableDatabase();
if(db != null){
ContentValues valores = new ContentValues();
valores.put("_id", id);
valores.put("nombre", nom);
valores.put("telefono", tlf);
valores.put("email", email);
db.insert("contactos", null, valores);
db.close();
}
}
Creamos un mtodo "insertarCONTACTO" y como parmetros los datos que
queremos insertar en la tabla (id, nombre, telefono, email). Dentro del mtodo
creamos una instancia de la clase "SQLiteDatabase" y usamos su mtodo
"getWritableDatabase()" para poder escribir en la base de datos. Encapsulamos
todo en un if por si acaso la base de datos no existe y ya dentro del if creamos
una instancia de la clase "ContentValues" que como su nombre indica es un
almacenador de un conjunto de datos. Usamos el metodo "put(key, value)" que
nos pide como primer parmetro "key" el nombre donde establecer el valor
almacenado y como segundo parmetro el valor que queremos almacenar. Una
vez almacenamos los datos insertamos una fila en la tabla usamos el mtodo
"insert(table, nullColumnHack, values)" que nos pide el nombre de la tabla
"table", un segundo parmetro en caso de que necesitemos insertar valores
nulos en la tabla "nullColumnHack" en este caso lo dejaremos pasar ya que no
lo vamos a usar y por lo tanto lo ponemos a null y como tercer parmetro
"values" nos pide un ContentValues. Para concluir deberemos cerrar la base de
datos con el mtodo "close()".
SQLiteDatabase db = getWritableDatabase();
ContentValues valores = new ContentValues();
valores.put("_id", id);
valores.put("nombre", nom);
valores.put("telefono", tlf);
valores.put("email", email);
db.update("contactos", valores, "_id=" + id, null);
db.close();
}
Prcticamente es igual que el anterior mtodo pero con la excepcin de que
aqu estamos usando el mtodo "update(table, values, whereClause,
whereArgs)" para actualizar/modificar registros de nuestra tabla. Este mtodo
nos pide el nombre de la tabla "table", los valores a modificar/actualizar
"values" (ContentValues), una condicin WHERE "whereClause" que nos sirve
para indicarle que valor queremos que actualic (en este caso cogemos como
referencia la id de nuestro contacto) y como ultimo parmetro "whereArgs"
podemos pasarle los valores nuevos a insertar, en este caso no lo vamos a
necesitar por lo tanto lo ponemos a null. Para terminar deberemos cerrar
siempre nuestra base de datos con el mtodo "close()".
// Recuperar/establecer ID
public int getID() {
return id;
}
// Recuperar/establecer NOMBRE
public String getNOMBRE() {
return nombre;
}
public void setNOMBRE(String nombre) {
this.nombre = nombre;
}
// Recuperar/establecer TELEFONO
public int getTELEFONO() {
return telefono;
}
public void setTELEFONO(int telefono) {
this.telefono = telefono;
}
// Recuperar/establecer EMAIL
public String getEMAIL() {
return email;
}
public void setEMAIL(String email) {
this.email = email;
}
}
Una vez creada nuestra clase Contactos volvemos a la clase "MiBaseDatos"
para crear los mtodos de lectura de un registro y lectura de todos los registros
de la tabla.
Los dos mtodos expuestos nos devolvern un Cursor que podremos recorrer
para recuperar todos los registros de la base de datos. Vamos a continuar con
el atculo y vamos a crear el mtodo para recuperar un registro:
}
Contactos contactos = new Contactos(c.getInt(0),
c.getString(1),
c.getInt(2), c.getString(3));
db.close();
c.close();
return contactos;
}
Este mtodo devuelve un objeto Contactos con los datos del contacto (id,
nombre, telefono, email). En este caso como queremos leer hacemos uso del
mtodo "getReadableDatabase()". Creamos una variable "valores_recuperar"
con las columnas que queremos recuperar, en este caso vamos a recuperar
todos los datos de un registro. Continuamos creando un "Cursor" que se
encarga de devolver el resultado de un registro de la tabla y lo almacena en la
memoria, le aplicamos el mtodo:
query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)
Con este mtodo conseguimos leer un registro de la tabla. Como primer
parmetro "table" nos pide el nombre de la tabla , "columns" las columnas que
queremos recuperar, con "selection" le indicamos el registro a recuperar (en
este caso recuperamos con el id), o los registros a recuperar "selectionArgs",
"groupBy" para agrupar los registros consultados , "having" es un filtro para
incluir los registros en el cursor (este parmetro se usara con groupBy),
"orderBy" para ordenar las filas y "limit" para limitar el numero de filas
consultadas.
Con el mtodo "moveToFirst()" ponemos el cursor al inicio de los datos
almacenados. Lo encapsulamos en un if por si acaso no hay datos
almacenados.
Continuamos creando un objeto "Contactos" para almacenar los datos
consultados de un registro, y los vamos recuperando del cursor con mtodos
get indicando la posicin de la columna.
Para terminar debemos cerrar la base de datos y el cursor.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Modificamos el registro 3
MDB.modificarCONTACTO(3, "PPPPP", 121212121,
"[email protected]");
// Borramos el registro 3
MDB.borrarCONTACTO(3);
}
}
Lo primero que hacemos es crear una instancia de nuestra clase "MiBaseDatos"
pasndole como parmetro un contexto.
Para insertar registros llamamos al mtodo "insertarCONTACTO(id, nom, tlf,
email)" y simplemente le indicamos los valores a insertar.
A la hora de recuperar registros hacemos uso del mtodo
"MDB.recuperarCONTACTOS.size()" que nos devuelve el numero de registros de
la tabla, sabiendo esto podemos crear 4 arrays con ese tamao para almacenar
los datos separados por categora. Con el mtodo "get(i)" recuperamos un
registro de la tabla y despus con los mtodos "getID()", "getNOMBRE()",
"getTELEFONO()" y "getEMAIL()" vamos recuperando los datos de ese registro.
Para terminar mostramos todo en el log.
Podemos modificar un registro de nuestra tabla con el mtodo
"modificarCONTACTO(id, nom, tlf, email)". Como primer parmetro indicaremos
el registro a modificar y los siguientes parmetros sern los nuevos valores
para ese registro. Mostramos el nuevo registro en el log.
Para concluir podemos borrar registros de la tabla con el mtodo
"borrarCONTACTO(id)" que nos pide como parmetro la id del registro a borrar.
1.
Luis Albes06 agosto, 2013 22:30
2.
1.
Luis Albes07 agosto, 2013 16:00
Hola, enhorabuena por el tutorial. He creado una lista expandible utilizando estos
mismos mtodos en la base de datos. El problema surge cuando quiero aadir un
item a un grupo ya existente, habiendo seleccionado previamente ste en un
Spinner. La base de datos consta de dos tablas: una para los grupos y otra para los
hijos. Tambin he creado los mtodos insertar, eliminar, actualizar y obtener en
ambos casos. Debo crear algn mtodo nuevo para poder aadir un elemento a un
grupo ya creado? Cul es la solucin? Gracias, es urgente.
Responder
Respuestas
1.
Luis Albes26 agosto, 2013 23:13
Gracias y perdona por tardar en contestar pero es que llevo un mes muy
liado.
No se realmente lo que estas haciendo pero teniendo la base de este tutorial
puedes crear los mtodos que te sean necesarios para aadir elementos a una
tabla, eso ya depende de tus necesidades. Deberas crear un mtodo que
inserte elementos en la tabla dependiendo del grupo seleccionado, para
luego poder recuperarlos segn su grupo.
Responder
5.
Annimo05 septiembre, 2013 21:13
6.
walter lopez28 septiembre, 2013 19:24
1.
Luis Albes22 noviembre, 2013 11:13
El error era mo (como era de esperarse). Tena una base de datos con una
versin ms grande que la que haba declarado. Saludos!
Responder
8.
RedRum11 noviembre, 2013 16:34
Excelente!!!
Responder
9.
Annimo18 noviembre, 2013 02:22
como consulto la fecha actual en sqlite xq en sql seria algo como esto select
getdate() y listo.... pero en sqlite no funciona
Responder
Respuestas
1.
Luis Albes22 noviembre, 2013 11:14
2.
Jorge Luis Villavicencio Correa17 marzo, 2014 21:45
https://www.youtube.com/user/anderwelt23
La fecha actual en sqlite, puede ser consultada dentro de la misma base de
datos sqlite de la siguiente manera: date('now'). Saludos!!
Responder
10.
Alejandra Ramirez05 diciembre, 2013 22:03
tengo una tabla con 4 campos y hasta ahi todo bien guardo y leo los datos sin
problema, pero cuando le quiero agregar una columna al momento de leer los datos
ya no lo hace y me manda error y ya no me abra la activity, y lo extrao es que
cuando guardo datos me dice que los guardo correctamente, el problema es al
leerlos. Espero alguien me pueda ayudar. Gracias!!!!
Responder
Respuestas
1.
Luis Albes10 diciembre, 2013 13:51
2.
Alejandra Ramirez10 diciembre, 2013 17:00
3.
Luis Albes11 diciembre, 2013 00:31
11.
francisco roman13 diciembre, 2013 22:51
Hola, oye me surgi una duda con respecto al tutorial, cada tema lo estas haciendo
en una nueva clase?
Responder
Respuestas
1.
Luis Albes14 diciembre, 2013 15:16
2.
francisco roman16 diciembre, 2013 22:14
Osea, que si cada tema que estas haciendo (creacin de la base de datos,,
insertar datos) los hiciste cada uno en una nueva clase o todos van en una
sola, o de no ser as, donde los escribiste??
3.
Luis Albes17 diciembre, 2013 13:37
Si te descargas el codigo fuente que esta al final del punto 3 veras como esta
estructurado todo. Hay 3 clases, la activity del punto 3, la clase objeto del
punto 2.4 y el resto es la clase de base de datos del punto 1.
Responder
12.
Walter Suazo21 diciembre, 2013 18:42
1.
Luis Albes21 diciembre, 2013 19:58
1.
Luis Albes28 diciembre, 2013 19:32
Hola
Podias explicarme como puedo hacer un select con el metodo rawquery en el que en
la clausula select me compare con una variable de java
Ej select * from tabla where columna = variable java
Gracias
Responder
Respuestas
1.
No he llegado a utilizar ese mtodo pero puedes probar a crear un string con
la consulta:
String consulta = "select * from tabla...";
Y aplicar ese string al mtodo rawquery:
db.rawquery(consulta, null);
Responder
15.
Hola Luis, necesito implementar la modificacion en una app, pero me manda error,
te pongo el codigo
public long GuardarModi(String [] servicio,String de, String ho, String re, String ti,
String doc, String cos, String tiem, String vi, String dom, String tel, String fa, String
co, String tra) {
// TODO Auto-generated method stub
ContentValues cv=new ContentValues();
cv.put(dependencia,de);
cv.put(horario,ho);
cv.put(requisitos, re);
cv.put(titular, ti);
cv.put(documento, doc);
cv.put(costo,cos);
cv.put(tiempo,tiem);
cv.put(vigencia,vi);
cv.put(domicilio,dom);
cv.put(telefono, tel);
cv.put(fax, fa);
cv.put(correo, co);
cv.put(tramite, tra);
//return nBD.rawquery("Update ");
//servicio=new String [] {"2"};
return nBD.update(N_TABLA,cv,"_id="+ servicio,null);
}
tambien puse el updete de la siguiente manera
return nBD.update(N_TABLA,cv,"_id=?", servicio);
pero de las dos formas me manda el siguiente error
java.lang.nullpointerexception
Espero me puedas ayudar, ya que llevo mucho tiempo atorada con este problema.
Saludos.
Responder
Respuestas
1.
Luis Albes21 enero, 2014 23:49
Doy por hecho que quieres actualizar un registro de la tabla por lo que seria
conveniente que revisaras el punto 2.2 del articulo. En principio los dos
updates parecen correctos a si que el error debe venirte de otro sitio, revisa
bien el logcat porque te dice exactamente donde esta el error en que clase
java y la linea. Ese error es tipico por ejemplo cuando un objeto, variable, ..
es nulo en ese momento de la ejecucion.
2.
Alejandra Ramirez22 enero, 2014 19:23
17.
Annimo29 enero, 2014 22:57
18.
Rebeca C. C.20 febrero, 2014 18:37
Hey qu tal? Oye, de casualidad no sabes como podra manejar imgenes en las
bases de datos? D: de verdad que me servira y mucho...
Responder
Respuestas
1.
Luis Albes21 febrero, 2014 14:59
Tienes dos opciones para almacenar una imagen en una columna de la base
de datos:
1.- Almacenar la ruta de la imagen en un String
2.- O almacenar la imagen en forma de BLOB
He estado probando la segunda por curiosidad y un blob simplemente en un
array de bytes. Entonces la cuestion es convertir la imagen a un array de
bytes y ya podrias almacenarla en una columna de la sqlite. Para recuperar la
imagen seria el proceso inverso, convertir el array de bytes en un bitmap.
4.
Luis Albes23 marzo, 2014 13:14
Hola ante todo muy buen tutorial. Tengo una duda. Quisiera saber como trabajar con
varias tablas. Por ejemplo buscar un registro en la primer tabla, buscar otro registro
en la segunda tabla y grabar.en la tarcer tabla los datos que busque de.la tabla 1 y
2.espero que me puedas ayudar.!
Gracias!
Gabriel
Responder
Respuestas
1.
eloy13 marzo, 2014 18:27
Para ser ms eficiente... o mejor dicho para tener una mejor estructuracin
de la jerarqua de las clases la clase FacadeDB es en realidad un Singleton,
con lo que su constructor e privado y para instanciarla se utiliza un mtodo
esttico generalmente llamado getInstance, que devuelve un objeto de tipo
static de la clase FacadeDB).
2.
Gracias por contestar eloy, ultimamente estoy muy liado y no tengo tiempo
para dedicarlo al blog.
Tu solucion esta bien para los que no tenemos conocimientos en sentencias
SQL. He estado hechando un ojo por google y encontre estos dos hilos en
stackoverflow:
http://stackoverflow.com/questions/2529656/how-can-i-select-records-fromtwo-different-tables-in-one-mysql-query
http://stackoverflow.com/questions/12890071/select-from-multiple-tablesmysql
En los dos casos explica como hacer una consulta a una base de datos con
dos tablas. (Las dos formas de hacerlo son validas, lo unico que al hacerlo
por sentencias SQL te ahorras algo mas de codigo).
La forma de hacerlo ya depende del desarrollador, en google hay muchos
tutoriales sobre el uso de la sintaxis SQL.
Responder
20.
eloy13 marzo, 2014 13:28
GRACIAS.
Responder
Respuestas
1.
Luis Albes14 marzo, 2014 13:03
Estoy un poco perdido en sintaxis SQL pero por lo que he podido ver en
google tu segundo ejemplo seria el valido:
update(TABLA, nuevosValores, "campoX = ? AND campoY=?", new
String[] {"arg_campoX", "arg_campoY"});
Se puede utilizar AND y OR, al igual que se utiliza en java. Hechale un ojo a
este articulo que te sacara de dudas:
http://www.w3schools.com/sql/sql_and_or.asp
Responder
21.
Annimo19 marzo, 2014 09:56
Hola muchas gracias por el tutorial. Tengo una pregunta a la que no paro de darle
vueltas e intentar. Si quisiese hacer un boton consultar para que al pulsar me
saliesen todos los contactos de la base de datos como lo tendra que hacer? gracias,
espero que alguien me pueda ayudar :(
Responder
Respuestas
1.
Frange19 marzo, 2014 22:03
Button Calibrar=(Button)
findbyid(R.id.nombredelbotoneneldiseodepantallalayout)
Calibrar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
seleccion();
}
});
Y crear una funcion seleccion:
private void seleccion(){
//Recorrer la tabla
int total=db.recuperarContacto().size();
for (int j=0;j<total;j++)
{
//Hacer lo que quieras con cada elemento (mostrar por ejemplo en textview o
listas)
int[] ids = new int[db.recuperarContacto().size()];
ids[j] = db.recuperarANIMAL().get(i).getID();
noms[j] = db.recuperarContacto().get(i).getNOMBRE();
tlfs[j] = db.recuperarContacto().get(i).getTELEFONO();
emls[j] = db.recuperarContacto().get(i).getEMAIL();
//Esas variables son las que tienes que poner donde quieras
}
}
2.
Deivid Salmeron Vicente01 mayo, 2014 02:37
22.
Deivid Salmeron Vicente30 abril, 2014 23:23
Amigo haces tutoriales ?? estara bueno que subieras uno de este tema porque eres
un maestro para esto mi profesor no ensea nada de esto
Responder
Respuestas
1.
Deivid Salmeron Vicente01 mayo, 2014 00:17
2.
Luis Albes01 mayo, 2014 13:27
25.
Dante Valencia01 septiembre, 2014 18:07
una duda, el modo de crear los mtodos para leer y registrar datos es el mismo?
Responder
26.
Annimo05 octubre, 2014 20:20
27.
Jair Tavera17 noviembre, 2014 00:38
29.
Eduardo Gutirrez24 enero, 2015 10:04
Hola estoy en las mismas tengo una duda deseo hacer dos botones para consultar al
cursor donde estan cargados todos los datos de la tablay poderlos cargar en 3
textview uno int y dos strtring. La idea es de un boton adelante y otro atras para
navergar sobre los registros cargados en el cursor. De antemano gracias a quien me
pueda colaborar.
Responder
31.
joz17 septiembre, 2015 18:33
eres un crack viejo nose si me vaya a funcionar pero al menos me aclaraste muchas
dudas sobre base de datos gracias
Responder
32.
christian jordy mamani sucasaire16 enero, 2016 01:18
Holas tengo una duda cuando guardo datos del sqlite en el cel, se guarda en el
archivo DATA pero no puedo acceder a ella...hay alguna solucin para extraer ese
dato en un archivo o guardarlo en la memoria externa?
Responder
33.
Annimo16 febrero, 2016 23:33
Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieseis algn consejo o algn link.
Responder
34.
Annimo17 febrero, 2016 02:04
Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieseis algn consejo o algn link.
Responder
Bases de Datos Android - Como crear una Base de Datos SQLite en Android
Arriba ves una clase tipica para crear y gestionar una Base de datos, como ves no tiene
mucho cogigo, costa de 3 partes claramente identificadas, una primera parte en la que
definen las variables de tipo texto (String) que contendran las sentencias de SQL para crear
las Tablas y/o actualizarlas, el metodo OnCreate de la clase, que es el encargado de crear la
tabla, y por ultimo el metodo OnUpdate, que normalmente estara vacio, es el que
utilizamos en el caso de necesitar crear alguna tabla nueva o algun campo nuevo, esto se
utiliza si por ejemplo actualizamos nuestra aplicacion porque hemos aadido nuevas
funcionalidades que requieren mas campos en nuestra BD.
Una sentencia SQL. El lenguaje de consulta estructurado o SQL (por sus siglas en ingls
structured query language) es un lenguaje declarativo de acceso a bases de datos
relacionales que permite especificar diversos tipos de operaciones en ellas. Una de sus
caractersticas es el manejo del lgebra y el clculo relacional que permiten efectuar
consultas con el fin de recuperar de forma sencilla informacin de inters de bases de
datos, as como hacer cambios en ella.
Supongo que no tendras mucha idea es esto no te preocupes! voy a explicar por encima las
sentencias que vamos a usar. Una Base de Datos es como un contenedor, dentro de este
puedes crear tantas tablas como quieras, las tablas son como organizadores, cuando
tenemos muchos campos y una aplicacion compleja, lo normal es crear varias tablas, no
esta bien crear todos los campos en una sola tabla (como poder se puede) pero no seria
correcto por motivos de organizacion y sobre todo de rendimiento (a la hora de hacer las
consultas cuanto mas grande es la tabla, es decir cuanto mas campos, mas tiempo se
necesita para consultar los datos), en nuestro caso si es correcto crear una tabla, porque es
una aplicacion sencilla con pocos campos. El ultimo componente de una BD son los
campos, los campos son las columnas que tendra la tabla, y las filas seran los registros que
contenga.
Una tabla debe contener siempre un campo llamado ID en el caso de Android este campo se
llamara _id asi en minusculas este campo es de tipo numerico y se auto-genera e
incrementa con cada registro que aadimos a la BD, piensa que una base de datos es como
un excel, contiene tantas columnas como campos, y tantas filas como registros y es
necesario que cada fila se numere de forma unica, el campo _id es como el DNI de cada
fila, de esta forma podremos encontrar la fila cuando la necesitemos, y en el caso de que
creemos otras tablas ese campo _id sera en que necesitemos para relacionar cada tabla entre
si, por eso este campo es muy importante. Voy a ponerte un ejemplo para que lo veas de
forma mas grafica una tabla con datos y lo comprendas mejor:
La tabla de arriba, contiene 4 campos (ID, Title, Type, Comment) y tiene 20 registros, fijate
que el campo ID es el numerico y unico. Cuando consultemos una Base de Datos, en
concreto esta tabla, pondremos un elemento llamado cursor en la primera FILA y nosotros
medienate otras instrucciones seremos capaces de desplazarnos por ella, leer los registros,
etc... mas adelante en proximas lecciones ya veremos como.
Ahora que a grandes rasgos ya sabes como es una Base de Datos vamos a ver el tema de las
sentencias SQL en concreto comencemos con la de crear una Base de datos, fijate en cada
parentesis y en cada coma TODO es necesario!!
Estas sentencias son MUY sensibles tienes que respetar su sintasis, ahora vamos a analizar
la sentencia:
String sqlCreate2 = "sentencia de SQL". Aqui se crea una variable de tipo texto que se
llama sqlCreate2, entre las comillas se pone la sentencia de SQL, estas comillas no forman
parte de la sentencia, son de la propia instruccion de Android para crear la variable de tipo
texto.
CREATE TABLE lugares (campos a crear);. Aqui definimos el tipo de sentencia SQL,
estamos diciendo que vamos a crear una tabla llamada lugares y entre los parentesis van los
campos que contendra dicha tabla acabamos con el ; que es propio de la instruccion de
Android, como hemos visto hasta aquicada instruccion de Android acaba con el ;.
_id INTEGER PRIMARY KEY AUTOINCREMENT, nombre TEXT Aqui creamos el
campo principal _id y el campo nombre que es de tipo texto, fijate con detalle que se pone
siempre el nombre del campo seguido del tipo de dato y entre ellos se separan mediante
'comas' esto debe ser asi, lo normal es poner comas de mas o de menos, esto es un error
muy habitual, presta atencion a las comas y parentesis!!.
Cuando llamemos a nuestra base de datos desde nuestro programa principal, este ira a la
clase que hallamos creado con anterioidad que extiende de la clase SQLiteOpenHelper y
ejecurara el codigo que se encuentra en el mtodo onCreate() y cuando he dicho por
primera vez, lo digo porque este codigo se ejecutara una unica vez, solo para crear la BD,
una vez creada, este metodo no se volera a ejecutar NUNCA.
Las tareas tpicas que deben hacerse en este mtodo sern: la creacin de todas las tablas
necesarias y la insercin de los datos iniciales si son necesarios, en este caso, slo creo la
tabla. Para la creacin de la tabla uso la sentencia SQL que comente antes y la ejecutaremos
contra la base de datos utilizando el mtodo ms sencillo de los disponibles en la API de
SQLite proporcionada por Android, llamado execSQL(sentencia SQL). Este mtodo se
limita a ejecutar directamente el cdigo SQL que le pasemos como parmetro.
La proxima leccion seguiremos analizando todo esto, espero que la cosa se valla
entendiendo, no te agobies, poco a poco iras encajando el puzzle, recuerda que puedes
opinar y/o sujerir mejoras en el FORO, por favor no te cortes, opina, mi objetivo es que
puedas aprender a programar, y no me bienen mal opiniones constructivas para mejorar la
web. Saludos!
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBAdapter {
private final static int DB_VERSION = 1;
private final static String DB_NAME = "nombreDB";
private final static String TB_NAME = "nombreTabla";
private class Columns implements BaseColumns {
public final static String ID = "_id";
public final static String CAMPO1 = "campo1";
public final static String CAMPO2 = "campo2";
public final static String CAMPO3 = "campo3";
// ...
}
private final static String CR_TABLE = "create table if not exists "
+ TB_NAME + "(" + Columns.ID
+ " integer autoincrement primary key, " + Columns.CAMPO1
+ " text not null, " + Columns.CAMPO2 + " text, " +
Columns.CAMPO3
+ " integer)";
private DBHelper dbHelper;
public DBAdapter(Context context) {
dbHelper = new DBHelper(context);
}
private class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CR_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
db.execSQL("drop table if exists " + TB_NAME);
onCreate(db);
}
}
}