Duyệt HashMap<Integer, Object> cứ mỗi phần tử trong HashMap đưa vào ResultSet???

Discussion in 'Xây dựng ứng dụng server-client web base' started by nvqcntt, 3/1/13.

  1. nvqcntt Member

    Chào các bạn, mình đang gặp vấn đề nhờ các bạn giúp đỡ:
    Trong HashMap<Integer, Object> (Trong đó Object là ResultSet), giờ mình muốn duyệt từng phần tử đấy, cứ mỗi phần tử trả về 1 ResultSet khác nhau. các xử lý thế nào?

    Đây là đoạn code về lớp kết nối connection trong đó có hàm getManyResultSet cho kết quả trả về nhiều ResultSet được lưu trong HashMap<Integer, ResultSet>

    PHP:

    package application
    .processData;

    ...
    public class 
    MyConnection {

    ...

    public 
    Connection getConnection() throws Exception {
    ...
    return 
    this.connection;
    }

    public 
    Statement getStatement() throws Exception {
    if (
    this.st == null true this.st.isClosed()) {
    this.st this.getConnection().createStatement();
    }
    return 
    st;
    }

    public 
    HashMap<IntegerResultSetgetManyResultSet(String StoreName){

    HashMap<IntegerResultSetdataOutput = new HashMap<IntegerResultSet>();
    ResultSet rs null;

    boolean resultSet;
     
    try {
    String callStore;
    callStore "{Call " StoreName "}";

    CallableStatement cs this.getConnection().prepareCall(callStore);
    cs.executeQuery();
    resultSet cs.execute();
    int count 0;
    while(
    resultSet){
    count ++;
    rs cs.getResultSet();
    dataOutput.put(countrs);
    resultSet cs.getMoreResults();
    rs.close();
    }
    cs.close();

    } catch (
    Exception e) {
    e.printStackTrace();
    }
    return 
    dataOutput;
    }
    }
    Đây là phương thức gọi kết quả từ lớp connection trên:

    PHP:

    public void abc(){

    HashMap<IntegerResultSetdataReport = new HashMap<IntegerResultSet>();
    dataReport = new MyConnection().getManyResultSet("ReaderDataNew");

    ResultSet rsInfor null;

    rsInfor = (ResultSet)dataReport.get(1);
    try {
    while(
    rsInfor.next()){
    filePath rsInfor.getString("DuongDan");
    tieuDe rsInfor.getString("TenTieuDe");
    }
    } catch (
    Exception e) {
    e.printStackTrace();
    }
    ResultSet rsData = (ResultSet)dataReport.get(2);
    }
    Exception ---> The Result set is closed.
    Mong các bạn chỉ giúp. Xin cảm ơn.
  2. huymq New Member

    ResultSet chỉ là con trỏ trỏ tới hàng dữ liệu hiện tại, nó có nhiệm vụ để đọc dữ liệu thôi. Trong trường hợp của bạn mỗi lần bạn lưu vào HashMap bạn đều close đi thì chả bị lỗi như vậy
  3. thanhlikes09bkdn Active Member

    Vì sao bạn phải lôi dữ liệu trong HQTCSDL ra để xử lý vậy. HQTCSDL có thể xử lý được tính toán bình thường mà.
    Còn nếu muốn đến vị trí nào của hàng thì có thể gọi phương thức absolute trong ResultSet mà!
  4. nvqcntt Member

    Huymq: Cảm ơn bạn, nhưng nếu trong hàm getManyResultSet không đóng resultSet kia thì nó cũng báo lỗi trên.
    thanhlikes...: có nhiều lúc cũng cần chứ bạn, ví dụ bạn muốn in báo cáo động, như vậy bạn phải nhập đường dẫn trong database, bạn phải lấy đường dẫn đó ra để xử lý sau đó hiển thị. Nếu là bạn thì bạn làm thế nào? mình cũng muốn tham khảo. absolute chỉ kiểm tra dòng dữ liệu tại 1 vị trí nào đấy, kết quả là kiểu boolean. Giờ muốn lấy giá trị 1 ô nào đó trong bảng thì làm thế nào?!
  5. thanhlikes09bkdn Active Member

    Bạn nêu rõ mục đích bạn làm cái gì? Mình đọc code không hiểu cho lắm :D
  6. huymq New Member

    Khi bạn đóng statement thì resultset đã tự động đóng rồi mà :), quan trọng như mình nói là nó chỉ là con trỏ để đọc thôi nên tốt nhất bạn nên đọc giá trị của từng hàng ra trước, map cả hàng hoặc giá trị từng cột mà bạn muốn vào một object (giống như java bean)
    Nancru likes this.
  7. nvqcntt Member

    Huymq:
    Kể cả mình không đóng statement thì cũng bị lỗi ấy. Thực sự thì không có cách nào khác ah. Nếu đọc từng dòng đưa vào Map thì nó sẽ lâu thêm phần đọc từng dòng dữ liệu khi chạy thủ tục làm quá trình hiễn thị dữ liệu lâu thêm.
    thanhlikes...:
    Thế này bạn nhé, mình cũng mới tiếp cận java thôi, nên sẽ có nhiều đoạn lệnh hơi "chuối" vì mọi cái là làm theo tư duy của .NET đưa sang.
    Bài toán của mình là: In báo cáo động: dữ liệu động, tiêu đề báo cáo động (để người dùng chủ động sửa tiêu đề nếu cần thiết), người ký duyệt báo cáo cũng động(người dùng chủ động thay đổi người ký). Tất cả được lấy từ database.
    Như vậy khi chạy 1 store thì nó đồng thời trả về 2 table: 1. Dữ liệu báo cáo, 2. Thông tin báo cáo (đường dẫn, tiêu đề, người duyệt). Như vậy khi chạy hàm getManyResultSet thì nó cho ta 2 resultSet, mỗi resultSet cho 1 kết quả khác nhau, làm nhiệm vụ khác nhau.
    Mình cũng nghe nói dùng subreport giải quyết trường hợp này, nhưng mình chưa thử. Nếu vậy store ở trên sẽ tách thành 2 store với 2 chức năng, và khi mỗi lần gọi báo cáo thì có 2 lần connected database hay có cách nào khác.
    Mong các bạn chỉ giúp. Xin trân trọng cảm on.
  8. thanhlikes09bkdn Active Member

    Bạn dùng SQLServer à?
    Mình dùng MySql mỗi thủ tục chỉ trả về một bảng chứ mấy.
    1. Dữ liệu báo cáo, 2. Thông tin báo cáo (đường dẫn, tiêu đề, người duyệt) hai bảng này có quan hệ với nhau chứ!
    Ý bạn là một số thông tin lấy ra từ cơ sở dữ liệu để report. Còn một số thông tin có thể thay đổi. Thế dữ liệu thay đổi đó không update lại à?
  9. huymq New Member

    Dùng getMoreResult cũng sẽ close ResultSet hiện tại rồi, bạn thử dùng getMoreResults(Statement.KEEP_CURRENT_RESULT) xem.
  10. nvqcntt Member

    Huymq:
    Cảm ơn bạn, mình cũng đang thử xem thế nào:
    thanhlikes...:
    Thế này bạn nhé, csdl nào không quan trọng, tư duy là như nhau cả thôi. Làm báo cáo sẽ có nhiều cách làm chứ không nhất thiết phải 2 table như mình nói.
    Nếu trả về 1 bảng: các thông tin mỗi người duyệt, mỗi chức vụ duyệt là 1 cột tương ứng, các báo cáo khác nhau có thể có số lượng người duyệt khác nhau, chức vụ khác nhau. Trong trường hợp dữ liệu không có, thì các thông tin người duyệt, chức vụ duyệt vẫn phải hiển thị. Những cái này bạn xử lý thế nào.
    Nếu trả về 2 bảng: dữ liệu báo cáo không có, thông tin báo cáo (người duyệt, chức vụ) vẫn hiển thị bình thường. Số lượng người duyệt chức vụ chỉ tăng lên theo dòng (trong trường hơp 1 bảng là theo cột) dễ kiểm soát hơn theo cột, thuận lợi cho việc thêm bớt số vai trò nhiệm vụ của người ký duyệt trong báo cáo khi hiển thị động.
    Với mình nếu trả về 1 hay 2 bảng thì mình sẽ giải quyết 2 hướng trên, không biết nếu là bạn thì bạn xử lý thế nào, mình rất muốn tham khảo, biết đâu lại học đc điều hay.
    Cảm ơn các bạn.
  11. Nancru CongDongJava Project Leader

    Việc close resultSet thì giải quyết bằng cách tạo một object khác để put dữ liệu vào. Cái này người ta gọi là entities hay domains hay models. Nếu có nhìu object thì bỏ vào một List, ko nhất thiết phải bỏ vào Map, chả để làm gì.

    Vấn đề business: không hiểu??? Nói gì lan man quá, có thể list ra các case có thể xảy ra ko?
  12. nvqcntt Member

    Nancru:
    1. Nếu giải quyết theo cách đấy thì quá trình hiển thị báo cáo sẽ lâu thêm vì có thêm phần duyệt mỗi dòng từng resultset rồi đưa vào list. Việc dùng list hay map thì có khác gì nhau mấy đâu, cái này ko bàn đến.
    2. Vấn đề kia thì mình đang muốn nói với bạn thanhlikes...
    Bài toán:
    Hiển thị báo cáo:
    Trong báo cáo gồm các thành phần sau:
    i. Thông tin đơn vị, tên tiêu đề báo cáo (header report)---> lấy từ database.
    ii. Dữ liệu (detail) ---> lấy từ database.
    iii. cuối báo cáo (footer report) có các thông tin chức vụ duyệt báo cáo và người duyệt báo cáo tương ứng ---> lấy từ database.
    Như vậy: khi chạy 1 báo cáo nào đó thì cần phải đưa 1 lúc các thông tin kia lên trong cùng 1 store.
    --->Xảy ra trường hợp:
    a. Nếu đưa vào 1 bảng khi chạy store thì mỗi thông tin: tên đơn vị, tiêu đề, chức vụ, người duyệt... là 1 cột.
    b. Nếu tách các bảng (3 bảng) ---> 3 resultSet. Nếu duyệt mỗi resultSet rồi đưa vào list ---> chạy lâu hơn.
    Không biết giải quyết thế nào. Mong các bạn có kinh nghiệm giải quyết.
    Vì đối với bài toán này. bên .NET mình làm là ok. nhưng bên này thì khó vì cũng mới tiếp cận.
  13. 1, đưa dữ liệu ra list sẽ ko ảnh hưởng đến perform nhiều,vì khi bạn đưa ResultSet lên báo cáo thì nó cũng phải duyệt từng Row.
    2.Bạn thử làm subreport xem sao. title 1 report,detail 1 report,footer 1 report rồi ghép vào nhau.
  14. Nancru CongDongJava Project Leader

    Tui không biết perform của bạn đòi hỏi là bao nhiu mà khắt khe cỡ vậy nhỉ???

    Còn bên .Net ko biết bạn có làm qua MVC framework chưa??? Nếu rồi thì vấn đề trên cũng có thể giải quyết như vậy. Lấy dữ liệu xong thì put vào một object. Rồi muốn làm gì thì làm.

    Ví dụ: object báo cáo: có thể chứa n nội dung = 1 table
    : có thể chứa n ngừoi ký duyệt = 1 table
    : có thể chứa n tiêu đề = 1 table

    Perform lúc này chỉ giảm xuống vài chục milisec.

    Tuy nhiên nếu vẫn muốn làm resultSet thì cách tốt nhất cho bạn là phải close resultSet và connection cuối cùng(sau khi in ra xong cái report).

    Vấn đề khác: Không dùng lib hỗ trợ viết báo cáo à ??
  15. nvqcntt Member

    Việc làm subreport thì mình đang làm, đang bug code vì chưa ra kết quả, có lẽ là tìm lib chưa đúng.
    Về đưa các dữ liệu vào Object thì mình chưa hình dung cách xử lý.
    Vì nếu dùng Object: khi đổ dữ liệu lên report theo lệnh sau:
    ...
    JasperReport jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, JRBeanCollectionDataSource(Object));
    ...
    không biết phần header, detail, footer có fill đúng dữ liệu của nó không?
  16. bạn dùng Ireport bản bao nhiêu thì vào phần lib của nó mà code.
    JasperReport jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, JRBeanCollectionDataSource(Object))
    Object là 1 Collection,
    Dữ liệu thì đúng được,quan trọng là bạn xử lý tnao thôi.
  17. nvqcntt Member

    Nếu đưa dữ liệu vào 1 object (object là collection) thì phải định nghĩa models? như vậy mỗi report là 1 models (nếu các báo cáo không cùng cấu trúc dữ liệu)? Nếu như vậy, khi hiển thị chắc là ok. Nhưng khi sửa report (thêm cột, thay cột hiển thị) thì chắc chắn models cũng can thiệp, store cũng can thiệp. Với store can thiệp thì đơn giản, nhưng models can thiệp thì phải build lại và sẽ rất mất thời gian, trong khi đó, nếu đưa vào resultset thì không cần phải viết models.
    Thực tế, không phải cứ report viết ra là khách hàng dùng ngay, mà có thể người ta yêu cầu thay đổi này, thay đổi nọ cho phù hợp với cách quản lý của họ, và phần thay đổi nhiều nhất khi triển khai 1 ứng dụng là report, có những vấn đề mình có thể tư vấn cho khách hàng theo mình, nhưng có những cái mình phải làm theo ý của họ.
    Mình đã gặp trường hợp này rất nhiều, chính vì thế mình muốn khi viết report, làm thế nào đễ sau này dễ chỉnh sửa nhất, nhanh nhất.
    Nếu là các bạn thì các bạn làm thế nào. Rất mong đc chia sẽ. Trân trọng cảm ơn.

Chia sẻ trang này



Ve may bay di Ha Noi | Ve may bay di Vinh | Ve may bay di Hue | Ve may bay di Da Nang | Ve may bay di Nha Trang | Ve may bay di Da Lat | Ve may bay di Phu Quoc | Ve may bay di Sai Gon | Ve may bay di TPHCM | Ve may bay di Buon Me Thuot | Ve may bay di Hai Phong | Ve may bay di Dong Hoi | Ve may bay Vietjet Air | Phong ve may bay Vietjet Air | Ve may bay Vietnam Airlines | Phong ve may bay Vietnam Airlines | Ve may bay Vietnam Airlines | Ve may bay gia re | Ve may bay | Mua ve may bay | Jetstar | Vietnam Airlines | Air Asia | Tiger Airways | Ve may bay di My | Vietjet Air | Ve may bay di Ha Noi | Ve may bay di Da Nang | Ve may bay di Hai Phong | Ve may bay di Vinh