my batis 가 char 형식 필드 를 사용 하여 Oacle 데이터 베 이 스 를 조회 할 때 결 과 는 null 문 제 를 되 돌려 줍 니 다.
사용 하 는 데이터 베 이 스 는 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 문 제 를 되 돌려 주 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
MySQL/마이바티스 | 동적 쿼리 사용A라는 서비스에 해당하는 테이블을 조인하고 조회하는 데 사용됩니다. 나중에 공통화를 위해 B 및 C 서비스도 추가됩니다. A, B, C 서비스는 모두 단일 쿼리에서 작동할 수 있도록 공통화되어야 합니다. 테이블에 각...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.