Java软件报表软件技术博客

java报表软件技术汇总 java报表软件制作 报表软件新闻
posts - 355, comments - 100, trackbacks - 0, articles - 3
   :: 首页 :: 新随笔 ::  :: 聚合  :: 管理
ParamDBTableDataDemo2
 
这是一个按参数从数据库取值的小例子;
参数为 param ,例如 grade:=77;87;97;
即传入数据库字段名和值 取出所需要的值列;
这里连的数据库为FineReport报表的内置数据库,适用时可输入grade:=87;97;或者classno:=class1;class2;

代码如下:

  /*
  * Copyright(c) 2001-2009, FineReport Inc, All Rights Reserved.
  */
package com.fr.demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

import com.fr.base.FRContext;
import com.fr.data.AbstractTableData;
import com.fr.report.parameter.Parameter;
/*
 *  ParamDBTableDataDemo2
 *
 *  这是一个按参数从数据库取值的小例子;
 *  参数为 param ,例如 grade:=77;87;97;
 *  即传入数据库字段名和值 取出所需要的值列;
 *  这里连的数据库为FineReport的内置数据库,适用时可输入grade:=87;97;或者classno:=class1;class2;
 *  建议使用安装目录下 /bin/DesignerDOS.exe 打开设计器,这样就能看到控制台输出
 */

public class ParamDBTableDataDemo2 extends AbstractTableData {
 
 // 自定义间隔符 暂定为':='和‘;’ 即输入参数时需像如此  grade:=77;87;97; 表示输出grade的值为77、87或者97的值列。
 // 您也可以输入您需要的id字段,例如id:=77;87;97。请注意这里需要输入数据库内的实际字段名.
 private String splitMark1 = ":=";
 private String splitMark2 = ";";
 
 // 列字段名数组 保存在数据集窗口下一开始显示的数据列名称
 private String[] columnNames = null;
 
 // 保存查询的多有字段名及其对应类型,例如 classNo->varchar grade->double
 Map col = new HashMap();
 
 // 保存查询得到的值列
 private ArrayList valueList = null;
 
 // 构造函数
 public ParamDBTableDataDemo2() {
  // 定义需要的参数 param
  this.parameters = new Parameter[]{new Parameter("param")};
  // 初始化下列名,暂定为columnName#0,columnName#1......显示在数据集窗体中的
  // 假如您的需求固定,可以直接在这里输入您确定的列名
  // 例如,您查找学生表有,name,sex,age 3个字段,那么编码如下
  // String[] columnNames = new String[3];columnNames[0]="name";columnNames[1]="sex"columnNames[2]="age";
  // 因为程序数据源的字段是一开始就固定的,所以您需要先设定。这里暂且以columnNames#N命名。
  columnNames = new String[10];
  for (int i = 0; i < 10 ; i++) {
   columnNames[i] = "columnNames#" + String.valueOf(i);
  }
 }
 
 // 取出列的数量
 public int getColumnCount() {
  return columnNames.length;
 }
 
 // 取出相应的列的数量
 public String getColumnName(int columnIndex) {
  return columnNames[columnIndex];
 }
 
 // 取出得到的结果集的总的行数
 public int getRowCount() {
  init();
  return valueList.size();
 }
 
 // 取出相应位置的值
 public Object getValueAt(int rowIndex, int columnIndex) {
  init();
  // 注意您查询的字段顺序是和数据集窗口中显示的字段一致的,例如您查询的字段顺序为name,sex,age
  //那么columnName#0 对应 name columnName#1 对应 sex ,columnName#2 对应 age
  if (columnIndex >= col.size()) {
   return null;
  }
  return ((Object[])valueList.get(rowIndex))[columnIndex];
 }
 
 // 按照取到的参数进行处理,得到结果集
 public void init() {
  //确保此函数只被执行一次
  if (this.valueList != null) {
   return;
  }
  // 保存得到的参数
  String param = null;
  // 保存取到的结果集
  valueList = new ArrayList();
  // 这里必须按照名称再做一次匹配取值,因为对象中的parameters数组在调用时,被排序过,暂时是以英文排序。
  // 虽然这个例子中只有一个参数,但需要解释清楚
  for (int i = 0;i < parameters.length ; i++) {
   if (parameters[i].getName().equals("param")) //做匹配
    param = parameters[i].getValue().toString();
  }
  // 数据库表名,这里固定,您也可以按照上一个例子用参数取值
  String tableName = "StScore";
  // 开始构造SQL语句,这里用*取全部值,您也可以自己定义需求,例如您想获得name,sex,age3个字段,那么这里改为"select name,sex,age from "
  String sql="select * from "+tableName;
  // 截取查询字段和值 paramArray[0]保存字段名 paramArray[1]保存值
  String[] paramArray = param.split(splitMark1);
  if( paramArray.length != 2 ) {
   FRContext.getLogger().log(Level.INFO, "Error: \n" +"参数格式不正确");
   return;
  }
  // 将值字段截取,保存到paranValue数组中
  String[] paramValue = paramArray[1].split(splitMark2);
  sql+=" where " + paramArray[0].trim() + " = ? ;";
  // 在日志中打印sql语句
  FRContext.getLogger().log(Level.INFO, "Query SQL of ParamDBTableData: \n" +sql);
  // 下面开始建立数据库连接,按照刚才的sql语句进行查询
  Connection conn = this.getConnection();
  // 定义结果集
  ResultSet rs = null;
  try {
   // 以下取得该表的所有字段及其对应的类型,并匹配参数中输入的查询字段,得到查询字段的类型。
   String querySql = "select * from " + tableName + " where 1=2;";
   Statement stmt = conn.createStatement();
   rs = stmt.executeQuery(querySql);
   // showRs(rs);假如您不知道所查表的具体字段名以及对应类型,这里可以使用showRs方法在控制台输出一下。
   // type即为输入的参数中查询字段的类型 例如示例所用StScore表中,grade为double classNo为varchar
   String type = getColumnType(rs,col,paramArray[0]);
   // 假如没有该字段,返回空
   if(type == null) {
    FRContext.getLogger().log(Level.INFO, "Error: \n" +"参数对应字段不存在");
    return;
   }
   // 这里开始查询
   PreparedStatement ps = conn.prepareStatement(sql);
   for(int i = 0;i < paramValue.length;i++){
    // 根据type类型做一下匹配,再赋值,示例中只有varchar和double两种类型
    // 您可以根据您实际数据库中类型更改,假如您不知道,可以用上面提到的showRs方法查看一下。
    // 假如您只需要输入id(一般都是int型),那么这里直接 ps.setInt(1,paramValue[i]);即可
    if(type.equals("varchar")){
     ps.setString(1, paramValue[i]);
    } else if(type.equals("double")) {
     ps.setDouble(1,Integer.parseInt(paramValue[i]));
    }
    rs = ps.executeQuery();
    //用对象数据保存一行数据
    Object[] objArray=null;
    while(rs.next()){
     objArray = new Object[col.size()];
     for(int j = 0; j < col.size() ; j++ ){
      objArray[j] = rs.getObject(j+1);
     }
     // 在valueList中加入这一行数据
     valueList.add(objArray);
    }
   }
   // 释放数据库资源
   rs.close();
   ps.close();
   conn.close();
   // 打印一共取到的数据行数量
   FRContext.getLogger().log(Level.INFO, "Query SQL of ParamDBTableData: \n" + valueList.size() + " rows selected");
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
 
 // 获取数据库连接 driverName 和 url 可以换成您需要的
 public Connection getConnection() {
  String driverName = "sun.jdbc.odbc.JdbcOdbcDriver";
  String url = "jdbc:odbc:FRDemo";
  String username = "";
  String password = "";
  Connection con = null;
  try {
   Class.forName(driverName);
   con = DriverManager.getConnection(url,username,password);
  } catch (Exception e) {
   e.printStackTrace();
   return null;
  }
  return con;
 }
 
 // 将表字段及其类型存入Map中,得到传入参数对应的字段类型
 public String getColumnType(ResultSet rs , Map col , String param){
  try {
   ResultSetMetaData md = rs.getMetaData();
   int cols = md.getColumnCount();
   for(int i = 1;i <= cols;i++){
    col.put(md.getColumnName(i).toLowerCase(), md.getColumnTypeName(i).toLowerCase());
   }
   return (String)col.get(param.toLowerCase());
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }
 
 // 得到结果集中的字段名及其字段类型
 public static void showRs(ResultSet rs){
  try{
   StringBuffer sb = new StringBuffer();
   ResultSetMetaData md = rs.getMetaData();
   int cols = md.getColumnCount();
   for(int i = 1;i <= cols;i++){
    sb.append(md.getColumnName(i) + "->");
    sb.append(md.getColumnType(i) + "==");//返回的是类型编号
    sb.append(md.getColumnTypeName(i) + "\n");//返回数据库中类型名字
   }
   while(rs.next()){
    for(int i = 1;i <= cols;i++){
     sb.append(md.getColumnName(i) + "=");
     sb.append(rs.getString(i) + "   ");
    }
    sb.append("\n");
   }
   System.out.println(sb);
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 
 // 释放一些资源,因为可能会有重复调用,所以需释放valueList,将上次查询的结果释放掉
 public void release() throws Exception {
  super.release();
  this.valueList = null;
 }
}




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


网站导航: