处理数据库:良好的软件工程概念



当我创建JDBC应用程序时,我通常会将"sql语句"硬编码到java程序中。例如

ResultSet rs = st.execute("select * from Users")

但是,我听说这种方法不是一个好的软件工程概念。有人说,所有这些sql语句都应该作为"存储过程"留在数据库中,JDBC应该访问它们。从这两种方法中,哪一种可以被归类为一个好的软件工程概念?请帮忙!

我预测,你不会在这方面找到共识。

存储的proc有助于封装复杂的数据库逻辑和查询,同时避免将数据从数据库中转移出来进行排序/过滤/查询等。

不利的一面是,您经常会发现业务逻辑悄悄地进入存储过程,而它很可能会保留在应用程序本身中。

因此,对于这个逻辑应该驻留在哪里以及如何使用存储的proc,开发人员/dba等之间经常会有拉锯战。我建议你要务实。本地化您的SQL查询,这样当您更改SQL(表名等)时,就不必在整个代码库中更改内容。在执行代码复杂但对数据库来说微不足道的事情时,请使用存储的proc来提高性能。

使用硬编码字符串并在Statement中传递它们肯定不是一种好的软件工程实践。

您应该始终使用PreparedStatement

示例:

String selectSQL = "SELECT USER_ID, USERNAME FROM DBUSER WHERE USER_ID = ?";
PreparedStatement preparedStatement = dbConnection.prepareStatement(selectSQL);
preparedStatement.setInt(1, 1001);
ResultSet rs = preparedStatement.executeQuery(selectSQL ); 

存储过程也是一种良好的做法。大多数情况下,存储过程更多地用作性能透视图,因为除了第一次运行之外,查询都是预编译的。

使用Hibernatehttp://www.hibernate.org/(或另一个ORM),这样您就不需要维护那么多SQL语句。Hibernate在后台为您生成大部分SQL,这样您就不必担心维护SQL语句了。

其他ORM也可用,如TopLink和OpenJPA

在返回SYS_REFCURSOR的数据库中使用函数或存储过程,并使用CallableStatement 从java中调用它们,这将是一种很好的做法

如果您使用的是Oracle数据库,您可以尝试以下

数据库功能

CREATE OR REPLACE FUNCTION my_func (p_deptno IN number,p_emp_no IN varchar2)
   RETURN SYS_REFCURSOR
AS
   p_cursor   SYS_REFCURSOR;
BEGIN
   OPEN p_cursor FOR
      select *
        from emp
        where deptno = p_deptno and emp_number=p_emp_no;
   RETURN p_cursor;
END;
/

Java

        callablestatement = 
                connection.prepareCall("begin ? :=my_func(?,?); end;");
callablestatement.registerOutParameter(1, OracleTypes.CURSOR);
callablestatement.setString(2, param);
callablestatement.setString(3, param);
            callablestatement.execute();
            resultSet = ((OracleCallableStatement)callablestatement).getCursor(1);

使用这种方法可以避免在java中对sql语句进行硬编码。

我更喜欢将所有SQL查询存储为常量:

public static final String sqlEmpInsert = "SELECT EMP_NAME FROM EMPLOYEES";

在一个单独的java类中。我为每个模块都有单独的"常量"类文件,对于某些模块,我将SQL查询存储在单独的属性文件中,以便将其与java类文件隔离。

如果对SQL语句进行硬编码,那么每次更改数据库中的某些内容时,可能都必须在源代码中对其进行更改。

通过使用存储过程,您只需要更改这些存储过程,并且无需更改java程序的源代码。

因此,我建议使用存储过程。

最新更新