一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 好大好猛好爽好深视频免费 | 天堂8在线天堂资源在线 | 日本高清在线播放 | 奇米影视7777久久精品 | 三级全黄裸体 | 男女交性特一级 | 国产99视频精品免费视频免里 | 满溢游泳池免费土豪全集下拉版 | 末代皇帝无删减版在线观看 | 国色天香社区视频免费高清在线观看 | 大胆暴露亚洲美女xxxx | ckinese中国男同gay男男 | 国产成人久久精品一区二区三区 | 无限资源在线观看播放 | 亚洲日韩精品欧美一区二区 | 日本javaajax| 奶大逼紧 | 国语刺激对白勾搭视频在线观看 | 国产麻豆精品免费视频 | 99re8在这里只有精品2 | 日韩免费一级片 | 91亚洲专区 | 国内在线观看 | 日韩精品免费一级视频 | 交换朋友夫妇3中文字幕 | 国产成人精品三级在线 | 亚洲www在线 | 日韩精品中文字幕久久 | 亚洲欧美日韩国产一区二区精品 | 欧美大片一区二区 | 久久99国产视频 | 亚洲精品在线播放 | 日本三级欧美三级人妇英文 | 奇米影视久久 | 亚洲视屏在线观看 | 欧美一级片在线视频 | 亚洲好骚综合 | 513热点网深夜影院影院诶 | 奇米影视中文字幕 | 武侠古典久久亚洲精品 | 2022色婷婷综合久久久 |