Persistencia de datos con Sqlite implementando JDBC.

Introducción

Hablar acerca de persistencia de datos con Sqlite, es considerar que la mayoría de aplicaciones requieren almacenar información. El objetivo puede ser la toma de decisiones, como es el caso de programas empresariales; o para mantener persistente una configuración de la misma aplicación. Podríamos requerir que esta información se almacene al lado del cliente o del servidor. En este artículo veremos cómo persistir nuestro datos del lado del cliente utilizando SQLite con Java.  Ahora que sabemos qué es SQLite y hemos dado nuestros primeros pasos con Maven, vamos a crear un pequeño proyecto en Java. A este proyecto lo nombraremos “jsqlite”. En él podremos hacer persistencia de datos con Sqlite implementando o utilizando JDBC puro.

El proyecto “jsqlite” estará desarrollado en Java y tendrá las siguientes características:

  • Portable
  • Lo podremos ejecutar desde una terminal
  • Creará la base de datos en el caso que no existiera.
  • Creará una tabla en el caso que no existiera.
  • También podremos agregar, listar, borrar y actualizar registros.
  • Está basado en patrones de diseño MVC y Singleton.

¿Qué es JDBC?

Java Database Connectivity es una API de Java con una colección de interfaces y clases. Nos ayuda a que los programas Java accedan a sistemas de gestión de bases de datos.
Las aplicaciones desarrolladas en Java, mediante las interfaces y clases estándar de JDBC, pueden hacer consultas escritas en el lenguaje de consulta estructurada (SQL). ¿Quieres saber más?

Desarrollo de jsqlite (Nuestro Proyecto).

Iniciamos el proyecto de persistencia de datos con Sqlite.

Iniciamos creando la estructura de directorios base. Utilizando Maven digitamos desde la terminal la siguiente instrucción:

mvn archetype:generate  -DgroupId=ni.jug -DartifactId=jsqlite -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Nos quedará la siguiente estructura de directorios:

. 
├── pom.xml 
└── src 
   ├── main 
   │   └── java 
   │       └── ni 
   │           └── jug 
   │               └── App.java 
   └── test 
       └── java 
           └── ni 
               └── jug 
                   └── AppTest.java

Crearemos las carpetas controller, view y model dentro de la carpeta main/java/ni/jug/

mkdir main/java/ni/jug/util
mkdir main/java/ni/jug/controller
mkdir main/java/ni/jug/view
mkdir main/java/ni/jug/model

Modificación el pom.xml

Modificamos el archivo pom.xml, agregamos la dependencia para el driver de SQLite. También agregamos el plugin maven-assembly-plugin para la construcción del jar y agregamos la propiedad para que al momento de compilar Maven utilice la versión de Java 11. Nos quedará de la siguiente manera:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>ni.jug</groupId>
    <artifactId>jsqlite</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>jsqlite</name>
    <url>http://maven.apache.org</url>
    <dependencies>
    <!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
      <dependency>
         <groupId>org.xerial</groupId>
         <artifactId>sqlite-jdbc</artifactId>
         <version>3.28.0</version>
      </dependency>
    </dependencies>
   <build>
     <plugins>
        <!-- Configuracion del plugin para contruccion del jar -->
        <plugin>
           <artifactId>maven-assembly-plugin</artifactId>
           <version>3.1.1</version>
           <configuration>
              <!-- Le decimos a maven que agrege en el manifiesto cual es la clase que contiene el metodo main -->
               <archive>
                  <manifest>
                     <addClasspath>true</addClasspath>
                     <mainClass>ni.jug.App</mainClass>
                  </manifest>
                </archive>
                <!-- Le decimos a maven que incluya las dependencia en el jar -->
                <descriptorRefs>
                     <descriptorRef>jar-with-dependencies</descriptorRef>
                 </descriptorRefs>
              </configuration>
             <executions>
                <execution>
                   <id>assemble-all</id>
                    <phase>package</phase> 
                    <goals>
                        <goal>single</goal>
                    </goals>
                 </execution>
              </executions>
            </plugin>
        </plugins>
   </build>
   <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <maven.compiler.source>11</maven.compiler.source>
         <maven.compiler.target>11</maven.compiler.target>
    </properties>
</project>

Conexión con la base de datos.

Vamos a crear un clase con el nombre ConnectionBD y estará ubicada en main/java/ni/jug. Esta clase hará la conexión a la base de datos. Aunque SQLite soporta que múltiples procesos lean la base de datos, solo puede haber un proceso de escritura, por lo utilizaremos el patrón de diseño Singleton para evitar múltiples conexiones a la base de datos.

package ni.jug;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
 * Establece la conexion con la base de datos y nos devuelve la conexion por el metodo
 * @author gacs
 */
public class ConnectionBD {
    private static ConnectionBD connectionBD=null;    //inilicializamos la clase de conexion 
    private final String strUrl;                      //Almacena la direccion de la base de datos
    private final String strDriver ;                  //Almacena el driver de conexion
    private static Connection conn=null;
    private ConnectionBD() {
    	this.strDriver="org.sqlite.JDBC"; //Driver de conexion
    	strUrl="jdbc:sqlite:var/db/mybd.db"; //Parametros de conexion de conexion
    	setConnection(); //Establece la conexion y la almacena en la propiedad conn
	}
    public static Connection getConnection(){
           if(connectionBD==null)
        	   connectionBD=new ConnectionBD(); 
           return conn;
    }
    /**
     * metodo de conexion con la base de datos
     * Almacena la conexion en la propiedad conn
     */
    private void setConnection() {
        try {
            Class.forName(strDriver);
            conn=DriverManager.getConnection(strUrl);
        }catch(ClassNotFoundException | SQLException e){
               System.err.println(e);
        }		   
  }
}

Crearemos la carpeta ../var/db dentro la carpeta donde hemos creado el proyecto, al mismo nivel de la carpeta src y del archivo pom.xml. La estructura de directorio se verá así:

.
├── src
│   ├── main
│   │   └── java
│   │       └── ni
│   │           └── jug
│   │               ├── controller
│   │               ├── model
│   │               ├── util
│   │               └── view
│   └── test
│       └── java
│           └── ni
│               └── jug
└── var
    └── db

Persistiendo datos con el patrón de diseño MVC.

Modelo

Crearemos una clase que nos servirá de modelo. Esta clase tendrá el nombre de Persona y estará ubicada en la carpeta main/java/ni/jug/model. A continuación el código que contiene la clase Persona:

package ni.jug.model;
/**
 * Clase modelo Persona 
 * @author gacs
 *
 */
public class Persona {
	private int id;
	private String nombre;
	private String apellido;
	private String sexo;
    public Persona() {
	}
	public Persona(int id, String nombre, String apellido, String sexo) {
		this.id = id;
		this.nombre = nombre;
		this.apellido = apellido;
		this.sexo = sexo;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getNombre() {
		return nombre;
	}
	public String getNombreCompleto() {
		return nombre+" "+apellido;
	}
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	public String getApellido() {
		return apellido;
	}
	public void setApellido(String apellido) {
		this.apellido = apellido;
	}
	public String getSexo() {
		return sexo;
	}
	public void setSexo(String sexo) {
		this.sexo = sexo;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Persona other = (Persona) obj;
		if (id != other.id)
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "[ "+id+"  "+  nombre +"  "+apellido + "  "+  sexo + "]";
	}
}

 

Vistas

Crearemos ahora las clases que nos darán la vista de los datos, como también las vistas que interactúan con el usuario. Estas clases estarán ubicadas en la carpeta main/java/ni/jug/view. Las clases que utilizaremos como vista son:

  • NewPersona: Esta clase se utiliza para que el usuario agregue un nuevo registro en la tabla persona.
  • ListPersona: Lista los registro de la tabla persona.
  • EditPersona: Con esta clase podremos editar y modificar un registro de la tabla persona.
  • DeletePersona: Con esta clase podremos borrar un registro almacenado en la tabla persona.

NewPersona.

package ni.jug.view;
import java.util.Scanner;
import ni.jug.model.Persona;
import util.Input;
/**
 * Agrega registro a la tabla
 * @author gacs
 *
 */
public class NewPersona {
	private Persona pm; 
	public NewPersona(Persona pm) {
            this.pm = pm;
	}
	/**
	 * Este metodo es llamado por el controlador
	 */ 
    public void setRegister() {
        Scanner reg = Input.getInstance();
        System.out.println( "Nombre:" );
        pm.setNombre(reg.next());
        System.out.println( "Apellido:" );
        pm.setApellido(reg.next());
        System.out.println( "Sexo:" );
        pm.setSexo(reg.next());
    }
}

ListPersona.

package ni.jug.view;
import java.io.IOException;
import java.util.List;
import ni.jug.model.Persona;
/**
 * Lista los registro de la tabla
 * @author gacs
 *
 */
public class ListPersona {
    public void sayRegisters(List a) 
    {
        System.out.println(" Id "+"  -- Nombre --   "+" -- Apellido -- "+" - Sexo - ");
	a.forEach(p ->{
            System.out.println(p.toString());	
	});
        try
        {
            System.out.println("\n\n  Presione ENTER..");
            System.in.read();
	}
	catch(IOException exe)
	{
            System.out.printf("Error?");
	}
    }
	public void sayRegister(Persona a) 
	{
		System.out.println(" Id "+"  -- Nombre --   "+" -- Apellido -- "+" - Sexo - ");
		System.out.println(a.toString());	
	}
}

EditPersona.

package ni.jug.view;
import java.util.Scanner;
import ni.jug.model.Persona;
import util.Input;
public class EditPersona {
	
    public int getRegister() {
        int register;
        Scanner r= Input.getInstance();
        System.out.print("Digite el Id del registro a modificar :");
        register=r.nextInt();
        return register;
    }	
    public void postRegister(Persona a) {
        Scanner r= Input.getInstance();
        System.out.println("Registro a modificar");
        System.out.println("Id      :"+a.getId());
        System.out.println("Apellido  :"+a.getApellido());
        a.setApellido(r.next());
        System.out.println("Nombre  :"+a.getNombre());
            a.setNombre(r.next());
        System.out.println("Sexo    :"+a.getSexo());
           a.setSexo(r.next());
    }
}

DeletePersona.

package ni.jug.view;
import java.util.Scanner;
import ni.jug.model.Persona;
import util.Input;
public class DeletePersona {
	
	public int getRegister() {
		int register;
		Scanner r= Input.getInstance();
		System.out.println("Digite el registro a eliminar");
		register=r.nextInt();
		return register;
	}
	public boolean postRegister(Persona a) {
		Scanner r= Input.getInstance();
		System.out.println("Se borra el registro");
		System.out.println("Id      :"+a.getId());
		System.out.println("Nombre  :"+a.getNombreCompleto());
		System.out.println("Sexo    :"+a.getSexo());
		System.out.print("Desear eliminar este registro ?[S/N]");
		String bln=r.next();
		return bln.equalsIgnoreCase("S");
	}
}

Clase util Input.

Vamos a crear una clase llama Input, la cual estará en la carpeta main/java/ni/jug/util . Esta clase devuelve la clase Scanner, la cual es utilizada por las vistas para interactuar con el usuario. El contenido de la clase es el siguiente:

package ni.jug.util;
import java.util.Scanner;
/**
 * Clase de utilidad para las vistas
 * aplicado bajo el modelo singleton
 * @author gacs
 */
public class Input {
	private static Scanner input=null;
	private Input() {
		input=new Scanner(System.in);
	}
	
	public static Scanner getInstance() {
        if(input==null)
     	   		new Input(); 
        return input;
	}
}

Controlador.

Ya tenemos el modelo y las vistas de de nuestro proyecto. Ahora vamos a crear nuestra clase controladora, la que nos hará la persistencia de los datos que suministró el usuario en las vista a través del modelo.  Esta clase tendrá el nombre de PersonaController y estará ubicado en la carpeta main/java/ni/jug/controller, y tendrá el siguiente código:

package ni.jug.controller;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import ni.jug.ConnectionBD;
import ni.jug.model.Persona;
import ni.jug.view.DeletePersona;
import ni.jug.view.EditPersona;
import ni.jug.view.ListPersona;
import ni.jug.view.NewPersona;
/**
 * Clase de control para la tabla persona
 * @author gacs
 */
 public class PersonaController {
	private final String SQLINSERT="INSERT INTO PERSONA VALUES(NULL,?,?,?)";
	private final String SQLQUERY="SELECT Id,Nombre,Apellido,Sexo FROM PERSONA";
	private final String SQLQUERYONE=SQLQUERY+" WHERE Id=?";
	private final String SQLDELETE="DELETE FROM PERSONA WHERE Id=?";
	private final String SQLUPDATE="UPDATE PERSONA SET Nombre=?, Apellido=?,Sexo=? WHERE Id=?";
	private Connection conn;
	public PersonaController() {
		initController();
	}
	/**
	 * Instancia la conexion, crea la tabla si esta no existe
	 */
	
	private void initController() {
		conn=ConnectionBD.getConnection();
		PreparedStatement pst=null;
		String sqlCreate="CREATE TABLE IF NOT EXISTS PERSONA (" + 
				"	Id	integer PRIMARY KEY autoincrement," + 
				"	Nombre	 varchar ( 25 ) NOT NULL," + 
				"	Apellido varchar ( 25 ) NOT NULL," + 
				"	Sexo char  NOT NULL" + 
				"	)";
		try {
			pst=conn.prepareStatement(sqlCreate);
			pst.execute();
	    }catch( SQLException e){
	        System.err.println(e);
	    }finally {
	    	try {
	    		if(pst!=null)
	    			pst.close();
		    }catch( SQLException e){
		        System.err.println(e);
		    }
	    }		   
	}
	
	/**
	 * llama a la vista NewPersona para que el usuario agregue los valores a los campos
	 * luego estos valores se agregan a la tabla
	 */
	public void addRegister() {
		Persona persona=new Persona();
		NewPersona view =new NewPersona(persona);
		view.setRegister();
		PreparedStatement pst=null;
		try {
			pst=conn.prepareStatement(SQLINSERT);
			pst.setString(1, persona.getNombre());
			pst.setString(2, persona.getApellido());
			pst.setString(3, persona.getSexo());
			pst.executeUpdate();
	    }catch( SQLException e){
	        System.err.println(e);
	    }finally {
	    	try {
	    		if(pst!=null)
	    			pst.close();
		    }catch( SQLException e){
		        System.err.println(e);
		    }
	    }		   
	}
/**
 * Extrae los registro de la tabla y los visualiza en pantalla por medio de la vista
 * ListPersona
 */
	public void getRegisters() {
		List personas=new ArrayList<>();
		PreparedStatement pst=null;
		ResultSet rs=null;
		try {
			pst=conn.prepareStatement(SQLQUERY);
			rs=pst.executeQuery();
			while(rs.next()) {
				personas.add(new Persona( rs.getInt("Id"),
						rs.getString("Nombre"),
						rs.getString("Apellido"),
						rs.getString("Sexo")
						));
			}
	    }catch( SQLException e){
	        System.err.println(e);
	    }finally {
	    	try {
	    		if(pst!=null)
	    			pst.close();
	    		if(rs!=null)
	    			rs.close();
		    }catch( SQLException e){
		        System.err.println(e);
		    }
	    }		   
		ListPersona view =new ListPersona();
		view.sayRegisters(personas);
	}	
	
	private Persona getRegister(int a) {
		PreparedStatement pst=null;
		ResultSet rs=null;
		Persona persona=null;
		try {
			pst=conn.prepareStatement(SQLQUERYONE);
			pst.setInt(1, a);
			rs=pst.executeQuery();
			if(rs.next()) {
				persona=new Persona( rs.getInt("Id"),
					rs.getString("Nombre"),
					rs.getString("Apellido"),
					rs.getString("Sexo")
				);
			}
	    }catch( SQLException e){
	        System.err.println(e);
	    }finally {		//Nos aseguramos que se cierre el PreparedStatement y ResultSet al finalizar el metodo
	    	try {
	    		if(pst!=null)
	    			pst.close();
	    		if(rs!=null)
	    			rs.close();
		    }catch( SQLException e){
		        System.err.println(e);
		    }
	    }		   
		
		return persona;
	}
	
	/**
	 * Borra un registro
	 * llama a la vista DeletePersona 
	 * con el metodo get determina el registro que quiere eliminar de la tabla
	 * con el metodo post visualiza el registro a eliminar y pide confirmacion para borrar
	 * 
	 */
    public void deleteRegister() {
	DeletePersona dp=new DeletePersona();
	Persona persona=null;
        int reg;
	PreparedStatement pst=null;
        do {
                reg=dp.getRegister();
                persona=getRegister(reg);
                if(persona.getId()!=reg) {
                        System.out.println("Registro no encontrado!!!");
                }
        }while(persona.getId()!=reg);
	if(dp.postRegister(persona)) {
            try {
		pst=conn.prepareStatement(SQLDELETE);
		pst.setInt(1, persona.getId());
		pst.execute();
            }catch( SQLException e){
	        System.err.println(e);
	    }
            finally {		//Nos aseguramos que se cierre el PreparedStatement al finalizar el metodo
           	try {
                    if(pst!=null)
		    	pst.close();
		}catch( SQLException e){
		        System.err.println(e);
                }
            }		   
	}
    }
	
    public void editRegister() {
        EditPersona edit =new EditPersona();
        Persona persona=null;
        int reg;
        PreparedStatement pst=null;
        do {
                reg=edit.getRegister();
                persona=getRegister(reg);
                if(persona.getId()!=reg) {
                        System.out.println("Registro no encontrado!!!");
                }
        }while(persona.getId()!=reg);
        //Envia el registro para ser modificado 
        edit.postRegister(persona);
        try {
                pst=conn.prepareStatement(SQLUPDATE);
                pst.setString(1, persona.getNombre());
                pst.setString(2, persona.getApellido());
                pst.setString(3, persona.getSexo());
                pst.setInt(4, persona.getId());
                pst.executeUpdate();
        }catch( SQLException e){
            System.err.println(e);
        }
            //Nos aseguramos que se cierre el PreparedStatement al finalizar el metodo
        finally {
            try {
                   if(pst!=null)
                            pst.close();
                }catch( SQLException e){
                    System.err.println(e);
            }
        }		   
    }
}

Clase principal (main class)

Para terminar el desarrollo de nuestro proyecto vamos a modificar la clase App.java, la cual se encuentra en la carpeta main/java/ni/jug. Esta es la primera clase que se iniciará en nuestra aplicación, por lo que en su contenido tendrá el método main. El código de esta clase sea el siguiente:

package ni.jug;
import java.sql.SQLException;
import java.util.Scanner;
import ni.jug.controller.PersonaController;
import ni.jug.util.Input;
/**
 * class main
  * @author gacs
 */
public class App 
{
    public App() {
    	menus();
    }
    public static void main( String[] args )
    {
            App app = new App();
    	System.out.println("Termino");	
    }
	/**
	 * Metodo que proporciona el menu de la aplicacion
	 */
    private void menus() {
    	Scanner menu;
    	menu=Input.getInstance();
    	PersonaController pc = new PersonaController();
        byte op=0;
        do {
            System.out.println( "-- Persistencia con SQLite --" );
            System.out.println( "1. Ingresar" );
            System.out.println( "2. Listar" );
            System.out.println( "3. Borrar" );
            System.out.println( "4. Editar" );
            System.out.println( "0. Salir de la aplicacion" );
            op=menu.nextByte();
            switch (op) {
                case 0:
                    System.out.println( "Saliendo del sistema" );
                    break;
                case 1:
                    pc.addRegister();
                    break;
                case 2:
                    pc.getRegisters();	
                    break;
                case 3:
                    pc.deleteRegister();	
                    break;
                case 4:
                    pc.editRegister();	
                    break;
                default:
                   System.out.println( "Solo puede eligir una de las opciones del menu" );
                    break;
            }
        }while(op!=0);
        menu.close();
   	try {
            ConnectionBD.getConnection().close(); 
	 }catch( SQLException e){
	    System.err.println(e);
	 }		   
    }
}

Hasta aquí ya tenemos finalizado nuestro proyecto, cumpliendo lo básico para persistir nuestros datos en base de datos SQLite por medio de JDBC.

Compilación y ejecución.

Compilando el proyecto.

Para terminar con el desarrollo de nuestro pequeño proyecto de persistencia de datos en  SQLite, procederemos con la compilación. Para ello, nos trasladamos a la carpeta que contiene nuestro proyecto y ejecutamos la siguiente sentencia.

 mvn clean install

Una vez que finalice de compilar, Maven nos habrá creado una carpeta target y en ella unos archivos jar.

target/jsqlite-1.0-SNAPSHOT.jar
target/jsqlite-1.0-SNAPSHOT-jar-with-dependencies.jar

Ejecución de jsqlite.

Para ejecutar nuestro aplicación, desde una terminal correremos el archivo jsqlite-1.0-SNAPSHOT-jar-with-dependencies.jar, con el siguiente sentencia

java -jar target/jsqlite-1.0-SNAPSHOT-jar-with-dependencies.jar

Nos presentará las siguientes pantallas:

 

Ingresamos datos con la opción 1.

Listamos los datos que ingresamos con la opción 2.

Salimos de la aplicación y volvemos a ingresar y listamos los registro que contiene la base de datos para comprobar si está persistiendo nuestra jsqlite.

Buenos, finalizamos y hemos alcanzado nuestro objetivo.

¿Qué les parece? ¿Dejé por fuera algo? ¿No entendiste algo? Déjamelo en los comentarios..

SQLite: Sistema de gestión de datos relacional embebidos.

Introducción.

Las empresas hoy en día se han visto la necesidad de tener información al instante de lo que requieren sus clientes y responder así ante la competencia. Esto a llevado a utilizar los dispositivos móviles como herramientas de gestión de información utilizando sistema de gestión de datos embebidos.

Esta necesidad ha provocado que el almacenamiento de los datos en los dispositivos móviles haya mejorado, creando diversas opciones de manejadores de base de datos. Gracias a esto contamos con las base de datos embebidas o empotradas y entre estas se encuentra SQLite.

¿Que es SQLite?

SQLite es una biblioteca en Lenguaje C compacta inferior a los 600KB, que implementa un motor de base de datos transaccional de SQL incorporado. No requiere de servidor, ni configuración, lee y escribe directamente de un archivos de disco ordinarios(¿Quieres Saber mas?).

SQLite Esta bajo una licencia de dominio publico, por lo tanto es de uso gratuito, libre para cualquier uso, ya sea comercial o privado. Actualmente es implementada en muchas aplicaciones y dispositivos, entre los cuales se encuentran (¿Quieres saber mas?):

  • Android
  • iPhone y iOS
  • Mac
  • Firefox
  • Chrome

Limitaciones

No se deje engañar por el “Lite” en el nombre. SQLite fue diseñado originalmente con una política de evitar límites arbitrarios. Debido a que los límites superiores no estaban bien definidos, no se probaron, y los errores (incluidas las posibles vulnerabilidades de seguridad) a menudo se encontraban al llevar a SQLite a extremos. Por esta razón, las versiones más nuevas de SQLite tienen límites bien definidos (Quieres saber mas):

  • Los bytes máximo en una cadena de BLOB 1,000,000,000 bytes .
  • Números de columnas máximo 2,000 columnas.
  • Los bytes máximo en una sentencia SQL 1,000,000 bytes .
  • Numero máximo de relaciones 64 relaciones.
  • Numero máximo de argumentos por función 100 argumentos.
  • Numero maximo de instrucciones SELECT compuesta 500 instrucciones.
  • Longitud máxima de un patrón LIKE o GLOB 50,000 bytes.
  • Número máximo de parámetros de host en instrucción SQL 999 intrucciones.
  • La profundidad máxima de Trigger Recursivos 1,000
  • Numero máximo de base de datos asociadas 10 Base de datos.
  • Paginas en un archivo de base de datos 1,073,741,823 Paginas.
  • Numero máximo de filas en una tabla 18446744073709551616 filas.
  • Numero máximo de tamaño de archivo BD 128 terabytes.
  • Numero máximo de tablas en una base de datos 1,073,741,823 Tablas.

Algunos limites puede varias si al momento de compilar cambian los valores de las macros, no recomendado por fallas de seguridad (¿Quieres saber mas?)

Tipos de datos

SQLite utiliza un sistema de tipado dinámico mas general. El tipo de datos esta asociado con un valor en si y no con su contenedor. Este tipado dinámico es compatible con el tipo estático de otros motores de base de datos, de modo que los tipos estáticos en SQL que funcionan en otra motores de base de datos deberían funcionar de la misma manera en SQLite.

Cada uno de los datos almacenados en una base de datos SQLite implementa alguno de los siguientes tipos:

  • NULL, un valor nulo.
  • INTEGER, un entero con signo que se almacena en 1, 2, 3, 4, 5, 6 o 8 bytes de acuerdo a la magnitud del valor.
  • REAL, un número de coma flotante (real), almacenado en 8 bytes.
  • TEXT, una cadena de texto almacenada con las codificaciones UTF-8, UTF-16BE o UTF-16-LE.
  • BLOB, datos en formato binario, se almacenan exactamente como se introdujeron.
  • Fecha y hora Tipo de datos SQLite no tiene una clase de almacenamiento reservada para almacenar fechas y / o horas. En su lugar, las funciones de fecha y hora incorporadas de SQLite son capaces de almacenar fechas y horas como valores TEXT, REAL o INTEGER:
    • TEXT como cadenas ISO8601 (“AAAA-MM-DD HH: MM: SS.SSS”).
    • REAL como números de día Juliano, el número de días desde el mediodía en Greenwich el 24 de noviembre de 4714 aC de acuerdo con el proleptico calendario gregoriano.
    • INTEGER como Unix Tiempo, el número de segundos desde 1970-01-01 00:00:00 UTC.

Afinidad de tipo de datos.

La clase de almacenamiento preferida para una columna se llama su “afinidad”. La afinidad de tipo de una columna es el tipo recomendado para los datos almacenados en esa columna.

Considera esto:

CREAR TABLA t1 (a INT, b VARCHAR (10));
INSERT INTO t1 (a, b) VALORES ('123', 456);

La base de datos de tipo rígido convertirá la cadena ‘123’ en un entero 123 y el entero 456 en una cadena ‘456’ antes de realizar la inserción.

Para que el ejemplo anterior funcione en SQLite como lo hace en otros motores de base de datos SQL, SQLite admite el concepto de afinidad de tipo de datos en las columnas.

SQLite asigna a cada columna de la base de datos las siguientes afinidades de tipo de datos.

  • TEXT
  • NUMERIC
  • INTEGER
  • REAL
  • BLOB

Reglas para la implementación de la afinidad de columna.

La afinidad de una columna está determinada por el tipo declarado de la columna, de acuerdo con las siguientes reglas en el orden mostrado:

Si el tipo declarado contiene la cadena “INT”, se le asigna afinidad INTEGER.

Si el tipo declarado de la columna contiene alguna de las cadenas “CHAR”, “CLOB” o “TEXT”, entonces esa columna tiene afinidad de TEXT. Observe que el tipo VARCHAR contiene la cadena “CHAR” y, por lo tanto, se le asigna afinidad de TEXTO.

Si el tipo declarado para una columna contiene la cadena “BLOB” o si no se especifica ningún tipo, entonces la columna tiene afinidad BLOB.

Si el tipo declarado para una columna contiene alguna de las cadenas “REAL”, “FLOA” o “DOUB”, entonces la columna tiene una afinidad REAL.

Si ninguna de las reglas anteriores cumple entonces se aplica la afinidad NUMERIC.

Tenga en cuenta que el orden de las reglas para determinar la afinidad de columnas es importante. Una columna cuyo tipo declarado es “CHARINT” coincidirá con las reglas 1 y 2, pero la primera regla tiene prioridad y, por lo tanto, la afinidad de la columna será INTEGER.

Tipo de Datos en SQLite

Esta tabla muestra solo un pequeño subconjunto de los nombres de tipos de datos que aceptará SQLite. Tenga en cuenta que SQLite ignora los argumentos numéricos entre paréntesis que siguen el nombre de tipo (por ejemplo, “VARCHAR (255)”) (¿Quieres saber mas?)

Ventajas

Es fácil de usar como un software integrado con dispositivos como televisores, teléfonos móviles, cámaras, dispositivos electrónicos domésticos, etc.

Actualiza su contenido de manera continua, por lo que se pierde poco o ningún trabajo en caso de falla de energía o falla.

Las consultas de SQLite son más pequeñas que los códigos de procedimiento equivalentes, por lo que las posibilidades de errores son mínimas.

También conserva la compatibilidad hacia atrás.

Desventajas.

SQLite no se utiliza para manejar solicitudes HTTP de tráfico alto.

El tamaño de la base de datos está restringido a 140TB en la mayoría de los casos.

Otros Base de datos embebidas.

Existen otras bases de datos embebidas que podrás probar entre las cuales tenemos:

Primeros pasos con SQLite.

Instalación interfaz.

En casi todas distribuciones Linux traen la posibilidad de instalar la interfaz de SQLite con el gestor de paquete de cada distribución. Podremos instalar fácilmente SQLite en otros sistemas operativo, descargando desde la pagina oficial de SQLite, donde encontraremos, el código fuente, como también los binarios necesario para la instalación en nuestro sistema operativo.

Instalación en Debian.

En el caso de Debian y las distribuciones basadas en su arquitectura, podemos instalar con la siguientes sentencias.

sudo apt update # Actualiza la base de datos de los paquetes
sudo apt upgrade # Actualiza los paquetes.
sudo apt install sqlite3 # instala sqlite3.

Instalación en window

Primer paso: Para instalar en el sistema operativo window, descargamos de la pagina oficial el archivo zip sqlite-tools-win32-x86-3290000.zip. el cual contiene la interfaz de SQLite.

[opcional ] Copiamos el archivo sqlite-tools-win32-x86-3290000.zip al escritorio.

SQLite en Window

Segundo paso: Extraemos el contenido de sqlite-tools-win32-x86-3290000.zip con la herramientas para descomprimir de su preferencia. En mi caso estoy utilizando 7-zip para window.

Instalando SQLite en Window

Desde el navegador de archivo veremos algo asi:

Instalando SQLite En window

Tercer paso:Creamos una carpeta en la unidad C: con el nombre sqlite3 y copiamos lo archivos del archivo que descomprimimos.

SQLite: Instalacion en window

Cuarto Paso:Agregamos el directorio C:\sqlite3 al path del sistema.

  1. Busque y seleccione: Variables del sistema
  2. En la variable de entorno PATH y selecciónela. Haga clic en Editar. Si no existe la variable de entorno PATH, haga clic en Nuevo.
  3. En la ventana Editar la variable del sistema (o Nueva variable del sistema), debe especificar el valor de la variable de entorno PATH. Haga clic en Aceptar. Cierre todas las demás ventanas haciendo clic en Aceptar.

SQLite: emplementando path en window

Corriendo interfaz de SQLite en window.

Una vez que tenemos instalado y agregado la dirección en donde se encuentra el ejecutable de sqlite, en la variable del PATH. Procedemos a ejecutar sqlite desde el lanzador de window digitando sqlite3 y damos enter.

SQLite configuracion en window

Hola SQLite, verán que nos aparece la interfaz de comando de SQLite en la terminal(cmd) de window.

Ejecutando SQLite en window

Como interpreta SQLite el estandar Sql.

Desde la interfaces podemos, crear, modificar y eliminar, tablas, índices, vistas y disparadores. SQLite implementa la mayorías de sentencias del estándar de SQL 92 y aunque omite algunas característica propias del lenguaje SQL, agrega otras propias de SQLite. En el siguiente enlace podrán encontrar como implementa SQLite las sentencias del estándar SQL 92.

Además de la sentencias SQL, en la interfaz de SQLite podemos ejecutar comandos propios del interfaze, que nos proporciona ayuda para configurar la interfaz, como también sentencias que nos muestra el contenido de la base de datos.

Para visualizar las sentencias de la interfaz escriba .help, el punto ante de la palabra help no es por error, cada sentencias de la interfaz de SQLite debe iniciar con un punto.Para salir de la interfaz debe escribir desde el indicador de comando de SQLite, .exit o .quit.

Todas las sentencias SQL que queramos ejecutar desde la interfaz de SQLite debemos finalizarla con punto y como(;).

Ejecutando SQLite desde terminal

Puesta en marcha.

Para crear una base de datos con la interfaz de SQLite, debe seguir la siguiente sintaxis.

sqlite3 [dirección donde se almacenara base de datos] \ basedatos.db

Crearemos la base de datos holamundo.db en el directorio que nos encontramos actualmente, digitado en la interfaz la siguiente sentencia.

sqlite3 holamundo.db

Si la base de datos ya estuviera creada, la interfaz no lo sobrescribe, si no que abre la base de datos.

Crear tablas.

SQLite: crear tablas en la base de datos

Crearemos una tabla llamada coins con los campos Id de tipo ENTEGER , Coin de tipo TEXT y Exchange de tipo real siguiendo la sentencia.

CREATE TABLE IF NOT EXISTS COINS (Id INTERGER PRIMARY KEY,Coin TEXT, Exchange REAL);

Para comprobar la afinidad de tipo de datos crearemos otra tabla con el nombre de COINSAFINIDAD y tendrá los campos Id de tipo TINYINT, Coin de tipo VARCHAR( 25) Y Exchange de tipo FLOAT (7.4), como podrá ver, cambiamos los tipos de datos, aunque SQLite los tipos de datos son NULL,TEXT,INTERGER,REAL Y BLOB, por medio de la afinidad crea la tabla.

CREATE TABLE IF NOT EXISTS COINSAFINIDAD (Id TINYINT PRIMARY KEY,Coin VARCHAR( 25), Exchange FLOAT (7.4));

Ingresar registros.

SQLite: sintxis de ingresar datos

Ingresaremos en cada tabla dos registros, en el primer registro asignaremos al Id =1, Coin =Córdoba oro y a Exchange =1.0. Al segundo registro asignaremos al Id =2, Coin =Dollar US y a Exchange =33.05.

INSERT INTO COINS VALUES (1,”Córdoba oro”,1.0),(2,”Dollar US ”,33.05);
INSERT INTO COINSAFINIDAD VALUES (1,”Córdoba oro”,1.0),(2,”Dollar US ”,33.05);

Visualizar el contenido de las tablas.

SQLite: Sintaxis listar datos

Para visualizar el contenido de las tablas, utilizaremos las siguientes sentencias

SELECT * FROM COINS;
SELECT * FROM COINSAFINIDAD;

SQLite: gestionando datos

Hasta aquí hemos podido ver, la interfaz de SQLite es una herramienta poderosa para el manejo de las base de datos de SQLite (¿Quieres saber mas?).

Además de la interfaz de comando de SQLite, contamos con GUI  para la gestión de datos entre las cuales:

Persistencia de datos con Java y SQLite.

Podemos utilizar Sqlite para persistencia de datos en nuestros proyectos desarrollados en java, ya sea para guardar datos de usuario o para almacenar configuraciones de aplicación. Aquí les dejamos un ejemplo de como persistir datos con SQLite y JDBC.

Nosotros y terceros seleccionados utilizamos cookies o tecnologías similares con fines técnicos y, con su consentimiento, para otras finalidades (“interacciones y funcionalidades básicas”, “mejora de la experiencia”, “medición” y “segmentación y publicidad”) según se especifica en la política de cookies. Usted es libre de otorgar, denegar o revocar su consentimiento en cualquier momento.    Configurar y más información
Privacidad