【Java】JavaWeb项目中使用SQLite免安装单文件数据库

Jsp项目中使用SQLite免安装单文件数据库

零、需求

有的同学电脑上安装MySQL或者其他数据库时出现问题,无法安装相关数据库供JavaWeb项目使用,可以使用SQLite数据库解决相关问题。

壹、SQLite介绍

SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。简单来讲就是不用安装,使用方便,可以随软件打包带走。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。

贰、使用方式

1. 程序包下载

新老版本都可以用,新版本(目前3.42.0.0)占用存储空间12.4M,老版本占用的存储空间更小(2M左右),选择合适的版本即可。新版本支持更多的函数,已知BUG更少,但是对于基本操作都差不多的。

我使用的是3.42.0.0版本

链接:
蓝奏云:https://minuhy.lanzout.com/b0c5yo69g 密码:dr3r
Maven官网:https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc
镜像开源地址:https://gitcode.net/mirrors/xerial/sqlite-jdbc

2. 导入程序包

下载完成后得到一个jar文件,将其拖入WebContentWEB-INFlib目录即可。

3. 数据库封装代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * SQLite數據庫封裝
 * 
 * @author y17mm
 * @time 2023-6-14 23:09:38
 * @version 1.0
 */
public class DBUtil {
	// 数据库文件存放位置
	private static String dbFilePath = "D:\sql.db";

	// 单例模式
	private static DBUtil db = null;

	private DBUtil() {
	}

	public static DBUtil getDB() {
		if (db == null) {
			synchronized (new Object()) {
				if (db == null) {
					db = new DBUtil();
				}
			}
		}
		return db;
	}

	Connection conn = null; // 連接對象
	Statement stat = null; // 執行對象
	ResultSet resu = null; // 結果集

	static {
		// 1. 加载驱动
		try {
			Class.forName("org.sqlite.JDBC");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 拿到數據庫連接
	 * 
	 * @throws SQLException SQL錯誤異常
	 * @time 2023-6-14 23:08:09
	 */
	public void getConnection() throws SQLException {
		// 2. 拿到连接
		conn = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath);
	}

	/**
	 * 拿到Statement對象
	 * 
	 * @throws SQLException SQL錯誤異常
	 * @time 2023-6-14 23:07:51
	 */
	public void getStatement() throws SQLException {
		// 3. 拿到Statement对象
		if (conn == null || conn.isClosed()) {
			getConnection();
		}

		stat = conn.createStatement();
	}

	/**
	 * 執行SQL查詢語句
	 * 
	 * @param sql SQL查詢語句
	 * @return 查詢結果對象
	 * @throws SQLException SQL錯誤異常
	 * @time 2023-6-14 23:07:23
	 */
	public ResultSet executeQuery(String sql) throws SQLException {
		// 4. 执行SQL语句拿到结果
		if (stat == null || stat.isClosed()) {
			getStatement();
		}

		System.out.println("执行的SQL语句:" + sql);

		resu = stat.executeQuery(sql);
		return resu;
	}

	/**
	 * 執行更改數據庫的語句(插入、更新、刪除、修改表等)
	 * 
	 * @param sql SQL語句
	 * @return 影響的行數
	 * @throws SQLException SQL錯誤異常
	 * @time 2023-6-14 23:06:24
	 */
	public int executeUpdate(String sql) throws SQLException {
		// 4. 执行SQL语句拿到结果
		if (stat == null || stat.isClosed()) {
			getStatement();
		}

		System.out.println("执行的SQL语句:" + sql);

		return stat.executeUpdate(sql);
	}

	/**
	 * 關閉連接
	 * 
	 * @time 2023-6-14 23:06:00
	 */
	public void close() {
		// 6.关掉连接
		try {
			if (resu != null && !resu.isClosed()) {
				resu.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		try {
			if (stat != null && !stat.isClosed()) {
				stat.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		try {
			if (conn != null && !conn.isClosed()) {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

4. 在Servlet中使用SQLite

以一个简单的登录业务为例:

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


@WebServlet("/login")
public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html; charset=UTF-8");
		HttpSession session = request.getSession();
		PrintWriter out = response.getWriter();
		
		// 1. 拿到数据
		String phone = request.getParameter("phone");
		String password = request.getParameter("password");

		// 2. 校验数据
		if (phone == null || password == null) {
			out.print("账号和密码不能为空");
			return;
		}

		// 3. 查询数据库,给出结果
		DBUtil db = DBUtil.getDB();
		try {
			// 拼接SQL語句
			String sql = "SELECT * FROM `main`.`user` WHERE `phone`='" + phone + "' and `password`='" + password + "'";
			ResultSet resu = db.executeQuery(sql); // 查詢
			if (resu.next()) {
				// 拿到結果
				String id = resu.getString("id");
				String nick = resu.getString("nick");
				String role = resu.getString("role");
				
				session.setAttribute("id", id);
				session.setAttribute("nick", nick);
				session.setAttribute("role", role);
				session.setAttribute("phone", phone);
				
				out.print("登录成功");
				return;
			} else {
				out.print("账号或密码错误");
				return;
			}
		} catch (SQLException e) {
			e.printStackTrace();
			out.print("登录失败,数据库错误");
			return;
		} finally {
			db.close();
		}
	}
}

使用过程与使用MySQL一致。

5. 图形化管理工具

可以使用Navicat管理SQLite数据库文件,连接时选择SQLite,然后选择打开现有文件,选择D:sql.db(我是D盘下的sql.db文件,根据你自己在上面数据库封装代码中设置的路径选择),确定后双击打开就能使用数据库。

6. 打包带走

因为SQLite是单文件的,所以你在把代码给别人时,应该把对应的SQLite的.db文件也一并打包发过去,同时告诉对方要把这个文件放在哪里才能正常运行。当然这一部分也可以让程序自动完成,检测文件是否存在,不存在则执行建表语句。

叁、参考资料

  1. https://www.sqlite.org/index.html
  2. https://gitcode.net/mirrors/xerial/sqlite-jdbc