1. 引子 try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解。不过,我亲自体验的“教训”告诉我,这个东西可不是想象中的那么简单、听话。不信?那你看看下面的代码,“猜猜”它执行后的结果会是什么?不要往后看答案、也不许执行代码看真正答案哦。如果你的答案是正确,那么这篇文章你就不用浪费时间看啦。 package Test; public class TestException {…
Java: SQLite 数据库基本操作
安装
在我们开始之前,我们需要在Java程序中使用SQLite,以确保我们有SQLite的JDBC驱动程序和Java的机器上。可以查看如何在机器上安装Java的教程。现在,让我们来检查一下如何设置SQLite的JDBC驱动程序。
- 下载 sqlite-jdbc-(VERSION).jar 的最新版本: sqlite-jdbc .
- 添加下载的jar文件sqlite-jdbc-(VERSION).jar 在类路径中,可以用带 – classpath选项,如下面例子。
前提条件
在学习本教程,应该对Java编程语言的一个很好的理解。因为要处理RDBMS,所以它需要对SQL和数据库的概念有很好的理解。
JDBC代表Java与数据库的连接,这对Java编程语言和广泛的数据库之间独立于数据库的连接标准的Java API。
JDBC库包含的API为每个通常与数据库的使用相关联的任务:
- 使得连接到数据库
- 创建SQL或MySQL语句
- 执行SQL或MySQL的查询数据库
查看和修改结果记录
从根本上说,JDBC是一种规范,它提供的接口,一套完整的,可移植的访问底层数据库的程序。可以用Java来写不同类型的可执行文件,如:
- Java应用程序
- Java Applets
- Java Servlets
- Java ServerPages (JSP)
- Enterprise JavaBeans (EJBs)
所有这些不同的可执行文件就可以使用JDBC驱动程序来访问数据库,并把存储的数据的优势。
JDBC提供了与ODBC相同的功能,允许Java程序包含与数据库无关的代码。
先决条件
如果您要学习本教程,需要具备以下两个主题内容很好的了解:
JDBC架构
JDBC API支持两层和三层处理模型进行数据库访问,但在一般的JDBC体系结构由两层组成:
- JDBC API: 提供了应用程序对JDBC的管理连接。
- JDBC Driver API: 支持JDBC管理到驱动器连接。
- JDBC API的使用驱动程序管理器和数据库特定的驱动程序提供透明的连接到异构数据库。
- JDBC驱动程序管理器可确保正确的驱动程序来访问每个数据源。该驱动程序管理器能够支持连接到多个异构数据库的多个并发的驱动程序。
常见的JDBC组件:
JDBC API提供了以下接口和类:
- DriverManager: 这个类管理数据库驱动程序的列表。确定内容是否符合从Java应用程序使用的通信子协议正确的数据库驱动程序的连接请求。识别JDBC在一定子协议的第一个驱动器将被用来建立数据库连接。
- Driver: 此接口处理与数据库服务器通信。很少直接直接使用驱动程序(Driver)对象,一般使用
DriverManager
中的对象,它用于管理此类型的对象。它也抽象与驱动程序对象工作相关的详细信息 - Connection : 此接口与接触数据库的所有方法。连接对象表示通信上下文,即,与数据库中的所有的通信是通过此唯一的连接对象。
- Statement : 可以使用这个接口创建的对象的SQL语句提交到数据库。一些派生的接口接受除执行存储过程的参数。
- ResultSet: 这些对象保存从数据库后,执行使用
Statement
对象的SQL查询中检索数据。它作为一个迭代器,可以通过移动它来检索下一个数据。 - SQLException: 这个类用于处理发生在数据库应用程序中的任何错误。
连接到数据库
继Java程序显示了如何连接到一个现有的数据库。如果数据库不存在,那么它就会被创建,终于将返回一个数据库对象。
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Opened database successfully"); } }
现在,让我们来编译和运行上面的程序在当前目录中创建我们的数据库test.db。按要求,可以改变路径。我们假设目前版本的JDBC驱动程序sqlite-jdbc-3.7.2.jar 可在当前路径
$javac SQLiteJDBC.java $java -classpath ".:sqlite-jdbc-3.7.2.jar" SQLiteJDBC Open database successfully
如果使用Windows机器上,那么就可以编译和运行代码如下:
$javac SQLiteJDBC.java $java -classpath ".;sqlite-jdbc-3.7.2.jar" SQLiteJDBC Opened database successfully
创建表
下面的Java程序将被用于先前创建的数据库中创建一个表:
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); System.out.println("Opened database successfully"); stmt = c.createStatement(); String sql = "CREATE TABLE COMPANY " + "(ID INT PRIMARY KEY NOT NULL," + " NAME TEXT NOT NULL, " + " AGE INT NOT NULL, " + " ADDRESS CHAR(50), " + " SALARY REAL)"; stmt.executeUpdate(sql); stmt.close(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Table created successfully"); } }
上述程序编译和执行时,它会创建test.db的文件和最终列出COMPANY表将如下:
-rw-r--r--. 1 root root 3201128 Jan 22 19:04 sqlite-jdbc-3.7.2.jar -rw-r--r--. 1 root root 1506 May 8 05:43 SQLiteJDBC.class -rw-r--r--. 1 root root 832 May 8 05:42 SQLiteJDBC.java -rw-r--r--. 1 root root 3072 May 8 05:43 test.db
INSERT 操作
下面的Java程序,显示我们如何能够创造我们的COMPANY在上面的例子中创建表中的记录:
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); c.setAutoCommit(false); System.out.println("Opened database successfully"); stmt = c.createStatement(); String sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (1, 'Paul', 32, 'California', 20000.00 );"; stmt.executeUpdate(sql); sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (2, 'Allen', 25, 'Texas', 15000.00 );"; stmt.executeUpdate(sql); sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );"; stmt.executeUpdate(sql); sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );"; stmt.executeUpdate(sql); stmt.close(); c.commit(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Records created successfully"); } }
上述程序编译和执行时,它会创建COMPANY表中的记录,并会显示以下两行:
Opened database successfully Records created successfully
SELECT 操作
下面的Java程序,表明我们如何能够获取并显示COMPANY表 在上面的例子中创建表的记录:
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); c.setAutoCommit(false); System.out.println("Opened database successfully"); stmt = c.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT * FROM COMPANY;" ); while ( rs.next() ) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); String address = rs.getString("address"); float salary = rs.getFloat("salary"); System.out.println( "ID = " + id ); System.out.println( "NAME = " + name ); System.out.println( "AGE = " + age ); System.out.println( "ADDRESS = " + address ); System.out.println( "SALARY = " + salary ); System.out.println(); } rs.close(); stmt.close(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Operation done successfully"); } }
上述程序编译和执行时,它会产生以下结果:
Opened database successfully ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 20000.0 ID = 2 NAME = Allen AGE = 25 ADDRESS = Texas SALARY = 15000.0 ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
UPDATE 操作
下面的Java代码显示了如何我们可以使用UPDATE语句来更新任何记录,然后获取并显示更新的记录,从COMPANY 表:
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); c.setAutoCommit(false); System.out.println("Opened database successfully"); stmt = c.createStatement(); String sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1;"; stmt.executeUpdate(sql); c.commit(); ResultSet rs = stmt.executeQuery( "SELECT * FROM COMPANY;" ); while ( rs.next() ) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); String address = rs.getString("address"); float salary = rs.getFloat("salary"); System.out.println( "ID = " + id ); System.out.println( "NAME = " + name ); System.out.println( "AGE = " + age ); System.out.println( "ADDRESS = " + address ); System.out.println( "SALARY = " + salary ); System.out.println(); } rs.close(); stmt.close(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Operation done successfully"); } }
上述程序编译和执行时,它会产生以下结果:
Opened database successfully ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 25000.0 ID = 2 NAME = Allen AGE = 25 ADDRESS = Texas SALARY = 15000.0 ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
DELETE 操作
下面的Java代码,表明我们如何能够使用DELETE语句删除任何记录,然后获取并显示COMPANY表剩余的记录:
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); c.setAutoCommit(false); System.out.println("Opened database successfully"); stmt = c.createStatement(); String sql = "DELETE from COMPANY where ID=2;"; stmt.executeUpdate(sql); c.commit(); ResultSet rs = stmt.executeQuery( "SELECT * FROM COMPANY;" ); while ( rs.next() ) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); String address = rs.getString("address"); float salary = rs.getFloat("salary"); System.out.println( "ID = " + id ); System.out.println( "NAME = " + name ); System.out.println( "AGE = " + age ); System.out.println( "ADDRESS = " + address ); System.out.println( "SALARY = " + salary ); System.out.println(); } rs.close(); stmt.close(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Operation done successfully"); } }
上述程序编译和执行时,它会产生以下结果:
Opened database successfully ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 25000.0 ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
简单测试类
package foo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /** * @author Tim */ public class JavaSqlite { public static void main(String[] args) { // TODO Auto-generated method stub try { // 0 连接SQLite的JDBC String sql="jdbc:sqlite://e:/tim.db"; Class.forName("org.sqlite.JDBC"); // 1 建立一个数据库名zieckey.db的连接,如果不存在就在当前目录下创建之 Connection conn = DriverManager.getConnection(sql); Statement stat = conn.createStatement(); // 2 创建一个表tbl1,录入数据 stat.executeUpdate("drop table if exists tbl1;"); stat.executeUpdate("create table if not exists tbl1(name varchar(20), salary int);");// 创建一个表,两列 stat.executeUpdate("insert into tbl1 values('ZhangSan',8000);"); // 插入数据 stat.executeUpdate("insert into tbl1 values('LiSi',7800);"); stat.executeUpdate("insert into tbl1 values('WangWu',5800);"); stat.executeUpdate("insert into tbl1 values('ZhaoLiu',9100);"); ResultSet rs = stat.executeQuery("select * from tbl1;"); // 查询数据 System.out.println("创建表结构录入数据操作演示:"); while (rs.next()) { // 将查询到的数据打印出来 System.out.print("name = " + rs.getString("name") + ", "); // 列属性一 System.out.println("salary = " + rs.getString("salary")); // 列属性二 } rs.close(); // 3 修改表结构,添加字段 address varchar(20) default 'changsha'; stat.executeUpdate("alter table tbl1 add column address varchar(20) not null default 'changsha'; ");// 创建一个表,两列 stat.executeUpdate("insert into tbl1 values('HongQi',9000,'tianjing');"); // 插入数据 stat.executeUpdate("insert into tbl1(name,salary) values('HongQi',9000);"); // 插入数据 rs = stat.executeQuery("select * from tbl1;"); // 查询数据 System.out.println("表结构变更操作演示:"); while (rs.next()) { // 将查询到的数据打印出来 System.out.print("name = " + rs.getString("name") + ", "); // 列属性一 System.out.print("name = " + rs.getString("name") + ", "); // 列属性二 System.out.println("address = " + rs.getString("address")); // 列属性三 } rs.close(); conn.close(); // 结束数据库的连接 } catch (Exception e) { e.printStackTrace(); } } } 更多参考:Java: SQLite 数据库基本操作 之 去除大小写敏感,防注入,execute,executeQuery和executeUpdate的区别