servlet学习笔记之四
——数据库访问
1.JDBC-ODBC桥,其本身也是一个驱动,利用这个驱动,我们可以使用JDBC API 通过ODBC去访问数据库。这种桥机制实际上是把标准的JDBC 调用转换成相应的ODBC 调用,因此这种方式访问数据库效率是比较低。也有些数据库没有提供JDBC驱动,只有ODBC 驱动,比如访问ms access数据库就只能利用JDBC-ODBC 桥来访问。
2.建立到数据库的连接
DriverManager类的getConection()方法建立到数据库的连接,返回一个Connection对象。在DriverManager类中提供了3个重载的getConnection()方法。
² public static Connection getConnection(String url)throws SQLException
给方法通过给出数据库URL建立到数据库的连接。比如:
Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection ("jdbc:odbc:test");
² public static Connection getConnection(String url,String user,String psw)throws SQLException
给方法取得数据库连接必须给出用户名和密码。如:
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
conn = DriverManager.getConnection(urlname,user,pw);
² public static Connection getConnection(String url,Properties info)throws SQLException
其中info 键值对,一般需要给出用户名和密码。
3.访问数据库
数据库连接被用于向数据库服务器发送命令和SQL语句,在连接建立后,需要对数据库进行访问,执行SQL语句。在java.sql包中给我们提供了3个接口:Statement,PreparedStatement ,CallableStatement.
Statement
调用Connection对象的creatStatement()方法创建一个Statement对象。Statement对象用于执行静态的SQL语句,返回执行的结果。
Statement接口中定义了下列方法用于执行SQL语句。
ResultSet executeQuery(String sql ) throws SQLException
该方法执行sql语句,返回一个ResultSet对象。ResultSet对象用于查看执行的结果。
int executeUpdate(String sql )throws SQLException
该方法执行sql指定的insert、update或者delete语句。另外,该方法也可以用于执行SQL DDL语句,例如:create table。
boolean execute(String sql)throws SQLException
感觉模糊,我觉得还是不用比较好。
连接数据库中,getInitParameter(“url”);获取的是web.xml的信息。
<Servlet>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mysql</param- value >
</init-param>
<init-param>
<param-name>user</param-name>
<param-value>javahe</param- value >
</init-param>
</Servlet>
PreparedStatement
我们在程序中传递的SQL语句在执行前必须被预编译,包括语句分析、代码优化等,然后才能被数据库引擎执行。如果重复执行只有参数不同的SQL语句,是比较低效的。如果要用不同的参数来多次执行同一个SQL语句,可以使用PreparedStatement的对象。PreparedStatement接口从Statement接口继承而来,它的对象表示一条预编译过的SQL语句。我们可以通过调用Connection对象的prepareStatement()方法而得到PreparedStatement对象。PreparedStatement对象所代表的SQL语句中的参数问号来表示,第一个参数从一开始。
eg:
String sql = "delete from " + m_objTable + " where " + m_objFldTagId + "=?";
PreparedStatement objStatement = m_objConnection.prepareStatement (sql);
objStatement.setInt (1, objSms.id);
objStatement. executeUpdate ();
CallableStatement
CallableStatement对象用于执行sql存储过程。CallableStatement接口从PreparedStatement接口继承而来,我们可以通过调用Connection对象的prepareCall()方法来得到CallableStatement对象。在执行存储过程之前,凡是存储过程中类型为OUT的参数必须被注册,这可以通过CallableStatement对象的registerOutParameter()方法来完成。对于类型为IN类型的参数,可以利用setXXX()方法来设置参数的值。
eg:
……
CallableStatement cstmt = conn.prepareCall(“call p_changesal(?,?)”);
cstmt.registerOutParameter(2,java.sql.Types.INTEGER);
cstmt.setInt(1,212212);
cstmt.execute();
int sal = cstmt.getInt(2);
元数据
在sql中,用于描述数据库或者它的各个组成部分之一的数据称为 元数据。
可以调用ResultSet 对象的getMetaData()方法来得到ResultSetMetaDate对象,该对象有获取元数据的方法(详细方法请查api)。
事务处理
事务处理保证所有的事务都作为一个工作单元来执行,即使出现了硬件或者系统失灵,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的操作都被提交,要么整个事务回滚到最初的状态。
当一个连接建立时,默认情况下是设置为自动提交事务,这意味着每次执行一个sql语句时,如果执行成功,就会向数据库自动提交,也就不能回滚了。为了将多个sql语句作为一个事务执行,可以调用Connection对象的setAutoCommit()方法,传入false来取消自动提交事务,然后在所有的sql语句完成后,调用Connection对象的commit()方法来提交事务,或者在执行出错时候调用Connection对象的rollback()方法来回滚事务。
至于可滚动和可更新的结果集。我这里不做总结。日后写翻页程序基本就了解了。
至于会话跟踪,不多说。改天练习一个购物车程序。练习一个在线人数统计(无非就是在web服务端用了静态Hash表存储信息,每次用户登录就add进去)。
转入JSP学习中。