ZetCode 数据库教程(十七)

打印 上一主题 下一主题

主题 911|帖子 911|积分 2733

原文:ZetCode
  协议:CC BY-NC-SA 4.0
  Derby 安全

   原文: http://zetcode.com/db/apachederbytutorial/sec/
  在下一章中,我们将提到 Derby 的安全性选项。
我们将在本章中简要提及两个基本安全概念。 用户认证和用户授权。 用户认证正在验证用户凭据,然后再授予对 Derby 系统的访问权限。 用户授权是授予读取和/或写入 Derby 数据库权限的手段。
此外,Derby 答应对磁盘上存储的数据库文件进行加密。 Derby 网络流量可以利用 SSL/TLS 加密协议进行加密。
Derby 默认

默认情况下,Derby 不必要用户认证。 用户名成为程序中的默认架构,并且用户暗码将被忽略。 要启用认证,我们必须修改 Derby 属性。 用户授权已关闭。 别的,Derby 没有数据库超等用户。
数据库所有者

数据库所有者是创建数据库的用户。 假如创建数据库时没有提供用户,则数据库所有者将设置为默认授权标识符 APP。 当我们启用 SQL 授权时,控制数据库所有者很紧张。
数据库加密

Derby 为我们提供了一种加密磁盘上数据的方法。 引导数据库的用户必须提供启动暗码。 创建数据库时可以对其进行加密。 也可以加密现有的未加密数据库。 在加密数据库时,还必须指定启动暗码,该暗码是用于天生加密键的字母数字字符串。
  1. ij> CONNECT 'jdbc:derby:testdb;create=true;dataEncryption=true;
  2. bootPassword=3344kkllqq**';
复制代码
创建数据库时,我们可以对其进行加密。 我们将dataEncryption属性设置为true,并提供启动暗码。 现在,每次启动数据库时,我们都必须提供启动暗码。
  1. ij> CONNECT 'jdbc:derby:testdb';
  2. ERROR XJ040: Failed to start database 'testdb' with class loader
  3. sun.misc.Launcher$AppClassLoader@360be0, see the next exception for details.
  4. ERROR XBM06: Startup failed. An encrypted database cannot be accessed without
  5. the correct boot password.
复制代码
在嵌入式模式下,当我们毗连到数据库时,我们还将引导它。 当我们实验在没有启动暗码的情况下毗连到加密数据库时,Derby 将显示以上错误消息。
  1. ij> CONNECT 'jdbc:derby:testdb;bootPassword=3344kkllqq**';
  2. ij> SHOW CONNECTIONS;
  3. CONNECTION0* -  jdbc:derby:testdb
  4. * = current connection
复制代码
利用正确的启动暗码,我们已成功毗连到testdb数据库。
认证方式

认证限定了对正确用户的访问。 默认情况下,Derby 中的认证处于关闭状态。
Derby 通过三种方式提供认证。


  • LDAP 外部认证
  • 自定义 Java 类
  • 内置系统
Derby 官方文档警告说 Derby 的内置认证机制仅实用于开发和测试目的。 强烈建议生产系统依赖 LDAP 或用户定义的类进行认证。
嵌入

认证可以设置为两个级别。 在系统级别或数据库级别。
  1. ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.user.user12', '34klq*');
  2. 0 rows inserted/updated/deleted
  3. ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.connection.requireAuthentication',
  4. 'true');
  5. 0 rows inserted/updated/deleted
复制代码
以上两个语句可在数据库级别为当前毗连的数据库启用用户认证。 我们利用暗码创建了一个用户,并启用了derby.connection.requireAuthentication属性。
  1. ij> CONNECT 'jdbc:derby:testdb';
  2. ERROR 08004: Connection authentication failure occurred.  Reason: Invalid authentication..
  3. ij> CONNECT 'jdbc:derby:testdb;user=user12;password=34klq*';
  4. ij> SHOW CONNECTIONS;
  5. CONNECTION0* -  jdbc:derby:testdb
  6. * = current connection
复制代码
启用用户认证后,当我们要毗连到testdb数据库时,我们必须提供用户凭据。
客户端服务器

在下一个示例中,我们将在客户端/服务器模式下利用 Derby。 我们有一个加密的testdb数据库。
  1. $ startNetworkServer &
  2. amp;
复制代码
Derby 服务器已启动。
  1. ij> CONNECT 'jdbc:derby://localhost:1527/dbs/testdb;bootPassword=3344kkllqq**';
复制代码
首次毗连testdb数据库时,必须提供启动暗码。 这是因为以前我们已经加密了testdb数据库。
  1. ij> CONNECT 'jdbc:derby://localhost:1527/dbs/testdb';
  2. ij> SHOW CONNECTIONS;
  3. CONNECTION0* -  jdbc:derby://localhost:1527/dbs/testdb
  4. * = current connection
复制代码
一旦数据库已经启动,我们就不必要以客户端/服务器模式启动数据库。 与嵌入式模式不同,在嵌入式模式下,我们每次都毗连到数据库时,也会对其进行引导。
在下一步中,我们将在客户端/服务器模式下启用用户认证。 为此,我们必要编辑derby.properties文件。
  1. $ stopNetworkServer
复制代码
起首,假如 Derby 服务器正在运行,我们将其停止。 请注意,启用用户认证后,我们必要提供用户凭据才能停止服务器。 stopNetworkServer脚本带有-user和-password选项。
  1. $ cat dbs/derby.properties
  2. derby.connection.requireAuthentication=true
  3. derby.user.user12=34klq*
  4. derby.authentication.provider=BUILTIN
复制代码
在 Derby 系统目录中,我们修改derby.properties文件。 假如文件不存在,我们将创建它。 在属性文件中,我们启用身份​​验证并利用暗码创建用户。 我们还将认证供应器设置为 Derby BUILTIN。
  1. $ startNetworkServer &
  2. amp;
复制代码
我们启动 Derby 服务器。
  1. $ java  -Dderby.system.home=/home/janbodnar/programming/derby/dbs \
  2. -Dij.protocol=jdbc:derby: -jar $DERBY_HOME/lib/derbyrun.jar ij
  3. ij version 10.8
  4. ij>
复制代码
我们启动ij工具。
  1. ij> CONNECT 'jdbc:derby:testdb;bootPassword=3344kkllqq**';
  2. ERROR 08004: Connection authentication failure occurred.  Reason: Invalid authentication..
复制代码
我们实验毗连到testdb数据库。 由于 Derby 服务器已重新启动,因此我们提供了启动暗码。 但是,我们看到一条错误消息。 这是因为我们启用了用户认证。 我们还必须提供用户凭据。
  1. ij> CONNECT 'jdbc:derby:testdb;user=user12;password=34klq*;
  2. bootPassword=3344kkllqq**';
复制代码
利用此毗连字符串,我们已成功毗连到testdb数据库。
用户授权

通过 Derby 中的用户授权,可以授予和撤消访问系统,数据库,对象或 SQL 操作的权限。 我们可以在 Derby 中将用户授权属性设置为系统级属性或数据库级属性。
Derby 具有一些影响用户授权的属性。 derby.database.defaultConnectionMode属性控制默认访问模式。 假如未设置该属性,则该属性默认为fullAccess,即具有读写访问权限。 其他两个选项是noAccess和readOnlyAccess。 通过derby.database.fullAccessUsers和derby.database.readOnlyAccessUsers,我们可以控制哪些用户可以读写,哪些用户可以对数据库进行只读访问。 derby.database.sqlAuthorization属性启用 SQL 尺度授权。 当derby.database.sqlAuthorization属性设置为true时,对象所有者可以利用GRANT和REVOKE SQL语句来设置特定命据库对象或特定 SQL 操作的用户权限。
我们可以授予或撤销的特权是:DELETE,EXECUTE,INSERT,SELECT,REFERENCES,TRIGGER和UPDATE。
为derby.database.defaultConnectionMode属性指定的访问模式将覆盖数据库对象所有者授予的权限。
  1. $ cat dbs/derby.properties
  2. derby.connection.requireAuthentication=true
  3. derby.user.user12=34klq*
  4. derby.user.user13=33kl33
  5. derby.user.user14=14kl14
  6. derby.user.user15=35rr++
  7. derby.authentication.provider=BUILTIN
  8. derby.database.defaultConnectionMode=readOnlyAccess
  9. derby.database.fullAccessUsers=user12
复制代码
我们修改derby.properties文件。 我们添加了三个用户。 一个用户user12拥有对数据库的完全访问权限。 其他三个具有默认的只读访问权限。
  1. export DERBY_OPTS=-Dderby.system.home=/home/janbodnar/programming/derby/dbs
复制代码
请注意,为了使网络服务器知道带有derby.property的系统目录在哪里,我们将DERBY_OPTS变量设置为包罗 derby 系统目录。
  1. $ stopNetworkServer
  2. $ startNetworkServer &
  3. amp;
  4. $ java  -Dderby.system.home=/home/janbodnar/programming/derby/dbs \-Dij.protocol=jdbc:derby: -jar $DERBY_HOME/lib/derbyrun.jar ij
复制代码
我们重新启动网络服务器并启动ij工具。
  1. ij> CONNECT 'jdbc:derby://localhost/testdb;user=user13;
  2. password=33kl33;bootPassword=3344kkllqq**';
复制代码
我们利用user13用户毗连到testdb数据库。 由于我们是第一次毗连数据库,因此我们也将其引导。 因此,我们必要启动暗码,因为该数据库先前已加密。
  1. ij> SELECT * FROM USER12.CARS;
  2. ID         |NAME                          |PRICE      
  3. ------------------------------------------------------
  4. 1          |Audi                          |52642      
  5. 2          |Mercedes                      |57127      
  6. 3          |Skoda                         |9000      
  7. 4          |Volvo                         |29000      
  8. 5          |Bentley                       |350000     
  9. 6          |Citroen                       |21000      
  10. 7          |Hummer                        |41400      
  11. 8          |Volkswagen                    |21600      
  12. 8 rows selected
复制代码
user13有权查看位于USER12模式中的CARS表中的数据。
  1. ij> INSERT INTO USER12.CARS VALUES(9, 'Toyota', 27000);
  2. ERROR 25502: An SQL data change is not permitted for a read-only connection,
  3. user or database.
复制代码
但是,实验修改CARS表中的数据会导致错误。 未授予实行更改的权限。
  1. ij> DISCONNECT;
  2. ij> CONNECT 'jdbc:derby://localhost/testdb;user=user12;
  3. password=34klq*';
复制代码
我们关闭毗连,并毗连为user12。 该用户在属性文件中具有完全访问权限。 即使user12是数据库的所有者和CARS表的所有者,他也不能修改表,除非利用 Derby 属性具有完全访问权限。
  1. ij> INSERT INTO CARS VALUES(9, 'Toyota', 27000);
  2. 1 row inserted/updated/deleted
  3. ij> SELECT * FROM CARS WHERE ID = 9;
  4. ID         |NAME                          |PRICE      
  5. ------------------------------------------------------
  6. 9          |Toyota                        |27000      
  7. 1 row selected
复制代码
我们已经成功地在CARS表中添加了新行。
SQL 授权

数据库或表之类的对象的所有者可以进一步限定利用数据库对象的权限。 我们可以利用GRANT和REVOKE语句来授予或撤消权限。 数据库和表的所有者是创建它们的当前用户。 请注意,derby.database.defaultConnectionMode会覆盖GRANT语句赋予的权限。 因此,假如用户具有通过默认毗连方式指定的readOnlyAccess,则即使GRANT语句授予了该权限,该用户也无法修改数据库对象。
当derby.database.sqlAuthorization属性设置为true时,对象所有者可以利用GRANT和REVOKE SQL语句来设置特定命据库对象或特定 SQL 操作的用户权限。 请注意,在derby.properties文件中设置系统范围的属性仅对新数据库有效。 对于现有数据库,我们只能设置数据库范围的derby.database.sqlAuthorization属性。 在将derby.database.sqlAuthorization属性设置为true之后,我们无法将该属性设置回false。
  1. ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.database.sqlAuthorization',
  2. 'true');
复制代码
derby.database.sqlAuthorization属性已设置为 true。 该属性是静态的。 我们必须重新启动testdb数据库以使该属性正常工作。
  1. ij> CONNECT 'jdbc:derby://localhost/testdb;shutdown=true;
  2. user=user12;password=34klq*';
  3. ij> CONNECT 'jdbc:derby://localhost/testdb;user=user12;
  4. password=34klq*;bootPassword=3344kkllqq**';
复制代码
我们关闭了testdb数据库,然后重新启动它。
  1. ij(CONNECTION1)> GRANT SELECT ON CARS TO user15;
  2. 0 rows inserted/updated/deleted
复制代码
我们向表CARS的user15提供SELECT特权。
  1. ij(CONNECTION1)> UPDATE CARS SET PRICE=27001 WHERE ID=9;
  2. 1 row inserted/updated/deleted
  3. ij(CONNECTION1)> SELECT * FROM CARS;
  4. ID         |NAME                          |PRICE      
  5. ------------------------------------------------------
  6. 1          |Audi                          |52642      
  7. 2          |Mercedes                      |57127      
  8. 3          |Skoda                         |9000      
  9. 4          |Volvo                         |29000      
  10. 5          |Bentley                       |350000     
  11. 6          |Citroen                       |21000      
  12. 7          |Hummer                        |41400      
  13. 8          |Volkswagen                    |21600      
  14. 9          |Toyota                        |27001
复制代码
作为表所有者的user12具有完全特权。 上面的下令确认他在CARS表上具有UPDATE和SELECT特权。
  1. ij(CONNECTION1)> DISCONNECT;
  2. ij> CONNECT 'jdbc:derby://localhost/testdb;user=user14;
  3. password=14kl14';
  4. ij(CONNECTION1)> SELECT * FROM USER12.CARS;
  5. ERROR 42502: User 'USER14' does not have SELECT permission
  6. on column 'ID' of table 'USER12'.'CARS'.
复制代码
我们从数据库断开毗连,并以user14身份毗连。 实验实行SELECT语句会导致错误。 user14不具有对CARS表中SELECT数据的特权。
  1. ij(CONNECTION1)> DISCONNECT;
  2. ij> CONNECT 'jdbc:derby://localhost/testdb;user=user15;
  3. password=35rr++';
  4. ij> SELECT * FROM USER12.CARS;
  5. ID         |NAME                          |PRICE      
  6. ------------------------------------------------------
  7. 1          |Audi                          |52642      
  8. 2          |Mercedes                      |57127      
  9. 3          |Skoda                         |9000      
  10. 4          |Volvo                         |29000      
  11. 5          |Bentley                       |350000     
  12. 6          |Citroen                       |21000      
  13. 7          |Hummer                        |41400      
  14. 8          |Volkswagen                    |21600   
  15. 9          |Toyota                        |27000      
  16. 8 rows selected
复制代码
接下来,我们以user15毗连。 用户可以从CARS表中选择数据。
  1. ij(CONNECTION1)> SELECT * FROM USER12.AUTHORS;
  2. ERROR 42502: User 'USER15' does not have SELECT
  3. permission on column 'ID' of table 'USER12'.'AUTHORS'.
复制代码
但是他不能从AUTHORS表中选择数据。 表所有者user12没有授予从该表中选择数据的权限。
  1. ij(CONNECTION1)> UPDATE USER12.CARS SET PRICE=27000 WHERE ID=9;
  2. ERROR 25502: An SQL data change is not permitted for a read-only
  3. connection, user or database.
复制代码
user15在CARS表上也没有UPDATE特权。
在本章中,我们讨论了 Derby 中的安全性选项。
利用 Derby & Apache Tomcat

   原文: http://zetcode.com/db/apachederbytutorial/tomcat/
  在本章中,我们将展示如何将 Derby 与 Apache Tomcat Web 容器组合在一起。
Apache Tomcat 是 Java 编程语言的 Web 容器。 它用于服务 JSP 页面和 servlet。 可以轻松地将 Apache Tomcat 与 Derby 一起利用。 Derby 在其lib子目录中有一个derby.war文件。 该 Web 存档仅用于控制 Derby 数据库。 Tomcat 和 Derby 都是 Apache Software Foundation 的项目。
  1. $ pwd
  2. /home/janbodnar/bin/tomcat
  3. $ ls lib/derby*
  4. lib/derbyclient.jar  lib/derby.jar  lib/derbynet.jar
复制代码
起首,我们必须将derbyclient.jar,derby.jar和derbynet.jar文件复制到 Tomcat 安装目录的lib子目录中。
  1. $ ls webapps
  2. derby.war  docs  examples  host-manager  manager  ROOT
复制代码
然后,我们必须将 derby.war 文件复制到 Tomcat 安装目录的webapps子目录文件中。 Tomcat 启动时,将解压缩并部署文件。
  1. $ export JAVA_OPTS=-Dderby.system.home=/home/janbodnar/programming/derby/dbs
复制代码
当我们通过 Tomcat 启动 Derby 时,不考虑DERBY_OPTS变量。 在启动 Tomcat 和 Derby 服务器之前,必须先设置derby.system.home。 我们可以在JAVA_OPTS变量中设置 Derby 系统目录。
  1. $ bin/startup.sh
  2. Using CATALINA_BASE:   /home/janbodnar/bin/tomcat
  3. Using CATALINA_HOME:   /home/janbodnar/bin/tomcat
  4. Using CATALINA_TMPDIR: /home/janbodnar/bin/tomcat/temp
  5. Using JRE_HOME:        /home/janbodnar/bin/jdk1.6.0_30
  6. Using CLASSPATH:       /home/janbodnar/bin/tomcat/bin/bootstrap.jar:
  7. /home/janbodnar/bin/tomcat/bin/tomcat-juli.jar
复制代码
利用startup.sh脚本启动 Tomcat 服务器。

图:Tomcat 启动页面
导航到localhost:8080,这是 Tomcat 监听的默认 URL,我们会看到 Tomcat 接待页面。

图:Derby 启动
要启动 Derby 数据库,我们导航到localhost:8080/derby/derbynet。 这将启动 Derby。 我们有几个按钮可用于启动/停止服务器,启用/禁用日志记录或跟踪。
  1. <load-on-startup>0</load-on-startup>
复制代码
每次启动 Tomcat 服务器时,我们都必须导航至上述 URL。 要自动启动 Derby,我们可以在web.xml文件的<servlet>标志内添加以上行。 该文件位于webapps/derby/WEB-INF目录中。
创建测试数据库

对于那些从一开始就没有遵循教程的人,我们将再次创建testdb数据库。 我们将一个表添加到数据库中。 您可以跳过数据库和表(假如已经存在)的创建。
  1. $ cat cars.sql
  2. CREATE SCHEMA USER12;
  3. CREATE TABLE CARS(ID INT PRIMARY KEY, NAME VARCHAR(30), PRICE INT);
  4. INSERT INTO CARS VALUES(1, 'Audi', 52642);
  5. INSERT INTO CARS VALUES(2, 'Mercedes', 57127);
  6. INSERT INTO CARS VALUES(3, 'Skoda', 9000);
  7. INSERT INTO CARS VALUES(4, 'Volvo', 29000);
  8. INSERT INTO CARS VALUES(5, 'Bentley', 350000);
  9. INSERT INTO CARS VALUES(6, 'Citroen', 21000);
  10. INSERT INTO CARS VALUES(7, 'Hummer', 41400);
  11. INSERT INTO CARS VALUES(8, 'Volkswagen', 21600);
复制代码
我们将必要此 SQL 文件。
  1. $ cat dbs/derby.properties
  2. derby.stream.error.logSeverityLevel=0
  3. derby.database.fullAccessUsers=user12
  4. derby.database.defaultConnectionMode=readOnlyAccess
  5. derby.connection.requireAuthentication=true
  6. derby.user.user12=34klq*
  7. derby.user.user13=33kl33
  8. derby.user.user14=14kl14
  9. derby.user.user15=35rr++
  10. derby.authentication.provider=builtin
复制代码
在 Derby 系统目录中,我们有derby.properties文件。 在此文件中,我们设置一些选项。 我们将日志严重性级别设置为 0 以报告所有可能的问题。 这是在测试环境中完成的。 我们启用身份​​验证。 我们利用相应的暗码创建四个用户。 用户 12 中只有一个拥有完全访问权限。 其他人只有readOnlyAccess。
  1. $ java  -Dderby.system.home=/home/janbodnar/programming/derby/dbs \
  2. -Dij.protocol=jdbc:derby: -jar $DERBY_HOME/lib/derbyrun.jar ij
  3. ij version 10.8
  4. ij>
复制代码
我们启动ij下令行工具。 我们将利用它来创建数据库和表。 Derby 系统目录位于/home/janbodnar/programming/derby/dbs。
  1. ij> CONNECT 'jdbc:derby://localhost:1527/testdb;create=true;
  2. user=user12;password=34klq*';
复制代码
我们创建testdb数据库并毗连到它。 我们提供用户凭证。
  1. ij> run 'cars.sql';
复制代码
我们实行cars.sql脚本,该脚本创建CARS表并将其添补数据。
  1. ij> SELECT * FROM CARS;
  2. ID         |NAME                          |PRICE      
  3. ------------------------------------------------------
  4. 1          |Audi                          |52642      
  5. 2          |Mercedes                      |57127      
  6. 3          |Skoda                         |9000      
  7. 4          |Volvo                         |29000      
  8. 5          |Bentley                       |350000     
  9. 6          |Citroen                       |21000      
  10. 7          |Hummer                        |41400      
  11. 8          |Volkswagen                    |21600      
  12. 8 rows selected
复制代码
这是我们的CARS表。 接下来,我们将创建一个 Java servlet,它将在 Web 浏览器中显示这些值。
项目

我们将创建一个简单的 Web 应用,该应用将毗连到 Derby 数据库。 一个 Java Servlet 将毗连到 Derby,并从CARS表中检索所有数据。
  1. $ tree
  2. .
  3. ├── build.xml
  4. ├── context.xml
  5. ├── lib
  6. │   └── servlet-api.jar
  7. ├── src
  8. │   └── zetcode
  9. │       └── SelectAllCars.java
  10. └── web.xml
  11. 3 directories, 5 files
复制代码
在当前工作目录中,我们有一个 Ant build.xml文件,context.xml设置文件,web.xml部署描述符文件以及src和lib子目录。 build.xml文件是 Ant 构建文件,它描述了构建,部署或清理项目的使命。 web.xml定义了 Web 应用的结构。 在lib目录中,有servlet-api.jar文件,用于编译源文件。 (可以在 Tomcat 安装目录的lib子目录中找到它。)在src目录中,我们有 Java 源文件。
web.xml文件定义 Web 应用的结构。
  1. <?xml version="1.0" encoding="UTF8"?>
  2. <web-app xmlns="http://java.sun.com/xml/ns/javaee"
  3.   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  5.                       http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  6.   version="3.0"
  7.   metadata-complete="true">
  8.     <description>
  9.       Servlet which connects to Derby
  10.     </description>
  11.     <display-name>Derby, Tomcat</display-name>
  12.     <servlet>
  13.         <servlet-name>SelectAllCars</servlet-name>
  14.         <servlet-class>zetcode.SelectAllCars</servlet-class>
  15.     </servlet>
  16.     <servlet-mapping>
  17.         <servlet-name>SelectAllCars</servlet-name>
  18.         <url-pattern>/SelectAllCars</url-pattern>
  19.     </servlet-mapping>
  20. </web-app>
复制代码
这些是web.xml文件的内容。 在此文件中,我们注册SelectAllCars servlet。
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Context>
  3.     <Resource name="jdbc/testdb"
  4.               auth="Container"
  5.               type="javax.sql.DataSource"
  6.               username="user12"
  7.               password="34klq*"              
  8.               driverClassName="org.apache.derby.jdbc.ClientDriver"
  9.               url="jdbc:derby://localhost:1527/testdb"
  10.               maxActive="10"
  11.               maxIdle="4"/>
  12. </Context>
复制代码
在context.xml文件中,我们定义 JDBC 数据源。 可以为所有 Web 应用或单个应用定义context.xml文件。 后者是我们的情况。
我们将显示 Ant 构建文件,该文件将用于构建和部署我们的小型应用。
  1. <?xml version="1.0" ?>
  2. <project name="allcars" default="deploy">
  3.     <property name="src.dir" value="src"/>
  4.     <property name="build.dir" value="build"/>
  5.     <property name="dist.dir" value="dist"/>
  6.     <property name="deploy.dir" value="/home/janbodnar/bin/tomcat/webapps"/>
  7.     <echo>${ant.project.name}</echo>
  8.     <target name="init">
  9.         <mkdir dir="${build.dir}/classes" />
  10.         <mkdir dir="${dist.dir}"/>
  11.         <echo>Directories created.</echo>
  12.     </target>
  13.     <target name="compile" depends="init">
  14.         <javac srcdir="${src.dir}" destdir="${build.dir}/classes"
  15.                includeantruntime="false">
  16.             <classpath path="lib/servlet-api.jar"/>  
  17.         </javac>
  18.         <echo>Source files compiled.</echo>
  19.     </target>   
  20.     <target name="archive" depends="compile">
  21.         <war destfile="${dist.dir}/${ant.project.name}.war" webxml="web.xml">
  22.             <classes dir="${build.dir}/classes"/>
  23.             <metainf file="context.xml"/>
  24.         </war>
  25.         <echo>Archive created.</echo>
  26.     </target>   
  27.     <target name="deploy" depends="archive">
  28.         <copy file="${dist.dir}/${ant.project.name}.war" todir="${deploy.dir}"/>
  29.         <echo>Project deployed.</echo>
  30.     </target>   
  31.     <target name="clean">
  32.         <delete dir="${dist.dir}"/>
  33.         <delete dir="${build.dir}"/>
  34.         <echo>Project cleaned.</echo>
  35.     </target>
  36. </project>
复制代码
构建文件包罗五个使命。 初始化使命将创建须要的目录。 编译使命将编译源代码。 存档使命将创建一个网络存档。 deploy 使命会将归档文件部署到 Tomcat 服务器。 末了,干净使命将进行干净。
以下是SelectAllCars Servlet。
  1. package zetcode;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import java.sql.Connection;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.sql.Statement;
  8. import java.util.logging.Level;
  9. import java.util.logging.Logger;
  10. import javax.naming.Context;
  11. import javax.naming.InitialContext;
  12. import javax.naming.NamingException;
  13. import javax.servlet.ServletException;
  14. import javax.servlet.http.HttpServlet;
  15. import javax.servlet.http.HttpServletRequest;
  16. import javax.servlet.http.HttpServletResponse;
  17. import javax.sql.DataSource;
  18. public class SelectAllCars extends HttpServlet {
  19.     protected void processRequest(HttpServletRequest request,
  20.             HttpServletResponse response)
  21.             throws ServletException, IOException {
  22.         response.setContentType("text/html;charset=UTF-8");
  23.         PrintWriter out = null;
  24.         Connection con = null;
  25.         Statement st = null;
  26.         ResultSet rs = null;
  27.         try {
  28.             out = response.getWriter();
  29.             Context ctx = new InitialContext();
  30.             DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/testdb");
  31.             con = ds.getConnection();
  32.             st = con.createStatement();
  33.             out.println("<html>");
  34.             out.println("<head>");
  35.             out.println("<title>SimpleServlet</title>");
  36.             out.println("</head>");
  37.             out.println("<body>");            
  38.             rs = st.executeQuery("SELECT * FROM CARS");
  39.             while (rs.next()) {
  40.                 out.print(rs.getInt(1));
  41.                 out.print(" ");
  42.                 out.print(rs.getString(2));
  43.                 out.print(" ");
  44.                 out.print(rs.getString(3));
  45.                 out.print("<br>");
  46.             }
  47.             out.println("</body>");
  48.             out.println("</html>");
  49.         } catch (NamingException | SQLException ex) {
  50.             Logger lgr = Logger.getLogger(SelectAllCars.class.getName());
  51.             lgr.log(Level.SEVERE, ex.getMessage(), ex);
  52.         } finally {
  53.             try {
  54.                 if (rs != null) {
  55.                     rs.close();
  56.                 }
  57.                 if (con != null) {
  58.                     con.close();
  59.                 }
  60.                 if (out != null) {
  61.                     out.close();
  62.                 }
  63.             } catch (SQLException ex) {
  64.                 Logger lgr = Logger.getLogger(SelectAllCars.class.getName());
  65.                 lgr.log(Level.WARNING, ex.getMessage(), ex);
  66.             }
  67.         }
  68.     }
  69.     @Override
  70.     protected void doGet(HttpServletRequest request,
  71.             HttpServletResponse response)
  72.             throws ServletException, IOException {
  73.         processRequest(request, response);
  74.     }
  75.     @Override
  76.     protected void doPost(HttpServletRequest request,
  77.             HttpServletResponse response)
  78.             throws ServletException, IOException {
  79.         processRequest(request, response);
  80.     }
  81. }
复制代码
在上面的 servlet 中,我们毗连到 Derby testdb数据库并从CARS表中获取所有行。
  1. Context ctx = new InitialContext();
  2. DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/testdb");
复制代码
我们利用 JNDI 定名查找来获取数据源。 从数据源,我们创建毗连对象。
  1. rs = st.executeQuery("SELECT * FROM CARS");
  2. while (rs.next()) {
  3.     out.print(rs.getInt(1));
  4.     out.print(" ");
  5.     out.print(rs.getString(2));
  6.     out.print(" ");
  7.     out.print(rs.getString(3));
  8.     out.print("<br>");
  9. }
复制代码
我们利用 SQL 语句从CARS表中检索所有数据。 我们从结果集对象中打印数据。
  1. $ ant
  2. Buildfile: /home/janbodnar/programming/derby/servlet/build.xml
  3.      [echo] allcars
  4. init:
  5.     [mkdir] Created dir: /home/janbodnar/programming/derby/servlet/build/classes
  6.     [mkdir] Created dir: /home/janbodnar/programming/derby/servlet/dist
  7.      [echo] Directories created.
  8. compile:
  9.     [javac] Compiling 1 source file to /home/janbodnar/programming/derby/
  10. servlet/build/classes
  11.      [echo] Source files compiled.
  12. archive:
  13.       [war] Building war: /home/janbodnar/programming/derby/servlet/dist/allcars.war
  14.      [echo] Archive created.
  15. deploy:
  16.      [copy] Copying 1 file to /home/janbodnar/bin/tomcat/webapps
  17.      [echo] Project deployed.
  18. BUILD SUCCESSFUL
  19. Total time: 1 second
复制代码
我们启动 ant 来构建和部署项目。

图:SelectAllCars servlet 的输出
我们导航到localhost:8080/allcars/SelectAllCars URL 并吸取输出。
在本章中,我们利用了 Derby 和 Apache Tomcat。
NetBeans 和 Derby

   原文: http://zetcode.com/db/apachederbytutorial/netbeans/
  在本章中,我们将利用 NetBeans IDE 中的 Derby 数据库。 NetBeans 在其基本 Java SE 捆绑软件中对 Derby 数据库提供了内置支持。
到目前为止,我们已经与 Apache Derby 发行版合作。 在本章中,我们将利用 Java DB。 它是雷同的数据库,只是名称不同。 Java DB 是 Java 6 版本附带的 Java 发行版。

图:NetBeans 服务窗口
在“服务”窗口中,我们睁开“数据库”节点。 我们可以看到两个节点。 Java DB 节点和驱动节点。 在 Java DB 节点中,我们拥有所有数据库。 在驱动程序节点中,我们可以看到用于毗连到 RDBMS 的各种 JDBC 驱动程序。 这些数据库驱动程序随 NetBeans IDE 一起提供。 我们有实用于嵌入式和服务器模式的 Java DB 驱动程序。

图:Java DB 属性窗口
上图是“Java DB 属性”对话框窗口。 当我们右键单击 Java DB 节点并选择Properties选项时,将显示该窗口。 在此对话框中,我们可以设置两个紧张设置。 Java DB 安装目录和 Java DB 系统目录。
建立数据库

起首要做的是创建一个新的数据库。 我们将创建testdb数据库。

图:Java DB 上下文菜单
当我们右键单击 Java DB 节点时,将显示一个上下文菜单。 它具有四个选项:启动服务器,停止服务器,创建数据库和属性。 我们选择创建数据库项来创建一个新数据库。

图:“创建 Java DB 数据库”对话框
弹出对话框。 在此对话框窗口中,我们提供数据库名称,用户名和暗码。 注意数据库位置字符串。 这是 Java DB 系统目录,将在此中创建我们的数据库文件。 默认的 Java DB 系统目录是主目录中的.netbeans-derby目录。

图:创建新数据库
目前,我们已经创建了一个新数据库。 它通过 Java DB 节点下的新数据库图标直观地指示。
数据库毗连

创建数据库后,我们创建一个数据库毗连。


NetBeans 将这些图标用于毗连对象。 第一个图标用于断开毗连的数据库毗连对象,第二个图标用于已建立的数据库毗连对象。

上面的毗连是利用 Java DB 服务器驱动程序创建的 Java DB 毗连。 请注意,当我们创建testdb数据库时,将自动启动 Java DB 服务器并创建毗连。 可以通过右键单击 Java DB 驱动程序并选择“毗连利用”选项来创建新的数据库毗连。
我们将创建一个嵌入式 Java DB 数据库毗连。 创建毗连之前,假如 Java DB 服务器正在运行,则必要停止它。 Java DB 数据库不能由 Java DB 服务器引导,也不能同时由嵌入式驱动程序毗连。 注意,我们不必显式启动服务器。 该服务器可以在后台启动。 例如,通过毗连到 Java DB 服务器毗连对象或创建新数据库。

图:停止服务器
我们用鼠标右键单击 Java DB 节点。 假如启用了“停止服务器”选项,则表示服务器正在运行。 我们选择它来停止服务器。

图:创建嵌入式毗连
要创建嵌入式毗连,我们右键单击 Java DB 嵌入式驱动程序,然后选择毗连利用选项。 同样,我们通过选择 Java DB 服务驱动程序来创建服务器毗连。

图:新建毗连向导
我们有一个新建毗连向导对话框。 在此对话框中,我们填写数据库名称和用户凭据。 JDBC URL 是根据此数据创建的。 我们已经指定了testdb数据库的完整路径。 这里似乎没有考虑 Java DB 系统目录。

成功创建嵌入式数据库毗连后,我们在 NetBeans Services 窗口中看到以上图标。
建立表

数据库毗连已创建。 接下来要做的是创建一个新的数据库表。 我们将创建一个名为FRIENDS的简单表,此中包罗两列:Id和Name。 ID 为INTEGER和Name VARCHAR(30)。
我们扩展数据库毗连节点,并进一步扩展USER12模式。 我们右键单击表图标,然后选择创建表选项。

图:创建一个新表
出现创建表对话框。 我们创建两列。 ID 和名称。

图:创建的Friends表
FRIENDS表已创建。 现在Tables节点是可扩展的,我们看到一个新的表图标。

图:实行下令
接下来,我们将实行一些 SQL 语句。 我们右键单击FRIENDS表图标,然后选择实行下令选项。 NetBeans 中将出现一个新的 SQL 下令窗口。

图:将数据插入FRIENDS表
在“SQL 下令”窗口中,我们编写了几个INSERT INTO SQL语句。 我们通过单击“运行 SQL”图标来实行语句。 该图标是带有绿色三角形的棕色椭圆形对象。 我们也可以利用Ctrl + Shift + E快捷方式实行 SQL 语句。

图:查看FRIENDS数据
在 SQL 下令窗口中运行SELECT * FROM FRIENDS,我们看到一个新窗口弹出。 在此窗口中,我们有一个表小部件,此中的数据按列和行进行组织。 我们有图标来修改此 gui 组件中的数据。

上图显示了用于处理表中数据的图标。 前两个图标分别用于插入新记录和删除所选记录。 假如我们利用鼠标指针选择更多的行并同时按下Shift键,则可以删除多个记录。 假如修改了数据,则会启用“提交记录”图标。 仅在我们实行此操作后才生存数据。 除了 SQL 语句,我们可以利用 GUI 工具修改数据。 通过双击记录,将显示一个行小部件。 在此小部件中,我们可以更改数据。 通过单击“提交记录”操作来生存更改。
在本章中,我们已经在 NetBeans IDE 中利用 Java DB。
SQLAlchemy 教程

   原文: http://zetcode.com/db/sqlalchemy/
  这是 SQLAlchemy 教程。 它涵盖了 SQLAlchemy SQL 工具包和对象关系映射器的基础。
目录



  • 简介
  • 原始 SQL
  • 架构
  • SQL 表达式语言
  • ORM
SQLAlchemy

SQLAlchemy SQL 工具包和对象关系映射器是一组用于处理数据库和 Python 的综合工具。 它提供了一整套着名的企业级持久性模式,旨在实现高效和高性能的数据库访问。 SQLAlchemy 和 Django 的 ORM 是 Python 社区中利用最广泛的两个对象关系映射工具。
Tweet
相关教程和电子书

SQLite Python 电子书是利用 Python 语言进行 SQLite 编程的深入材料。 MySQL 教程涵盖了 MySQL 数据库系统。 SQLite 教程涵盖了 SQLite 数据库系统。 以下教程是 Python 数据库编程教程: SQLite Python 教程和 MySQL Python 教程。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表