国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

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

2024-07-14 08:41:14
字體:
來源:轉載
供稿:網友

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

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

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

一、解決方法:

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

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

改為:

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

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

二、深入了解mybatis返回null

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

 如創建一個測試表:

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方式查詢數據:

conn=getConnection();ps=conn.prepareStatement("select * from t_user where user_name=?");ps.setString(1,"sgl");ResultSet rs = ps.executeQuery();

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

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

conn=getConnection();ps=conn.prepareStatement("select * from t_user where user_name=?");ps.setString(1,"sgl "); -- 增加兩個空格不足5位長度ResultSet rs = ps.executeQuery();

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

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如下:

<select id="selectByName" resultType="com.entity.Data" parameterType="java.lang.String"> select * from data where data.name=#{name}</select>

main方法內容為:

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工具類:

 

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();      }    }  }}

測試類:

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問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 三台县| 桐柏县| 延寿县| 蛟河市| 屏南县| 保德县| 梁河县| 肇源县| 南雄市| 淅川县| 横山县| 江达县| 新安县| 台中市| 济宁市| 高清| 明溪县| 眉山市| 循化| 北流市| 华亭县| 固原市| 新干县| 酒泉市| 黑河市| 梁平县| 平定县| 克拉玛依市| 建湖县| 郯城县| 广安市| 大竹县| 陆河县| 德江县| 滦南县| 故城县| 赫章县| 河东区| 陈巴尔虎旗| 章丘市| 靖边县|