質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.21%

MySQLのレコード数を配列String[]の要素数にして他クラスから参照したい

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 4,443

fufun

score 10

MySQLのレコード数を配列String[]の要素数にして、他クラスから参照したいと考えています。
具体的には、
「SELECT count(*) FROM table");」の結果nを、
String[] a = new String[n]として、中身にデータを与え、それを他クラスから参照したいと考えています。

該当のソースコード

public class tst {
    public static void main(String args[]) throws SQLException, ClassNotFoundException {
        tst2.MainMethod();
        for (int i = 0; i < tst2.a.length; i++) {
            tst2.a[i] = Integer.toString(i);
            System.out.println(tst2.a[i]);
        }
    }

}
public class tst2 {
    public static int n;
    public static String[] a = new String[n];

    public static void MainMethod() throws SQLException, ClassNotFoundException {
        String url = "jdbc:mysql://localhost/data1";
        String user = "user";
        String password = "pass";
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(url, user, password);
        Statement stmt = conn.createStatement();

        count(stmt);
        String[] a = new String[n]; //冗長な宣言

        stmt.close();
        conn.close();
    }

    public static void count(Statement stmt) throws SQLException {
        ResultSet rset2 = stmt.executeQuery("SELECT count(*) FROM table");
        rset2.next();
        n = Integer.parseInt(rset2.getString(1));
        rset2.close();
    }

}

tst2.javaでは、
・レコード数nを代入するint n;
・n個分の要素数を持つ配列String[] a;
が宣言されています。
グローバル変数となっていますので、プログラムを実行した時にはnの中身は0が代入されており、結果的にString[] aの要素数も0となるので配列として機能しません。
そこでtst2.javaでは、レコード数をjdbcドライバで取得した後にも宣言しています。

String[] a = new String[n]; //冗長な宣言

明らかに二度手間な変数宣言ですが、グローバル変数のString[] a の行を無くし、こちらで宣言すると、tst2.javaではString a[レコード数]として扱うことが出来るのですが、tst.javaから参照することが出来ません(グローバル変数で無いため)。

上記プログラム(tst.java)ではtst2.a[i]の値にString型のiを代入していますが、MySQLからロードした文字列を代入したいと考えています。

まとめ

  • tst.javaで、tst2.javaの配列a[n]に代入、または参照したい。

  • そのためには配列aはグローバル変数である必要がある。

  • グローバル変数で宣言すると、レコード数nの値が0になってしまい、必要な要素数が確保できない

となります。
拙文となりますが、よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+3

明らかに二度手間な変数宣言

「二度手間」ではなく「間違っている」というべきですね。メソッドの中での宣言とnewによる初期化は削除すべきです。

  1. nが決まるところでa = new String[n]とすればよいです。
    aをstatic変数にしてますが、nがわからない状況でnewしようとしているから問題なのです。
    nの値がわかった時点(countメソッドの中など)でnewすればいいのですよ?
  2. tst2クラスのstaticフィールドnは不要です。aに配列を代入した後でa.lengthとすれば何個配列要素があるかはわかるからです。冗長な情報はプログラムの明快さを損なうことがあるので明確な目的がない限り省く方がよいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/11 08:14

    コメントありがとうございます。おかげ様で解決しました。

    > nがわからない状況でnewしようとしているから問題なのです。
    知りたい事がこの一文にありました。非常に分かりやすかったです。
    > aに配列を代入した後でa.lengthとすれば何個配列要素があるかはわかるからです。
    目から鱗でした。ありがとうございます。

    キャンセル

0

SELECT count(*) FROM table


の結果は常に1行なので、String[] で受ける必要はないでしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

直接関係ないかもしれませんがとりあえず別名をつけることをお勧めします

SELECT count(*) as count FROM table

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

全データをString[][]に入れる例です
あくまでも全データがString型だったらの場合に限ります

String sql="SELECT * FROM table";
            ResultSet rs=stmt.executeQuery(sql);
            ArrayList<String[]> wee=new ArrayList<>();
            while (rs.next()) {
                ArrayList<String> we=new ArrayList<>();
                int count=0;

                while(true){
                    count++;
                    String r=new String();
                    try{
                     r=rs.getString(count);}
                    catch(Exception e){
                        break;
                    }
                    we.add(r);


                }
                String[] r2=we.toArray(new String[0]);
                wee.add(r2);

                }
                String[][] r3=wee.toArray(new String[0][0]);

                for(String[] r4:r3){
                for(String r5:r4){
                    System.out.print(r5+" ");
                }
                System.out.println();

                }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/11 00:13

    変数 r を宣言する際に毎回、new String() を代入している理由は何ですか?

    また、
    > あくまでも全データがString型だったらの場合

    とのことですが、そうでない場合は何が起きるのか教えていただけますか?

    キャンセル

  • 2016/11/11 00:41

    >変数 r を宣言する際に毎回、new String() を代入している理由
    データベースの表の中に空白がある場合空オブジェクトをaddして空白である事を示すデータをArrayListに入れておくためです これがないと空白がある時上下に対して表示がずれ、いくつ目のデータかも分からなくなります


    >そうでない場合は何が起きるのか
    r=rs.getString(count);の部分で何らかのエラーが出ると思います
    データ一行に複数の型の変数が入っている場合は
    r=rs.getObject(count);とするべきですが
    その場合String[]を作ってデータを格納することができそうにありません

    キャンセル

  • 2016/11/11 01:26 編集

    返信ありがとうございます。

    > データベースの表の中に空白がある場合空オブジェクトをadd

    「空白」とは NULL のことでしょうか?
    何にせよ、変数 we に「空オブジェクト」が add されることはあり得ません。

     r=rs.getString(count);

    が実行された時点で変数 r にはDBから取得した値が代入される上に、
    この行で例外が発生した場合は直ちに break しているためです。

    それ以前に、ループの中でString型の引数無しのコンストラクタを実行するのは、メモリのムダ遣いです。
    毎回、新しいインスタンスを生成してしまうからです。

    http://docs.oracle.com/javase/jp/7/api/java/lang/String.html#String()
    > String は不変なので、このコンストラクタを使う必要はありません。

    単に String r = "" で、十分です。
    (もし、実行する必要があれば、の話ですが)


    また、
    > r=rs.getString(count);の部分で何らかのエラーが出ると思います

    について、少なくとも MySQL では、テーブルのデータ型が何であっても getString() の実行で例外が発生することはなく(※)、
    正常に各カラム型の文字列表現を取得することができます。

    ResultSet インターフェースのAPIリファレンスでも
    > 指定された列の値を、Java プログラミング言語の String 【として】取り出します。

    とあるので、おそらくこの動作はどのDBでも同様と考えられます。
    http://docs.oracle.com/javase/jp/7/api/java/sql/ResultSet.html#getString(int)

    ※ int, datetime, timestamp, decimal, float, binary, varbinary, blob で確認

    キャンセル

  • 2016/11/11 03:59

    そうですか それではString r = ""でよく、getString()に全てのデータが入れられるのかも知れませんね

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る