posts - 37, comments - 8, trackbacks - 0, articles - 0

JSP中数据库的一些操作续

Posted on 2008-10-21 22:24 梦与桥 阅读(229) 评论(0)  编辑  收藏 所属分类: jsp程序设计
1、使用事务
如果事务中所有命令都能正确执行,就提交这个事务,否则如果有一个命令出错,就回滚这个事务,并返回到提交前的状态,这样可以保护数据库的完整性。一个数据库连接的默认提交方式是自动提交,每个SQL命令一执行就会提交给数据库,所以先要改为非自动提交模式。实例代码如下:
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ page import="java.sql.*,javax.naming.*,javax.sql.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>    
    
<title>使用数据库事务</title>
  
</head>  
  
<body>
  
<%
   Connection con 
= null;
    try {
            
// 通过连接池来获得一个连接
            Context initContext 
= new InitialContext();
            Context envContext  
= (Context)initContext.lookup("java:/comp/env");
            DataSource ds 
= (DataSource)envContext.lookup("jdbc/sqlserver");
            con 
= ds.getConnection();
            PreparedStatement updateAge 
= null;
            
String updateString = "update student "
                    
+ "set age = ? where name like ?";            
        
            updateAge 
= con.prepareStatement(updateString);
            
int[] age = { 45392596 };
            
String[] names = { "梁朝伟%""贝壳汗母%""小罗%""霍元甲%" };
            
int len = age.length;

            
// 设置事务提交模式为非自动提交
            con.setAutoCommit(
false);

            
for (int i = 0; i < len; i++) {
                updateAge.setInt(
1, age[i]);
                updateAge.setString(
2, names[i]);
                updateAge.executeUpdate();
            }
            
// 上面执行的语句,如果不出现异常则提交 SQL 语句
            con.commit();
            out.println(
"<h1>修改成功,事务执行完毕</h1>");

        } catch (NamingException ex) {
            System.out.println(
"Name Not Bound : " + ex.getMessage());
        } catch (SQLException ex) {
            System.out.println(
"SQLException: " + ex.getMessage());
            
if (con != null) {
                try {
                    System.out.print(
"Transaction is being ");
                    System.out.println(
"rolled back");
                    
// 如果出现异常则事务回滚
                    con.rollback();
                } catch (SQLException excep) {
                    System.out.print(
"SQLException: ");
                    System.out.println(excep.getMessage());
                }
            }
        } finally {
// 不管发生不发生异常,要关闭连接,释放资源
            try {
                
if (con != null) {                    
                    con.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

   
%>    
  
</body>
</html>
2、批处理更新
可以向数据库提交多个更新操作,在某些情况下可以大大提高性能。可以利用Statement、PreparedStatement、CallableStatement对象来提交批处理更新。实例代码如下:
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ page import="java.sql.*,javax.naming.*,javax.sql.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>    
    
<title>使用数据库批处理更新</title>
  
</head>  
  
<body>
  
<%
   Connection con 
= null;
   Statement stmt 
= null;
    try {
            
// 通过连接池来获得一个连接
            Context initContext 
= new InitialContext();
            Context envContext  
= (Context)initContext.lookup("java:/comp/env");
            DataSource ds 
= (DataSource)envContext.lookup("jdbc/sqlserver");
            con 
= ds.getConnection();
            
            stmt 
= con.createStatement();
            con.setAutoCommit(
false);
            stmt.addBatch(
"insert into student values(20,'拉登',56)");
            stmt.addBatch(
"insert into student values(21,'张学友',49)");
            stmt.addBatch(
"insert into student values(22,'刘德华',51)");
            stmt.addBatch(
"insert into student values(23,'猪八戒',128)");
            
int[] updateCounts = stmt.executeBatch();
            con.commit();
            
for (int i = 0; i < updateCounts.length; i++) {
                out.println(
"" + (i + 1+ "条SQL语句修改数据库记录数 : "
                        
+ updateCounts[i]+"<br>");
            }
            con.setAutoCommit(
true);
            ResultSet uprs 
= stmt.executeQuery("select * from student");
            out.println(
"执行批处理更新后的student表中记录:<br>");

            
while (uprs.next()) {
                
String name = uprs.getString("name");
                
int age = uprs.getInt("age");
                out.print(name 
+ " " + age+"<br>");
                out.println();
            }
            
            
// 上面执行的语句,如果不出现异常则提交 SQL 语句
            con.commit();
            out.println(
"<h1>修改成功,事务执行完毕</h1>");
            uprs.close();
            stmt.close();

        } catch (NamingException ex) {
            System.out.println(
"Name Not Bound : " + ex.getMessage());
        } catch (SQLException ex) {
            System.out.println(
"SQLException: " + ex.getMessage());
            
if (con != null) {
                try {
                    System.out.print(
"Transaction is being ");
                    System.out.println(
"rolled back");
                    
// 如果出现异常则事务回滚
                    con.rollback();
                } catch (SQLException excep) {
                    System.out.print(
"SQLException: ");
                    System.out.println(excep.getMessage());
                }
            }
        } finally {
// 不管发生不发生异常,要关闭连接,释放资源
            try {
                
if (con != null) {                    
                    con.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

   
%>    
  
</body>
</html>    
3、操作元数据
    1)DatabaseMetaData(数据库元数据)
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ page import="java.sql.*,javax.naming.*,javax.sql.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>    
    
<title>数据库元数据</title>
  
</head>  
  
<body>
  
<%
   Connection con 
= null;
    try {
            
// 通过连接池来获得一个连接
            Context initContext 
= new InitialContext();
            Context envContext  
= (Context)initContext.lookup("java:/comp/env");
            DataSource ds 
= (DataSource)envContext.lookup("jdbc/sqlserver");
            con 
= ds.getConnection();
        
            
// 测试数据库信息
            DatabaseMetaData dm 
= con.getMetaData();
            out.println(
"<h2>1. 数据库的基本信息</h1>");
            out.println(
"Database is " + dm.getDatabaseProductName()+"<br>");
            out.println(
"Database version is "
                    
+ dm.getDatabaseProductVersion()+"<br>");
            out.println(
"JDBC Driver is " + dm.getDriverName()+"<br>");
            out.println(
"JDBC driver version is "
                    
+ dm.getDriverVersion()+"<br>");
            
// 获取数据库中目录(数据库)的信息
            out.println(
"<h2>2. 数据库中目录(数据库)的信息</h2>");
            ResultSet catalogs 
= dm.getCatalogs();
            
while (catalogs.next()) {
                out.println(catalogs.getString(
1));
            }
            
// 获取数据库中模式的信息
            out.println(
"<h2>3. 数据库中模式的信息</h2>");
            ResultSet schemas 
= dm.getSchemas();
            
while (schemas.next()) {
                out.println(schemas.getString(
1)+"<br>");
            }
            
// 获取数据库中各个表的情况
            out.println(
"<h2>4. 数据库中各个表的信息</h2>");
            ResultSet tables 
= dm.getTables("pubs"nullnullnull);
            
while (tables.next()) {
                
for (int i = 0; i < 5; i++) {
                    out.print(tables.getString(i 
+ 1));
                    out.print(
"  |  ");
                }
                out.println();
            }
            
// 获取数据库表中各个列的信息
            out.println(
"<h2>5. 数据库表中各个列的信息</h2>");
            ResultSet columns 
= dm.getColumns(nullnull,"student"null);
            
while (columns.next()) {
                
for (int i = 0; i < 18; i++) {
                    out.print(columns.getString(i 
+ 1));
                    out.print(
"  |  ");
                }
                out.println();
            }
            
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                
// 用完后要关闭连接,释放资源
                
if (con != null)
                    con.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
   
%>    
  
</body>
</html>
    2)ResultSetMetaData(结果集元数据)
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ page import="java.sql.*,javax.naming.*,javax.sql.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>    
    
<title>结果集元数据</title>
  
</head>  
  
<body>
  
<%
   Connection con 
= null;
   Statement stmt 
= null;
   ResultSet rs 
= null;
   
    try {
            
// 通过连接池来获得一个连接
            Context initContext 
= new InitialContext();
            Context envContext  
= (Context)initContext.lookup("java:/comp/env");
            DataSource ds 
= (DataSource)envContext.lookup("jdbc/sqlserver");
            con 
= ds.getConnection();
            stmt 
= con.createStatement();
            
String querySQL1 = "select * from student";
            rs 
= stmt.executeQuery(querySQL1);

            
// 提取结果集的元数据:
            ResultSetMetaData rsmd 
= rs.getMetaData();
            
int colCount = rsmd.getColumnCount();
            
String[] columnNames = new String[colCount];
            
String[] columnLabels = new String[colCount];
            
int[] columnTypes = new int[colCount];

            
for (int i = 0; i < colCount; i++) {
                columnNames[i] 
= rsmd.getColumnName(i + 1);
                columnLabels[i] 
= rsmd.getColumnLabel(i + 1);
                columnTypes[i] 
= rsmd.getColumnType(i + 1);
            }            
            out.println(
"<h2>结果集的元数据如下:</h2>");
            out.println(
"<h2>----------------------</h2>");
            out.println(
"列名:");
            
for (int i = 0; i < colCount; i++) {
                out.print(columnLabels[i] 
+ "\t");
            }
            out.println(
"<br>");
            out.println(
"列标签:");
            
for (int i = 0; i < colCount; i++) {
                out.print(columnNames[i] 
+ "\t");
            }        
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                
// 用完后要关闭连接,释放资源
                
if (con != null)
                    con.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
   
%>    
  
</body>
</html>
4、JavaBean操作数据库
    1)JavaBean
package jdbcdemo;
/**
 * 封装数据库操作的JavaBean
 * 
@author Administrator
 *
 
*/

import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import java.util.*;
public class QueryBean {
    
private Connection conn=null;
    
private Vector data=new Vector();    
    
    
private Connection getConn(){
        
try{
//             通过连接池来获得一个连接
            Context initContext = new InitialContext();
            Context envContext  
= (Context)initContext.lookup("java:/comp/env");
            DataSource ds 
= (DataSource)envContext.lookup("jdbc/sqlserver");
            conn
= ds.getConnection();
            
        }
catch(Exception e){
            e.printStackTrace();
        }

        
return conn;
    }

    
    
public Vector getData(){
        
try{
            getConn();
            Statement st 
= conn.createStatement();
            String query 
= "select id,name from student";

            
// 获得一个结果集
            ResultSet rs = st.executeQuery(query);
            
// 获得结果集的元数据(表及相关的信息)
            ResultSetMetaData rsmt = rs.getMetaData();
            
// 得到结果集有几列
            int num = rsmt.getColumnCount();
            
while (rs.next()) {
                Vector row
=new Vector();
                
// 输出每一行的值                
                for (int i = 1; i <= num; i++{
                    String temp 
= rs.getString(i);    
                    row.add(temp);
                }

                data.add(row);                
                
            }
            
            
        }
catch(Exception e){
            e.printStackTrace();
            
        }
finally{
            
try {
                
// 用完后要关闭连接,释放资源
                if (conn != null)
                    conn.close();
            }
 catch (Exception e) {
                e.printStackTrace();
            }

        }
        
        
return data;        
    }

}
    2)显示
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ page import="java.util.*" %>
<jsp:directive.page import="jdbcdemo.QueryBean"/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>    
    
<title>查询数据库数据</title>
  
</head>  
  
<body>
  
<jsp:useBean id="sel" scope="page" class="jdbcdemo.QueryBean"></jsp:useBean>
  
  
<%  
    try {
            out.println(
"<H1>调用JavaBean查询数据</H1>");    
            out.println(
"<table width='600' border='1'>");
            Vector data
=sel.getData();
            
for(int i=0; i<data.size();i++){
                out.println(
"<tr>");
                Vector row
=(Vector)data.elementAt(i);
                
for(int j=0;j<row.size();j++){
                    out.println(
"<td>"+row.elementAt(j)+"</td>");
                }
                out.println(
"</tr>");
            }            
            out.println(
"</table>");
            
        } catch (Exception e) {
            e.printStackTrace();        
        }
   
%>    
  
</body>
</html>
5、JavaBean操作数据库
    所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入或页面请示的查询字符串,欺骗服务器执行恶意的SQL命令。以验证用户身份登录为例,网页中的Web表单要求用户输入用户名和密码,如果后台采用如下方式构造SQL语句来验证用户和密码是否正确:select * from admin where username=' "&user&" ' and password=' "&pwd&" '
那么,如果输入的用户名是:1 'or' 1 '='1,后台的查询语句将会变成:
select * from admin where username=' 1 'or' 1 '= ' 1 ' and password=' "&pwd&" '
这样查询语句就通过了,从而就可以进入管理界面。所以防范的时候需要对用户的输入进行检查,特别是一些特殊的字符串,比如单引号、双引号、分号、逗号、冒号、连接号等,对它们进行转换或者过滤。
要防范SQL注入式攻击有两种方式:一种是编写客户端代码以阻止用户提交包含敏感信息的数据;另一种是编写服务端代码以在服务端进行业务操作之前,对用户提交的参数进行检查。
1)客户端防范SQL注入式攻击的JavaScript代码:
<script language="javascript">
<!--
var url=location.search;
var re=/^\? (.*)(select%20|insert%20|delete%20|count\(|drop%20table|update%20truncate%20|asc \(|mid\(|char \(|xp_cmdshell|exec%20master|net%20localgroup%20administrators|\"|:|net%20user|\'|%20)(.*)$/gi;
var e=re.test(url);
if(e)
{
laert(
"含有非法字符");
location.href=
"error.jsp";
}
//-->

2)服务器端防范SQL注入式攻击的Java代码:
booleancheckParam(String param){
//列出要查找的敏感字符串
  String[] checkstr={"'","%","delete","insert"};
  
for(int i=0;i<checkstr.length;i++){
     
if(param.indexOf(checkstr[i]>=0){
       
return false;
    }

  }

  
return true;
}


只有注册用户登录后才能发表评论。


网站导航: