- PR -

MySQLにbyte[]のデータを入れたい。

投稿者投稿内容
ナスティキャット
常連さん
会議室デビュー日: 2004/03/03
投稿数: 24
投稿日時: 2004-03-26 12:47
こんにちはナスティキャットです。

MySQLにbyte配列のデータを入れたいのですが、どのようにすれば良いのでしょうか?
現在はこのようにしていますがエラーが出てしまいます。
コード:
String strSql = "INSERT INTO images(name,image) " +
"VALUES('" +
(String)Name + "'," +
(byte[])Image + ",0);";


SQLの書き方が稚拙ですいません。
データベースに登録するクラスは、String型でSQL文を受け取ってDBに書き込む形になっています。そこに送るSQLですがどのようにしたら良いのでしょうか?
taku
ぬし
会議室デビュー日: 2002/11/12
投稿数: 918
お住まい・勤務地: 墨田区→中野区
投稿日時: 2004-03-26 13:08
JavaでDBにバイナリ−を登録する場合は、
Statementではなくて、PreparedStatementを使用するのではないでしょうか?
少なくとも、私はStatementでバイナリを登録するSQLを書けません。
ナスティキャット
常連さん
会議室デビュー日: 2004/03/03
投稿数: 24
投稿日時: 2004-03-26 13:48
takuさん返信ありがとうございます。
コード:
	public int executeUpdate(String strSql) {
		try {
			Statement state = con_.prepareStatement(strSql);
			ResultSet rs = state.executeQuery(strSql);
			rs.close();
			state.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return 0;
		}
		return 1;
	}


と現在のexecuteUpdateメソッドを使っていますが、PreparedStatementを使用する場合、SQLを送った後に、setStringメソッドやsetBinaryStreamをやらなければなりませんよね?
これをやるためにはDBにアクセスするクラスにConnectionを確立して返すメソッドを作ったほうが良いのでしょうか?このメソッド自体を書き換えたほうが良いのでしょうか?
どちらのほうが効率が良いのでしょう?
でゅうく
大ベテラン
会議室デビュー日: 2003/11/30
投稿数: 129
投稿日時: 2004-03-26 13:52
こんなんでどうですか?

コード:

byte[] bytes =

〜省略

String sql = "INSERT INTO "
+ "images(filename, image) ")
+ "VALUES(?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, filename);
statement.setBinaryStream(2, new ByteArrayInputStream(bytes), bytes.length);



〔追記〕
ご理解されていたようで・・・。
失礼致しました。

[ メッセージ編集済み 編集者: でゅうく 編集日時 2004-03-26 13:55 ]
taku
ぬし
会議室デビュー日: 2002/11/12
投稿数: 918
お住まい・勤務地: 墨田区→中野区
投稿日時: 2004-03-26 14:29
引用:

ナスティキャットさんの書き込み (2004-03-26 13:48) より:
takuさん返信ありがとうございます。
コード:
	public int executeUpdate(String strSql) {
		try {
			Statement state = con_.prepareStatement(strSql);
			ResultSet rs = state.executeQuery(strSql);
			rs.close();
			state.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return 0;
		}
		return 1;
	}


と現在のexecuteUpdateメソッドを使っていますが、PreparedStatementを使用する場合、SQLを送った後に、setStringメソッドやsetBinaryStreamをやらなければなりませんよね?
これをやるためにはDBにアクセスするクラスにConnectionを確立して返すメソッドを作ったほうが良いのでしょうか?このメソッド自体を書き換えたほうが良いのでしょうか?
どちらのほうが効率が良いのでしょう?


 「Connectionを確立して返すメゾット」と今回の件と無関係な気が・・・。
まあ、私はそういったメゾットを用意してますけど。

 少なくとも、私ならPreparedStatementを使用する場合、
SQLをセットするメゾットと、SQLを実行するメゾットを一緒にはしません。
こうしてしまうと、PreparedStatementを使用する意味が減ります。
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2004-03-26 14:49
永井です。

素朴な疑問なんですが、仮に上手く展開してSQL文にバイナリを貼り付けられたと仮定して、それってDBの接続部分で文字コード変換フィルタが悪さしないでしょうか?
個人的には、普通にStreamから流し込む方が安定な気がします……。
#今のDBアクセスクラスの方針をあまり変えたくないのであれば、SQLと一緒にバイナリデータへの参照を渡せるようなインターフェースを追加して、その内部でバインド&流し込みを行うとかでしょう
<追記>
何が何でも全部#setXXXで値を渡さなければいけないというわけでもないですから、バイナリを渡したい場合だけ当該部分を「?」にしておいて、受け側で流し込み用のStreamだけをバインドするというような方向性でいいのではないかと思います。
#で、基本的には動的SQL生成と
</追記>

---

以下、余談。(最近余談ばっかだ……)

ナスティキャットさんのコード、ずいぶんとCライクな書き方ですね、はこの際置いておくとして。

引用:

コード:

Statement state = con_.prepareStatement(strSql);
ResultSet rs = state.executeQuery(strSql);





このコードは、どちらのSQL文が使われるんでしょう?
#たまたまどちらも同じ文字列への参照を渡しているので気になってないのかも知れませんが……



[ メッセージ編集済み 編集者: 永井和彦 編集日時 2004-03-26 14:54 ]
ナスティキャット
常連さん
会議室デビュー日: 2004/03/03
投稿数: 24
投稿日時: 2004-03-26 18:20
すいません。コードに一部誤りがありました。

コード:
Statement state = con_.prepareStatement(strSql);


は実際には
コード:
Statement state = con_.getStatement();


となっていました。

余談:Cライクなのは、初めて触った言語がCだったためと思われます。
porcupine
会議室デビュー日: 2004/03/28
投稿数: 1
投稿日時: 2004-03-28 23:40
はじめまして。

どうしても文字列としてSQLを組み立てたいなら、MySQLの場合
「"0x" + 16進ダンプ」の形式でバイナリデータを埋め込めます。

とはいうものの、MySQLへの依存度が高くなりますので、
特に理由が無ければPreparedStatementを使用する方をお勧めします。

ちなみに現行の安定版MySQLはサーバサイドでのSQLのプリコンパイルは、
まだサポートしていません。(α版ではサポート。)

con.prepareStatement(), setXXX()はJDBCドライバ内で完結した処理、
ということになります。

スキルアップ/キャリアアップ(JOB@IT)