激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - 解決mybatis使用char類型字段查詢oracle數據庫時結果返回null問題

解決mybatis使用char類型字段查詢oracle數據庫時結果返回null問題

2021-05-09 12:14曾衛 Java教程

這篇文章主要介紹了mybatis使用char類型字段查詢oracle數據庫時結果返回null問題的解決方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

同事在學mybatis時,遇到了一個問題就是,使用char類型字段作為查詢條件時一直都查不出數據,其他類型的則可以。

 使用的數據庫是oracle,查詢條件字段類型是char(50),java代碼對應的是string類型。

 后來經過排查,是由于在oracle中,char類型字段,如果內容長度不夠,會自動以空格方式補足長度。如字段 name char(5),若值為sgl,那么oracle會自動用空格補足長度,最終值為sgl。

一、解決方法:

 方法1:先用trim()函數把值去掉兩邊空格再作為條件查詢,如:

?
1
select * from data where data.name=#{name}

改為:

?
1
select * from data where trim(data.name)=#{name}

方法2:將字段類型char()改為varchar2()類型。一般情況下,只有所有值長度都一樣時才用char()類型,比如性別字段,用0表示男和1表示女時,就可以用char(1),如果值的長度不固定,有長有短,最好別用char()類型。

二、深入了解mybatis返回null

拋開mybatis框架,回到原始的jdbc查詢,當使用oracle的char類型作為條件查詢數據時,只有值完全一樣時才能查到數據。

 如創建一個測試表:

?
1
2
3
4
create table t_user(
    user_name char(5)
);
insert into t_user (user_name)values('sgl');

select '"'||user_name||'"' from  t_user; -- 查詢結果為"sgl  ",可以看出oracle自動補了兩個空格

通過jdbc的preparedstatement方式查詢數據:

?
1
2
3
4
conn=getconnection();
ps=conn.preparestatement("select * from t_user where user_name=?");
ps.setstring(1,"sgl");
resultset rs = ps.executequery();

通過上面方式是無法查到數據的,因為查詢條件值”sgl”和數據庫中值”sgl “是不相等的。

 如果值用“sgl ”可以查到數據:

?
1
2
3
4
conn=getconnection();
ps=conn.preparestatement("select * from t_user where user_name=?");
ps.setstring(1,"sgl "); -- 增加兩個空格不足5位長度
resultset rs = ps.executequery();

如果使用trim()方式也可以查詢到數據,如:

?
1
2
3
4
conn=getconnection();
ps=conn.preparestatement("select * from t_user where trim(user_name)=?"); -- 先對數據庫中user_name進行去空格,然后再比較
ps.setstring(1,"sgl");
resultset rs = ps.executequery();

現在回到mybatis,同事的mapper文件里查詢sql如下:

?
1
2
3
<select id="selectbyname" resulttype="com.entity.data" parametertype="java.lang.string">
 select * from data where data.name=#{name}
</select>

main方法內容為:

?
1
2
3
4
5
6
7
public static void main(string[] args) {
  applicationcontext ctx = new classpathxmlapplicationcontext("applicationcontext.xml");
  dataservice d = (dataservice) ctx.getbean("dataserviceimpl");
 
  data data = d.selectbyname("sgl");
  system.out.println(data);
}

其實,通過查看源碼或將日志改為debug級別,可以看出在mybatis底層,會將查詢語句使用preparedstatement預編譯,然后再將參數設置進去。如下面是mybatis打印出來的日志:

==> preparing: select * from data where data.name=?
==> parameters: sgl(string)

根據前面的jdbc查詢,我們知道原因,所以很容易理解mybatis中的問題。

另外,mysql下面,當char類型字段的值不足時,好像并不自動將值以空格補足,盡管如此,當值長度不固定時,也不推薦使用char類型。

jdbc查詢完整的代碼如下:

jdbc工具類:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package com.songguoliang.url;
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.list;
import java.util.resourcebundle;
/**
 * 純jdbc連接數據類
 * @author sgl
 *
 */
public class purejdbcdao {
  private static resourcebundle bundle = resourcebundle.getbundle("jdbc");
  private static int recount = 0;
  /**
   * 獲取連接
   * @return
   */
  private static connection getconnection(){
    connection conn=null;
    try {
      class.forname(bundle.getstring("driverclassname"));
      conn = drivermanager.getconnection(bundle.getstring("url") ,
          bundle.getstring("username") , bundle.getstring("password"));
    } catch (classnotfoundexception e) {
      e.printstacktrace();
    } catch (sqlexception e) {
      e.printstacktrace();
    }finally{
      if(null==conn&&recount<5){
        try {
          thread.sleep(10000);
        } catch (interruptedexception e) {
          e.printstacktrace();
        }
        recount++;
        system.out.println("數據庫第"+recount+"次重連");
        conn = getconnection();
      }
    }
    return conn;
  }
  /**
   * 查詢數據
   * @param sql
   * @return
   */
  public static list<string[]>query(string sql){
    list<string[]>result=new arraylist<string[]>();
    connection conn=null;
    statement stmt=null;
    try {
      //system.out.println("[purejdbcdao]查詢語句:" + sql);
      conn=getconnection();
      stmt = conn.createstatement();
      resultset rs = stmt.executequery(sql);
      resultsetmetadata rsmeta = rs.getmetadata();
      while(rs.next()){
        int columnnum=rsmeta.getcolumncount();
        string []field=new string[columnnum];
        string fieldvalue=null;
        for(int i=1;i<=columnnum;i++){
          fieldvalue=rs.getstring(i);
          if(fieldvalue==null){
            fieldvalue="";
          }
          field[i-1]=fieldvalue;
        }
        result.add(field);
      }
    } catch (sqlexception e) {
      e.printstacktrace();
    }finally{
      try {
        if(stmt!=null){
          stmt.close();
        }
        if(conn!=null){
          conn.close();
        }
      } catch (sqlexception e) {
        e.printstacktrace();
      }
    }
    return result;
  }
  public static list<string[]>query(string sql,list<string>params){
    list<string[]>result=new arraylist<string[]>();
    connection conn=null;
    preparedstatement ps=null;
    try {
      conn=getconnection();
      ps=conn.preparestatement(sql);
      for(int i=0;i<params.size();i++){
        ps.setstring(i+1,params.get(i));
      }
      resultset rs = ps.executequery();
      resultsetmetadata rsmeta = rs.getmetadata();
      while(rs.next()){
        int columnnum=rsmeta.getcolumncount();
        string []field=new string[columnnum];
        string fieldvalue=null;
        for(int i=1;i<=columnnum;i++){
          fieldvalue=rs.getstring(i);
          if(fieldvalue==null){
            fieldvalue="";
          }
          field[i-1]=fieldvalue;
        }
        result.add(field);
      }
    } catch (sqlexception e) {
      e.printstacktrace();
    }finally{
      try {
        if(ps!=null){
          ps.close();
        }
        if(conn!=null){
          conn.close();
        }
      } catch (sqlexception e) {
        e.printstacktrace();
      }
    }
    return result;
  }
  /**
   * 執行sql語句
   * @param sql
   */
  public static void execute(string sql){
    connection conn=null;
    statement stmt=null;
    try {
      //system.out.println("[purejdbcdao]sql語句:" + sql);
      conn = getconnection();
      conn.setautocommit(false);
      stmt = conn.createstatement();
      stmt.execute(sql);
      conn.commit();
    } catch (sqlexception e) {
      try {
        conn.rollback();
      } catch (sqlexception e1) {
        e1.printstacktrace();
      }
      e.printstacktrace();
    }finally{
      try {
        if(stmt!=null){
          stmt.close();
        }
        if(conn!=null){
          conn.close();
        }
      } catch (sqlexception e) {
        e.printstacktrace();
      }
    }
  }
}

測試類:

?
1
2
3
4
5
6
7
8
9
10
11
12
package com.songguoliang;
import java.util.arrays;
import java.util.list;
import com.songguoliang.url.purejdbcdao;
public class test {
  public static void main(string[] args) {
    //list<string[]>list=purejdbcdao.query("select * from t_user where user_name=?",arrays.aslist("sgl")); // 查詢到條數:0
    //list<string[]>list=purejdbcdao.query("select * from t_user where user_name=?",arrays.aslist("sgl ")); //查詢到條數:1
    list<string[]>list=purejdbcdao.query("select * from t_user where trim(user_name)=?",arrays.aslist("sgl")); //查詢到條數:1
    system.out.println("查詢到條數:"+list.size());
  }
}

總結

以上所述是小編給大家介紹的解決mybatis使用char類型字段查詢oracle數據庫時結果返回null問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

原文鏈接:https://blog.csdn.net/u014344668/article/details/80664919

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产午夜精品视频免费不卡69堂 | 国产一区二区视频在线播放 | 精品国产一二区 | 91在线视频在线观看 | 欧美一级片在线 | 国产午夜精品久久久久久免费视 | 久久久三级免费电影 | 久草在线观看首页 | 国产色片在线观看 | 91久久国产 | 日日鲁夜夜视频热线播放 | 91短视频在线观看视频 | 国产精品99久久久久久宅女 | 日韩视频在线视频 | 中文字幕免费看 | 一二区成人影院电影网 | 欧美日本综合 | 欧美a∨一区二区三区久久黄 | 亚欧美一区二区 | 久久欧美亚洲另类专区91大神 | 精品国产视频一区二区三区 | 免费黄色在线观看网站 | 性 毛片 | 一级外国毛片 | 成人在线视频免费播放 | 污片在线观看视频 | 999精品国产 | 中文亚洲视频 | 欧美18—19sex性hd按摩 | 国产亚洲精品yxsp | 中文字幕精品久久 | 日本视频在线免费观看 | 13一14毛片免费看 | 二区三区在线观看 | 黄网站色成年大片免费高 | av成人在线播放 | 中文欧美日韩 | 性看小视频 | av免费在线播放网址 | 久久av免费 | 国产日韩亚洲 |