Una vez creado importaremos el jar del driver jTDS a nuestro proyecto, para esto hacemos
click derecho sobre nuestro proyecto->Properties->Java Build Path->Libraries y en Add
External JARs..., buscamos nuestro jar descargado y click en OK.
La clase DBConnection
Creamos una nueva clase que llamaremos DBConnection y la crear como un Singleton,
Aadimos los atributos URL, USER y PASS que contendrn la informacin y credenciales
para conectarnos a la base de datos.
Ya saben lo que pienso sobre el cdigo duro pero dado que es un ejemplo, podemos dejarlo
pasar.
1
Despus creamos el mtodo que har la conexin, y en el instanciamos el driver para
despus pasarle nuestros datos de conexin al DriverManager.
Bueno, ya para terminar creare otro mtodo singleton que obtendr la conexin hecha en
nuestro mtodo conectar().
2
Llamando a nuestra conexin
Ahora para llamar llamar a nuestra clase lo haremos de la manera como se llaman a las
clases Singleton.
Si habis hecho conexiones a mysql desde java sabris que con una clase que
contenga 4 o 5 lineas de cdigo podamos realizar nuestra conexin a mysql, podis
comprobarlo aqu, posteriormente solo tenamos que manejar los datos obtenidos (7 u
8 lineas) y ya podamos mostrar resultados en nuestro programa. Bien, esto en
android cambia y se vuelve ms complejo ya que, por seguridad, deberemos crear un
webservice para que nos sirva de puente entre nuestra aplicacin y nuestro servidor.
Un Webservice suele ser un archivo PHP que recibe peticiones de nuestra app y se
las enva al servidor, posteriormente el servidor responde a nuestro webservice, y
este, a su vez, responde a nuestra app. Os dejo una imagen para que lo entendis
mejor.
3
Mi base de datos esta compuesta por una tabla "personas" con los
siguientes campos:
DNI---Varchar
Nombre--Varchar
Telfono--Varchar
Email.--Varchar
Uno o varios WebService (segn necesitemos). Yo voy a utilizar 2:
Insert.php
selectAll.php
Una conexin mediante la clase HttpClient de la API de Apache
No hay que agregar libreras, esta API va incluida en el repositorio
android.
Ejecutarlo todo mediante hilos AsyncTask.
A partir de la versin 3 o superior, correrlo todo en AsyncTask es
obligatorio.
4
Antes de continuar vamos a ir a nuestro archivo AndroidManifest y vamos a agregar
permisos de INTERNET, muy importante.
Una vez hecho todo lo anterior vamos a crear un mtodo que enve la informacin que
introducimos en los campos a nuestroWebService para que este se lo comunique al
servidor y obtener una respuesta.
5
Bueno, no os asustis de ver tanta linea, ante todo saber que solo trabajamos con 2
clases y un ArrayList:
HttpClient: Clase encargada de enviar la informacin almacenada
en httpPost a nuestro WebService.
HttpPost: almacena los datos que sern enviados, por medio de HttpClient, a
nuestro WebService.
List: Almacena objetos de tipo "NameValuePair" el cual almacena por
constructor (NameValuePair es una interfaz la cual implementa la
clase BasicNameValuePair ) una variable y el valor que contendr dicha variable, las
cuales son las que obtendr nuestro WebService.
Veamos:
Implementamos las clases con las que vamos a trabajar:
HttpClient httpclient=new DefaultHttpClient();
HttpPost httppost=new HttpPost("URL DE NUESTRO
WEBSERVICE EN EL SERVIDOR")
Yo tengo puesto la ip local de mi pc, ya que si ponemos
localhost o 127.0.0.1, el dispositivo va a buscar su propio localhost, el que va incluido
en el mvil, y puede crear errores, lo mejor si estas probando, la ip local de tu pc. Si
utilizas el emulador que trae el eclipse SDK android, tendrs que poner 10.0.0.2, ya
que si no te dar fallo.
List nameValuePairs=new ArrayList(4);
En este caso le damos a nuestro ArrayList un tamao (4) ya que
son el nmero de variables con las que vamos a tratar, si quieres utilizar 3, pones 3, y
as sucesivamente.
6
Bien, esto no tiene mucha historia, almacenamos objetos
de BasicNameValuePair con una variable y el valor que va a tener que le pasamos
por constructor. Agregamos a nuestroArrayList un objeto de este tipo segn el
tamao que le hayamos dado.
Una vez almacenados los datos, le pasamos el ArrayList a nuestra
clase HttpPost para que lo codifique:
httppost.setEntity(new UrlEncodeForEntity(nameValuePairs));
Bueno, una vez que lo tenemos codificado con la url del webservice y la
informacin de nuestro ArrayList, hacemos que HttpClient lo enve:
httpclient.execute(httppost);
Veamos, este es nuestro WebService, un archivo escrito en PHP que interactua con
nuestro servidor, su funcionamiento sera de la siguiente manera:
Rellenamos las variables del localhost con la informacin de nuestro servidor:
Hostname: Nombre del host.
Database: Nombre de nuestra base de datos.
Username: Nombre de usuario del servidor.
Password: Contrasea del servidor.
Posteriormente, con los datos de servidor que hemos introducido, le pedimos
que conecte al servidor y almacene la respuesta en otra variable:
$localhost =
mysql_connect($hostname_localhost,$username_localhost,$password_localhos
t)
Si no puede conectar enviara un informe de error
or trigger_error(mysql_error(),E_USER_ERROR);
Una vez conectado al servidor, buscar nuestra base de datos y se conectar:
mysql_select_db($database_localhost, $localhost);
Posteriormente, y una vez encontrad la base de datos, obtendr las variables
que le pasamos por nuestra aplicacin y las almacenar en otras variables que pueda
manejar mejor.
$nombre=$_POST['nombre'];
$dni=$_POST['dni'];
$telefono=$_POST['telefono'];
7
$email=$_POST['email'];
Daos cuenta de que los nombres entre comillas simples se
llaman igual a las variables que les pasamos por nuestra app.
Almacenadas las variables, introduce los valores en un sentencia sql para
realizar una consulta al servidor:
$query_search = "insert into personas(nombre,dni,telefono,email)
values ('".$nombre."','".$dni."','".$telefono."','".$email."')";
Cuidado con las comillas simples y dobles, que puede ser un
folln jeje.
Finalmente, y si todo ha ido bien, realizar la consulta a nuestro servidor, el
cual, en caso de fallar la sentencia, nos enviar un informe de error.
$query_exec = mysql_query($query_search) or die(mysql_error());
Cerramos la conexin.
mysql_close($localhost);
Bien, ya tenemos el cdigo java para conectarnos a nuestro servidor por medio de
android y tenemos un webservice escrito en PHP que hace de puente entre nuestra
app y el servidor, pero an nos queda un ltimo paso, realizar la consulta por medio de
una clase AsyncTask.
NOTA:No voy a hacer aqu una explicacin sobre el funcionamiento de una clase AsyncTask,
ya que me quedara muy extenso el post, en el futuro crear un tema para esta clase. En
google puedes encontrar mucha informacin sobre esta clase.
Nos volvemos a nuestra clase, y creamos una clase interna que herede
de AsyncTask:
8
Bien, en el mtodo doInBackground creamos una condicin if, en el cual
introducimos como condicin el mtodo insertar() (por esa razn lo hice booleano) si
se los datos han sido insertados, el mtodo nos devuelve true y nos muestra
un Toast con el xito de la operacin y limpiando nuestro formulario, todo esto debe
correr en un hilo ya que si no bloqueara nuestroAsyncTask y nos funde a errores, si
los datos no han podido ser insertados, el mtodo insertar nos devolver false, y nos
mostrar un Toast corriendo en un hilo.
Bueno, mencionar que mi dispositivo android no me hace bien las capturas de fotos y
nos puedo mostrar una captura con datos, pero si os puedo mostrar como los muestra
mi tabla personas una vez insertado los datos.
9
Listas en Android con ListView
ListView es uno de los patrones de diseo ms comunes de Android, es la lista en la que
se puede hacer scroll que aparece en casi todas las aplicaciones de Android. Pueden ser
muy sencillas desde slo mostrar una lnea de texto, hasta tener imgenes, mltiples
botones, ser desplegables entre otros.
10
ListView Android
Como la mejor forma de aprender es haciendo vamos a crear una pequea aplicacin y
simple que va a mostrar una lista de cosas por hacer y la cual vamos a llamar MiLista.
Crear el Proyecto
Vamos a utilizar Android Studio.
Nombre: MiLista.
Minimum SDK: 15, es decir Android 4.0.3 en adelante, que ms que suficiente para este
tutorial.
Actividad: Activity with Fragment y le dejaremos el nombre por defecto MainActivity.
Hacemos doble click sobre este archivo si ya no est abierto y nos vamos a encontrar
con este cdigo:
<RelativeLayout xmlns:android="http://schemas.android.com/app/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="matc
h_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity
_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity$PlaceholderFragment">
android:layout_height="wrap_content" />
</RelativeLayout>
11
Que es el contenido por defecto del Fragmento con la palabra Hello World. Vamos a
borrar el TextView y lo vamos a reemplazar por nuestra lista quedndonos el cdigo as:
<RelativeLayout xmlns:android="http://schemas.android.com/app/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity$PlaceholderFragment">
<ListView
android:id="@+id/milista"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
Como ven ahora tenemos un elemento ListView el cual tiene las siguientes propiedades:
Adapter
Muy bien ahora tenemos nuestro ListView dentro del fragmento de la actividad
principal, pero no nos sirve de mucho vacio.
El ListView est comprendido por ListItems estos Items son cada una de las filas de
nuestro ListView y el contenido de estos Items viene dado por un adaptador o Adapter
en el lenguaje de Android.
12
Podemos pensar en el Adapter como un puente entre nuestra vista y los datos que
queremos mostrar, este Adapter puede convertir los datos de un arreglo, de una base de
datos, de un archivo JSON o cualquier otra fuente a un formato que entienda nuestro
ListView.
ArrayAdapter
Para este tutorial, que es el primero de la serie, vamos a utilizar un adaptador
llamado ArrayAdapterque como su nombre lo indica toma un arreglo en Java y lo
transforma a nuestro ListView. Este es uno de los Adaptadores ms simples, y espera un
slo campo de texto o TextView para llenar.
Abrimos la clase MainActivity, dentro de esta clase tenemos una clase llamada
PlaceholderFragment que es la que maneja el Fragmento donde tenemos nuestra lista.
@Override
Bundle savedInstanceState) {
13
// B. Creamos un nuevo ArrayAdapter con nuestra lista de cosasPorHacer
android.R.layout.simple_list_item_1, cosasPorHacer);
miLista.setAdapter(arrayAdapter);
return rootView;
Vamos a ver lo que hicimos, en el cdigo pueden cada punto como comentario:
A. Primero creamos un arreglo tipo String llamado cosasPorHacer, cada uno de los
elementos va a representar una fila en nuestra lista.
Esto es todo una vez que tengas este cdigo puedes correr la aplicacin en el botn de
Build de Android
14
Lo puedes hacer correr en un telfono que tengas conectado a tu computador o en el
emulador. Vers una pantalla parecida a esta:
Mi Lista 1
15
Como ves Android coloca cada elemento en una fila, tiene el separador por defecto de
las listas y si hacemos la lista lo suficientemente larga agregando ms elementos a
nuestro arreglo tendremos Scroll automticamente.
miLista.setAdapter(arrayAdapter);
miLista.setOnItemClickListener(new AdapterView.OnItemClickListener(
) {
@Override
Toast.LENGTH_LONG).show();
});
Le asignamos el Listener a nuestra lista para que reaccione cada vez que se toca alguno
de los items.
Sobreescribimos el mtodo onItemClick que va a tener los parmetros mostrados
Creamos un Toast, que es un pequeo mensaje que se despliega sobre la ventana, en el
cual mostramos la posicin del item que le hicimos click, la posicin comienza en el
nmero 0.
Ahora corremos la aplicacin y cuando toquemos un item nos saldr un mensaje como
este:
16
17
1. Crea un nuevo Application Android Project con la siguiente
configuracin:
Nombre de la aplicacin: Prueba de SQLite
Nombre del proyecto: SQLiteTest
Nombre del paquete: com.tutorial.sqlitetest
Actividad: Actividad en blanco
Nombre de la actividad: MainActivity.java
Nombre de Presentacin: activity_main.xml
2. Crearemos dos clases en el paquete com.tutorial.sqlitetest, estas se
llamaran, SQLiteHelper.java y SQLite.java.
18
final privado cadena sql = "CREATE TABLE" + __tabla__ + "(" + __campo_id +
"INTEGER PRIMARY KEY AutoIncrement NOT NULL," + __campo_nombre + "TEXTO" +
__campo_apellido + "TEXTO" + __campo_sexo + "TEXTO)" ;
/ **
* Constructor de clase
**/
pblico SQLiteHelper ( Contexto contexto ) {
sper ( contexto , __DATABASE , nula , __VERSION );
}
@Anular
pblica vaco onCreate ( SQLiteDatabase db ) {
db . execSQL ( sql );
}
@Anular
pblica vaco ONUPGRADE ( SQLiteDatabase db , int OldVersion , int newVersion
){
si ( newVersion > OldVersion )
{
// Elimina tabla
db . execSQL ( "DROP TABLE IF EXISTS" + __tabla__ );
// y LUEGO Creamos la nueva tabla
db . execSQL ( sql );
}
}
}
4. Por lo general, cuando se trabaja con base de datos, se introducen
datos (INSERT), se actualizan datos (UPDATE) , se eliminan datos
(DELETE) y se extraen datos (SELECT), Android cuenta
conSQLiteDatabase el cual tiene todos los mtodos necesarios para
llevar a cabo estas tareas.
A continuacin, veremos cada uno de estos mtodos y como
implementarlos en nuestra clase SQLite.java
Consultas. Para realizar consultas, SQLiteDatabase dispone de varios
mtodos llamados QUERY con diferentes parmetros de entrada, el
valor que retorna es un Cursor. Puedes ver ms sobre este QUERY en
la API de Android.
public Cursor getSoloHombres()
{
Log.i("SQLite", "query -> Consulta solo registros sexo='Hombre' " );
//tabla
//columnas ,
//selection WHERE ,
//selectionArgs , groupby, having,
//orderby
return db.query( sqliteHelper.__tabla__ ,
new String[]{ sqliteHelper.__campo_id , sqliteHelper.__campo_nombre ,
sqliteHelper.__campo_apellido},
" sexo='Hombre' ",
null, null, null,
" nombre ASC " );
}
INSERT. Para agregar registros se hace uso del mtodo INSERT para
los valores se utiliza ContentValues , en este ejemplo declaramos un
19
mtodo para agregar una nueva persona el cual cuenta con tres campos
los cuales debemos declarar en ContentValues mediante la
instruccin PUT( KEY, VALUE ). El valor de retorno sera -1 si ocurri
algn error caso contrario retorna el ID de la fila insertada.
pblica a largo insertarPersona ( Cadena nombre , cadena Apellido , Cadena sexo )
{
Log . i ( "SQLite" , "INSERT:" + nombre + "," + Apellido + "," + sexo );
ContentValues nullColumnHack, los valores vuelven db . inserte ( sqliteHelper .
__tabla__ , nulos , contentValues ); }
SQLiteHelper sqliteHelper ;
SQLiteDatabase db ;
20
}
/**
* Metodo para obtener registros que correspondan solo a "hombres" ordenados por nombre
* @return Cursor
* */
public Cursor getSoloHombres()
{
Log.i("SQLite", "query -> Consulta solo registros sexo='Hombre' " );
//tabla
//columnas ,
//selection WHERE ,
//selectionArgs , groupby, having,
//orderby
return db.query( sqliteHelper.__tabla__ ,
new String[]{ sqliteHelper.__campo_id , sqliteHelper.__campo_nombre ,
sqliteHelper.__campo_apellido},
" sexo='Hombre' ",
null, null, null,
" nombre ASC " );
}
/**
* Metodo para agregar un nuevo registro
* @param nombre
* @param apellido
* @param sexo
* @return -1 si ocurrio un error o ID de fila insertada
* */
public long insertarPersona( String nombre, String apellido, String sexo )
{
Log.i("SQLite", "INSERT: " + nombre + "," + apellido + "," + sexo );
ContentValues contentValues = new ContentValues();
contentValues.put( sqliteHelper.__campo_nombre , nombre);
contentValues.put( sqliteHelper.__campo_apellido , apellido);
contentValues.put( sqliteHelper.__campo_sexo , sexo);
//table, nullColumnHack, values
return db.insert( sqliteHelper.__tabla__ , null, contentValues );
}
/**
* Metodo para eliminar un registro
* @param id Identificador unico de registro PRIMARY KEY
* @return El nmero de filas afectadas 0 en caso contrario.
* */
public int eliminarPersona( int id )
{
Log.i("SQLite", "DELETE: id=" + id );
//table , whereClause, whereArgs
return db.delete( sqliteHelper.__tabla__ , sqliteHelper.__campo_id + " = " +
id , null);
}
/**
21
* Metodo para actualizar un registro
* @param id Identificador unico de registro PRIMARY KEY
* @param nombre
* @param apellido
* @param sexo
* @return numero de filas afectadas
* */
public int actualizarPersona( int id, String nombre, String apellido, String sexo )
{
Log.i("SQLite", "UPDATE: id=" + id + " - " + nombre + "," + apellido + "," + sexo
);
ContentValues contentValues = new ContentValues();
contentValues.put( sqliteHelper.__campo_nombre , nombre);
contentValues.put( sqliteHelper.__campo_apellido , apellido);
contentValues.put( sqliteHelper.__campo_sexo , sexo);
return db.update( sqliteHelper.__tabla__ , contentValues,
sqliteHelper.__campo_id + " = " + id , null);
}
/**
* Metodo que dado un Cursor, recorre los registros y coloca en un String
* @param Cursor
* @return String registros separados por comas y salto de linea
* */
public String imprimirListaHombres( Cursor cursor )
{
StringBuffer lista = new StringBuffer();
if( cursor.moveToFirst() )
{
do{
lista.append( cursor.getString( 0 ) + ", " );
lista.append( cursor.getString( 1 ) + ", " );
lista.append( cursor.getString( 2 ) + "\r\n" );
}while( cursor.moveToNext() );
}
return lista.toString();
}
}
5. Finalmente, debemos implementar la clase SQLite.java en
el MainActivity.java, de la siguiente forma:
paquete com . tutorial . sqlitetest ;
@Anular
protegidos void onCreate ( Bundle savedInstanceState ) {
sper . onCreate ( savedInstanceState );
setContentView ( R . diseo . activity_main );
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Log . i ( "SQLite" , "===================================================" );
Log . i ( "SQLite" , "Inicio SQLite de Aplicacin " );
SQLite SQLite = nueva SQLite ( este );
sqlite . abrir ();
22
//
Entrar . i ( " SQLite " , " Se insertan 4 registros " );
sqlite . insertarPersona ( " Paco " , " Mermela " , "Hombre" ); // id = 1
sqlite . insertarPersona ( "Juana" , "Fulanita" , "Mujer" ); // id = 2
sqlite . insertarPersona ( "Tula" , "traes" , "Hombre" ); // id = 3
sqlite . insertarPersona ( "Aquiles" , "Brinco" , "Hombre" ); // id = 4
//
Entrar . i ( "SQLite" , "Se imprime registros de tabla" );
cursor cursor = sqlite . getSoloHombres (); // Se obtiene registros
de cadena Lista = sqlite . imprimirListaHombres ( cursor );
Log . i ( "SQLite" , "Registros: \ r \ n " + Lista );
// Se Actualiza registro con ID # 3
Log . i ( "SQLite" , "Se Actualiza registro con ID # 3" );
sqlite . actualizarPersona ( 3 , "Monty" , "quemaduras" , "Hombre" );
// Se Elimina registro con ID # 4
Log . i ( "SQLite" , "Se Elimina registro con ID # 4" );
sqlite . eliminarPersona ( 4 );
//
Entrar . i ( "SQLite" , "Se imprime registros Hombres en solitario" );
cursor = sqlite . getSoloHombres (); / / Se obtiene registros
lista = sqlite . imprimirListaHombres ( cursor );
Log . i ( "SQLite" , "Registros: \r\n " + lista );
//
sqlite . cerrar ();
Log . i ( "SQLite" , "fin " );
Log . i ( "SQLite" , "===================================================" );
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@Anular
pblica booleano onCreateOptionsMenu ( Men men ) {
// Inflar el men; esto agrega elementos a la barra de accin si est presente.
getMenuInflater (). infle ( R . men . principal , men );
volver verdadera ;
}
}
No hacemos uso de ningn TextView, Button, etc, por lo que cuando
ejecutemos el programa la interfaz mostrara el clsico Hello World,
donde deberemos estar atentos es en LogCat, ah veremos paso a paso
el desarrollo de la aplicacin.
logcat
23
Con este segundo post sobre SQLite terminamos lo que es introduccin
a base de datos en Android, trate de mostrar como es el trabajo de
bases de datos con ejemplos prcticos en lugar de llenarlos de
conceptos, si se te presenta alguna duda, la API de SQLite esta por
dems completa y es de lectura obligatoria si es que quieres disear
aplicaciones android con base de datos.
24