java - 将 Java 类连接到 Derby 数据库可提高池连接的性能

标签 java sql jdbc database-connection derby

我有一个名为 ConnectionDerby 的类,在该类中我设置了连接到嵌入式数据库(Derby)的参数,我想减少太多的连接冗余,实际的方法和连接有效,但我想增加性能,所以该类的代码是这样的:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.swing.JOptionPane;

public class ConnectionDerby {

    private Connection conn = null;
    private Statement sttm = null;

    public Connection CrearBD(String query) {
        try {
        //Obtenemos el Driver de Derby
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        conn = DriverManager.getConnection("jdbc:derby:.\\BD\\inventario.db;create=true");
        if (conn != null) {
            //JOptionPane.showMessageDialog(null, "Base de Datos Lista");
            try {
                PreparedStatement pstm = conn.prepareStatement(query);
                pstm.execute();
                pstm.close();
                //JOptionPane.showMessageDialog(null, "Base de Datos Creada Correctamente");
                System.out.println("SENTENCIA SQL EFECTUADA CORRECTAMENTE");
            } catch (SQLException ex) {
                //JOptionPane.showMessageDialog(null, ex.getLocalizedMessage());
                System.out.println(ex.getMessage());
                JOptionPane.showMessageDialog(null, "NO SE PUDO EFECTUAR LA SENTENCIA SQL", "Error", JOptionPane.ERROR_MESSAGE);
                //JOptionPane.showMessageDialog(null, "NO SE PUDO EFECTUAR LA SENTENCIA SQL");
            }
        }

        } catch (SQLException e) {
        System.out.println(e.getMessage());
        JOptionPane.showMessageDialog(null, "NO SE PUDO EFECTUAR LA SENTENCIA SQL", "Error", JOptionPane.ERROR_MESSAGE);
        //JOptionPane.showMessageDialog(null, "TRONO LA APLICACION EN EJECUTAR LAS SENTENCIAS SQL parte 2");
    } catch (ClassNotFoundException e) {
        System.out.println(e.getMessage());
        JOptionPane.showMessageDialog(null, "NO SE PUDO EFECTUAR LA SENTENCIA SQL", "Error", JOptionPane.ERROR_MESSAGE);
        //JOptionPane.showMessageDialog(null, "TRONO LA APLICACION EN EJECUTAR LAS SENTENCIAS SQL parte 3");
    }
        return conn;
    }

    public Connection AccederBD() {
        try {
            //Obtenemos el Driver de Derby
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
            //Obtenemos la Conexión
            conn = DriverManager.getConnection("jdbc:derby:.\\BD\\inventario.db");
            if (conn != null) {
                System.out.println("Base de Datos Ya Leida Correctamente");
                //JOptionPane.showMessageDialog(null, "Base de Datos Ya Leida Correctamente");
            }
        } catch (SQLException e) {
            System.out.println(e.getMessage());
            System.out.println("NO SE ENCONTRO LA BASE DE DATOS");
            System.out.println("CREANDO BASE DE DATOS EN DERBY DATABASE");
            String createTableProyecto = "CREATE TABLE proyecto\n"
                + "(\n"
                + "idproyecto INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),\n"
                + "nombre VARCHAR(50) NOT NULL,\n"
                + "descripcion VARCHAR(1000),\n"
                + "CONSTRAINT proyecto_pk PRIMARY KEY (idproyecto)\n"
                + ")";
            String createTablePrimera = "CREATE TABLE primera\n"
                + "(\n"
                + "idprimera INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),\n"
                + "nombre VARCHAR(75) NOT NULL,\n"
                + "descripcion VARCHAR(1000),\n"
                + "CONSTRAINT primera_pk PRIMARY KEY (idprimera)\n"
                + ") ";
            String createTableSegunda = "CREATE TABLE segunda\n"
                + "(\n"
                + "idsegunda INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),\n"
                + "nombre VARCHAR(75) NOT NULL,\n"
                + "descripcion VARCHAR(1000),\n"
                + "CONSTRAINT segunda_pk PRIMARY KEY (idsegunda)\n"
                + ")";
            String createTableEncabezado = "CREATE TABLE encabezado\n"
                + "(\n"
                + "idencabezado INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),\n"
                + "idproyecto INTEGER NOT NULL,\n"
                + "idprimera INTEGER NOT NULL,\n"
                + "idsegunda INTEGER NOT NULL,\n"
                + "fecha DATE NOT NULL,\n"
                + "CONSTRAINT encabezado_pk PRIMARY KEY (idencabezado)\n"
                + ")";
            String createRelationCotizacionIdTopCoat = "ALTER TABLE ENCABEZADO ADD FOREIGN KEY (IDSEGUNDA) REFERENCES SEGUNDA(IDSEGUNDA)";
            String createRelationCotizacionIdPrimer = "ALTER TABLE ENCABEZADO ADD FOREIGN KEY (IDPRIMERA) REFERENCES PRIMERA(IDPRIMERA)";
            String createRelationCotizacionIdProyecto = "ALTER TABLE ENCABEZADO ADD FOREIGN KEY (IDPROYECTO) REFERENCES PROYECTO(IDPROYECTO)";
            CrearBD(createTableProyecto);
            CrearBD(createTablePrimera);
            CrearBD(createTableSegunda);
            CrearBD(createTableEncabezado);
            CrearBD(createRelationCotizacionIdTopCoat);
            CrearBD(createRelationCotizacionIdPrimer);
            CrearBD(createRelationCotizacionIdProyecto);
            //*************PRUEBAS*****************
        } catch (ClassNotFoundException e) {
            System.out.println(e.getMessage());
            System.out.println("ERROR DE TIPO ClassNotFoundException");
            //JOptionPane.showMessageDialog(null, "TRONO LA APLICACION EN ACCEDER A LA BASE DE DATOS parte 2");
        }
        return conn;
    }

    public void UID(String sqlcad) {
        try {
            //Obtenemos el Driver de Derby
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
            conn = DriverManager.getConnection("jdbc:derby:.\\BD\\inventario.db");
            sttm = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
            sttm.executeUpdate(sqlcad);
            System.out.println("Conexión Exitosa a la Base de Datos");
            //JOptionPane.showMessageDialog(null, "Conexión exitosa");
            sttm.close();
            conn.close();
            if (conn != null) {
            System.out.println("Consulta Realizada Correctamente");
            //JOptionPane.showMessageDialog(null, "Base de Datos Ya Leida Correctamente");
            }
        } catch (SQLException e) {
            System.out.println("Error= " + e.getMessage());
        } catch (ClassNotFoundException e) {
            System.out.println("Error= " + e.getMessage());
        }
    }

    public ResultSet getvalores(String sqlcad) {
        ResultSet rs = null;
        try {
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        conn = DriverManager.getConnection("jdbc:derby:.\\BD\\inventario.db");
        sttm = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
        //String sqlcad = "Select nombre, descripcion from primera";
        rs = sttm.executeQuery(sqlcad);
        return rs;
        } catch (Exception e) {
            System.out.println("Error= " + e.getMessage());
            return rs;
        }
    }
}

我使用另一个类来设置查询的查询字符串,如下所示:

import java.sql.ResultSet;

public class Primer {

    ConnectionDerby c = new ConnectionDerby();

    public void insertMaestroPrimera(String nombre, String descripcion) {
        c.UID("INSERT INTO primera(nombre, descripcion) values('" + nombre + "','" + descripcion + "')");
    }

    public void updateMaestroPrimera(int id, String nombre, String descripcion) {
        c.UID("UPDATE primera set nombre='" + nombre + "',descripcion='" + descripcion + "' where idprimera=" + id);
    }

    public void deleteMaestroPrimer(int id) {
        c.UID("DELETE FROM primera where idprimera=" + id);
    }

    public ResultSet llenarTable() {
        ResultSet rs = null;
        String sql = "SELECT nombre, descripcion from primera ORDER BY nombre";
        rs = c.getvalores(sql);
        return rs;
    }

    public ResultSet obtenerDatos(String value) {
        ResultSet rs = null;
        String sql = "SELECT idprimera, nombre, descripcion from primera WHERE nombre = '" + value + "'";
        rs = c.getvalores(sql);
        return rs;
    }
}

所以我想要一些建议,因为当我在表 encabezado 中进行更新时,我收到以下错误:“Error= Statement.executeUpdate() 无法使用返回 ResultSet 的语句调用。”和“错误=无法在请求的时间内获得锁定”。我认为这是因为池连接太多,所以请任何人都可以帮助我提高性能,或者我不知道sql可能是错误的,但是其他表(primera、segunda、proyecto)中的CRUD效果很好!顺便感谢您抽出时间!

最佳答案

您当前的设计存在两个大问题:

  1. 连接变量必须每个方法本地声明。您将 Connection 声明为一个字段,因此如果两个线程访问同一个 ConnectionDerby 对象实例,同时执行不同的操作,则会陷入竞争状态,从而有奇怪的问题,如在此错误消息中发布的: Error= Statement.executeUpdate() 无法使用返回 ResultSet 的语句调用,这意味着线程 A 尝试执行更新,而线程 B 尝试执行在同一个实例上同时执行读取操作,并且竞争条件混合了 ConnectionStatement 实例。

  2. 您正在手动打开连接。这是一个坏主意,因为打开连接的性能成本很高。您应该使用数据库连接池。

话虽如此,您可以通过以下方式提高性能并解决项目中的问题:

  • 使用数据库连接池。有几个选项,我建议使用 BoneCP .
  • ConnectionDerby 类中删除 ConnectionStatement 字段,而是添加新的 ConnectionStatement 每个方法内的变量。请记住在使用资源后始终关闭它们。

更多信息:

您可能没有使用 JBoss,但答案中的概念也适用于这种情况。

关于java - 将 Java 类连接到 Derby 数据库可提高池连接的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22227547/

相关文章:

java - 我的多线程程序出了什么问题?

java - JDBC 可调用语句中的 'call' 是什么意思?

SQL group by 和 count 固定列值

java - 我需要运行查询 "USE database",每次我调用一个新函数

java - Jackson2ObjectMapperBuilder 不序列化对象

java - 如何访问 Java 中每个循环的下一个元素?

java - 使用 Java 从数据库中读取 UDT 的最佳方法是什么?

Java MYSQL,搜索时忽略空白字符串

sql - 如何查找仅包含数字数据的非数字列?

mysql - 如何对不熟悉的行进行分组?