my batis 가 char 형식 필드 를 사용 하여 Oacle 데이터 베 이 스 를 조회 할 때 결 과 는 null 문 제 를 되 돌려 줍 니 다.

9617 단어 mybatisOaclechar
동료 가 my batis 를 배 울 때 문 제 는 char 형식 필드 를 조회 조건 으로 사용 할 때 데 이 터 를 찾 지 못 하고 다른 유형 은 가능 하 다 는 것 이다.
 사용 하 는 데이터 베 이 스 는 Oacle 이 고 조회 조건 필드 유형 은 char(50)이 며 자바 코드 는 String 형식 에 대응 합 니 다.
 나중에 검 사 를 통 해 Oacle 에서 char 형식 필드 가 내용 길이 가 부족 하면 자동 으로 빈 칸 으로 길 이 를 보충 하기 때 문 입 니 다.필드 name char(5)와 같이 값 이 sgl 이면 Oacle 은 자동 으로 빈 칸 으로 길 이 를 보충 하고 최종 값 은 sgl 입 니 다.
1.해결 방법:
 방법 1:먼저 trim()함수 로 값 을 양쪽 빈 칸 을 제거 한 다음 조건 으로 조회 합 니 다.예 를 들 어:

select * from data where data.name=#{name}
다음으로 변경:

select * from data where trim(data.name)=#{name}
방법 2:필드 형식 char()를 varchar 2()형식 으로 바 꿉 니 다.일반적으로 모든 값 의 길이 가 같 을 때 만 char()유형 을 사용 합 니 다.예 를 들 어 성별 필드 는 0 으로 남자 와 1 로 여 자 를 표시 할 때 char(1)를 사용 할 수 있 습 니 다.만약 에 값 의 길이 가 고정 되 지 않 고 길 고 짧 으 면 char()유형 을 사용 하지 않 는 것 이 좋 습 니 다.
2.my batis 를 깊이 이해 하고 null 로 돌아 가기
my batis 프레임 워 크 를 버 리 고 원본 jdbc 로 돌아 가 조회 합 니 다.Oacle 의 char 형식 을 조건 으로 데 이 터 를 조회 할 때 값 이 똑 같 을 때 만 데 이 터 를 찾 을 수 있 습 니 다.
 테스트 표를 만 들 면:

create table t_user(
    user_name char(5)
);
insert into t_user (user_name)values('sgl');
select '"'||user_name||'"' from  t_user ; -- 검색 결 과 는"sgl"입 니 다.  ",Oacle 이 자동 으로 두 개의 빈 칸 을 채 웠 음 을 알 수 있 습 니 다.
jdbc 의 Prepared Statement 방식 으로 데 이 터 를 조회 합 니 다.

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();
현재 my batis 로 돌아 가 동료의 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 단계 로 바 꾸 면 my batis 밑 에 있 음 을 알 수 있 습 니 다.검색 어 를 Prepared Statement 으로 미리 컴 파일 한 다음 에 파 라 메 터 를 설정 합 니 다.아래 와 같이 my batis 가 인쇄 한 로그 입 니 다:
==> Preparing: select * from data where data.name=?
==> Parameters: sgl(String)
앞의 jdbc 조회 에 따 르 면 우 리 는 원인 을 알 고 있 기 때문에 my batis 의 문 제 를 쉽게 이해 할 수 있 습 니 다.
또한,my sql 아래 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());
  }
}
총결산
위 에서 말 한 것 은 마 이 바 티 스 가 char 형식 필드 를 사용 하여 Oacle 데이터 베 이 스 를 조회 할 때 결 과 는 null 문 제 를 되 돌려 주 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기