繁体   English   中英

Java JDBC-如何执行语句严格只读

[英]Java jdbc - how to execute a statement strictly read only

我的服务器应用程序几乎在所有情况下都使用准备好的语句,以防止sql注入。 但是,有可能需要提供特殊的用户来执行原始的SELECT查询。

如何或多或少安全地确保查询不会修改数据库? 是否可以执行只读查询,或者是否有其他“安全”方式来确保没有人尝试任何SQL注入? (使用sqlite3,所以我不能使用任何特权)

非常感谢!

JDBC通过调用Connection.setReadOnly(true)支持只读连接。 但是,javadoc说:

将此连接置于只读模式,以提示驱动程序启用数据库优化

一些 JDBC驱动程序将强制执行只读请求,其他一些 JDBC驱动程序将仅将其用于优化或忽略它。 我不知道sqlite3如何实现它。 您必须进行测试。

否则,您可以对SQL语句进行“简单”解析,以确保它是单个有效的SELECT语句。

我不知道指定只读的常规JBDC配置。 但是Sqlite确实具有特殊的数据库打开模式,可以在与sqlite数据库的连接中利用它。 例如。

Properties config = new Properties();
config.setProperty("open_mode", "1");  //1 == readonly
Connection conn = DriverManager.getConnection("jdbc:sqlite:sample.db", config);

信用: https : //stackoverflow.com/a/18092761/62344

FWIW 在此处可以看到所有受支持的打开模式。

如果使用某种工厂类来创建或返回数据库连接,则可以将连接分别设置为只读:

public Connection getReadOnlyConnection() {
    // Alternatively this could come from a connection pool:
    final Connection conn = DriverManager.getConnection("jdbc:sqlite:sample.db");
    conn.setReadOnly(true);
    return conn;
}

如果使用连接池,那么您可能还希望提供一种获取可写连接的方法:

public Connection getWriteableConnection() {
     final Connection conn = getPooledConnection(); // I'm assuming this method exists!
     conn.setReadOnly(false);
     return conn;
}

您也可以只提供一个getConnection(boolean readOnly)方法,只需将参数传递给setReadOnly(boolean)调用即可。 我个人更喜欢使用单独的方法,因为这样可以使您的意图更加清晰。

或者,某些数据库(例如Oracle)提供可以启用的只读模式。 SQLite不提供一个,但您可以通过简单地将实际数据库文件(包括目录)设置为仅在文件系统本身上读取来模拟它。

这样做的另一种方式如下( 对于以下代码,信用将变为死锁 ):

public Connection getReadOnlyConnection() {
    SQLiteConfig config = new SQLiteConfig();
    config.setReadOnly(true);
    Connection conn = DriverManager.getConnection("jdbc:sqlite:sample.db",
            config.toProperties());
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM