日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jdbc中如何实现模糊查询

發布時間:2025/5/22 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jdbc中如何实现模糊查询 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

情況如何

再利用jdbc執行sql語句的時候,對于其他的句子的執行沒什么太大的問題:加上占位符,然后設置占位符的值。

但是在模糊查詢的時候,一直都寫不對,這里提供了兩種可選的解決辦法,以供參考。

解決方法

第一種:

String sql = "select studentname, age, phone, address, other from customer"
??????????????? + " where studentname like ? ";
pstmt = conn.prepareStatement(sql);
// 設定參數
pstmt.setString(1, "%" + customername + "%" );???????
// 獲取查詢的結果集???????????
rs = pstmt.executeQuery();

第二種:

百分號直接寫在sql語句中

String sql = "select customercode, customername, phone, address, relationman, other from customer"
??????????????? + " where customername like \"%\"?\"%\" ";
pstmt = conn.prepareStatement(sql);???????????
// 設定參數
pstmt.setString(1, customername);???????
// 獲取查詢的結果集???????????
rs = pstmt.executeQuery();

為什么會這樣?

得研究一下PreparedStatement是如何來處理占位符的。

在PresparedStatement中的setString()方法中有如下的一段代碼:

public void setString(int parameterIndex, String x) throws SQLException {
??? synchronized (checkClosed().getConnectionMutex()) {
??????? // 如果x是空的話,就直接調用另外的方法
??????? if (x == null) {
??????????? setNull(parameterIndex, Types.CHAR);
??????? } else {
??????????? checkClosed();

??????????? // 獲得待插入的字符串的長度
??????????? int stringLength = x.length();

??????????? if (this.connection.isNoBackslashEscapesSet()) {
??????????????? // Scan for any nasty chars

??????????????? // 判斷字符串中是否需要進行轉義的字符
??????????????? boolean needsHexEscape = isEscapeNeededForString(x, stringLength);

??????????????? // 如果x里面沒有需要轉義的字符串
??????????????? if (!needsHexEscape) {
??????????????????? byte[] parameterAsBytes = null;

??????????????????? StringBuilder quotedString = new StringBuilder(x.length() + 2);

??????????????????? // 直接就以字符串的形式加入到串中
??????????????????? quotedString.append('\'');
??????????????????? quotedString.append(x);
??????????????????? quotedString.append('\'');

??????????????????? if (!this.isLoadDataQuery) {
??????????????????????? parameterAsBytes = StringUtils.getBytes(quotedString.toString(), this.charConverter, this.charEncoding,
??????????????????????????????? this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), getExceptionInterceptor());
??????????????????? } else {
??????????????????????? // Send with platform character encoding
??????????????????????? parameterAsBytes = StringUtils.getBytes(quotedString.toString());
??????????????????? }

??????????????????? setInternal(parameterIndex, parameterAsBytes);
??????????????? } else {
??????????????????? byte[] parameterAsBytes = null;

??????????????????? if (!this.isLoadDataQuery) {
??????????????????????? parameterAsBytes = StringUtils.getBytes(x, this.charConverter, this.charEncoding, this.connection.getServerCharset(),
??????????????????????????????? this.connection.parserKnowsUnicode(), getExceptionInterceptor());
??????????????????? } else {
??????????????????????? // Send with platform character encoding
??????????????????????? parameterAsBytes = StringUtils.getBytes(x);
??????????????????? }

??????????????????? setBytes(parameterIndex, parameterAsBytes);
??????????????? }

??????????????? return;
??????????? }

??????????? String parameterAsString = x;
??????????? boolean needsQuoted = true;

??????????? if (this.isLoadDataQuery || isEscapeNeededForString(x, stringLength)) {
??????????????? needsQuoted = false; // saves an allocation later

??????????????? StringBuilder buf = new StringBuilder((int) (x.length() * 1.1));

??????????????? buf.append('\'');

??????????????? //
??????????????? // Note: buf.append(char) is _faster_ than appending in blocks, because the block append requires a System.arraycopy().... go figure...
??????????????? //
??????????????? // 如果需要轉義則遍歷需要轉義的字符
??????????????? for (int i = 0; i < stringLength; ++i) {
??????????????????? char c = x.charAt(i);

??????????????????? switch (c) {
??????????????????????? case 0: /* Must be escaped for 'mysql' */
??????????????????????????? buf.append('\\');
??????????????????????????? buf.append('0');

??????????????????????????? break;

??????????????????????? case '\n': /* Must be escaped for logs */
??????????????????????????? buf.append('\\');
??????????????????????????? buf.append('n');

??????????????????????????? break;

??????????????????????? case '\r':
??????????????????????????? buf.append('\\');
??????????????????????????? buf.append('r');

??????????????????????????? break;

??????????????????????? case '\\':
??????????????????????????? buf.append('\\');
??????????????????????????? buf.append('\\');

??????????????????????????? break;

??????????????????????? case '\'':
??????????????????????????? buf.append('\\');
??????????????????????????? buf.append('\'');

??????????????????????????? break;

??????????????????????? case '"': /* Better safe than sorry */
??????????????????????????? if (this.usingAnsiMode) {
??????????????????????????????? buf.append('\\');
??????????????????????????? }

??????????????????????????? buf.append('"');

??????????????????????????? break;

??????????????????????? case '\032': /* This gives problems on Win32 */
??????????????????????????? buf.append('\\');
??????????????????????????? buf.append('Z');

??????????????????????????? break;

??????????????????????? case '\u00a5':
??????????????????????? case '\u20a9':
??????????????????????????? // escape characters interpreted as backslash by mysql
??????????????????????????? if (this.charsetEncoder != null) {
??????????????????????????????? CharBuffer cbuf = CharBuffer.allocate(1);
??????????????????????????????? ByteBuffer bbuf = ByteBuffer.allocate(1);
??????????????????????????????? cbuf.put(c);
??????????????????????????????? cbuf.position(0);
??????????????????????????????? this.charsetEncoder.encode(cbuf, bbuf, true);
??????????????????????????????? if (bbuf.get(0) == '\\') {
??????????????????????????????????? buf.append('\\');
??????????????????????????????? }
??????????????????????????? }
??????????????????????????? // fall through

??????????????????????? default:
??????????????????????????? buf.append(c);
??????????????????? }
??????????????? }

??????????????? buf.append('\'');

??????????????? parameterAsString = buf.toString();
??????????? }

??????????? byte[] parameterAsBytes = null;

??????????? if (!this.isLoadDataQuery) {
??????????????? if (needsQuoted) {
??????????????????? parameterAsBytes = StringUtils.getBytesWrapped(parameterAsString, '\'', '\'', this.charConverter, this.charEncoding,
??????????????????????????? this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), getExceptionInterceptor());
??????????????? } else {
??????????????????? parameterAsBytes = StringUtils.getBytes(parameterAsString, this.charConverter, this.charEncoding, this.connection.getServerCharset(),
??????????????????????????? this.connection.parserKnowsUnicode(), getExceptionInterceptor());
??????????????? }
??????????? } else {
??????????????? // Send with platform character encoding
??????????????? parameterAsBytes = StringUtils.getBytes(parameterAsString);
??????????? }

??????????? setInternal(parameterIndex, parameterAsBytes);

??????????? this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.VARCHAR;
??????? }
??? }
}

protected final void setInternal(int paramIndex, byte[] val) throws SQLException {
??? synchronized (checkClosed().getConnectionMutex()) {

??????? int parameterIndexOffset = getParameterIndexOffset();

??????? checkBounds(paramIndex, parameterIndexOffset);

??????? this.isStream[paramIndex - 1 + parameterIndexOffset] = false;
??????? this.isNull[paramIndex - 1 + parameterIndexOffset] = false;
??????? this.parameterStreams[paramIndex - 1 + parameterIndexOffset] = null;
??????? this.parameterValues[paramIndex - 1 + parameterIndexOffset] = val;
??? }
}

在setString()方法中,字符串會變為\'string\'的這種形式插入。

第一種方法可以成功比較好理解一些,但是第二種就有點想不通了。這里從源代碼看出一點端倪就是會判斷字符串中有沒有轉義字符,而且還會判斷字符串需不需要被括起來。現就了解了這些,有空再深鉆。

轉載于:https://www.cnblogs.com/tuhooo/p/6181623.html

總結

以上是生活随笔為你收集整理的jdbc中如何实现模糊查询的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。