내 동료가 Mybatis를 공부할 때, 그는 Char Type 필드를 쿼리 조건으로 사용할 때 데이터를 찾을 수 없었고 다른 유형의 괜찮은 문제를 겪었습니다.
사용 된 데이터베이스는 Oracle이고 쿼리 조건 필드 유형은 char (50)이며 Java 코드는 문자열 유형에 해당합니다.
나중에 문제 해결 후, Oracle에서는 숯 유형 필드의 내용 길이가 충분하지 않으면 길이가 공간 형태로 자동으로 채워지기 때문입니다. 필드 이름 char (5) 인 경우 값이 SGL 인 경우 Oracle은 자동으로 길이를 공백으로 채우고 최종 값은 SGL입니다.
1. 해결책 :
방법 1 : 먼저 trim () 함수를 사용하여 값의 양쪽의 공간을 제거한 다음 다음과 같은 조건부 쿼리로 사용합니다.
Data.Name =#{name}에서 *에서 * 선택 *변경 :
trim (data.name) =#{name}에서 * 선택 * 선택방법 2 : 필드 유형 char ()를 varchar2 () 유형으로 변경합니다. 일반적으로, char () 유형은 모든 값의 길이가 같은 경우에만 사용됩니다. 예를 들어, 성 필드가 남성을 나타내는 데 사용되고 1은 여성을 나타내는 데 사용되면 숯 (1)을 사용할 수 있습니다. 값의 길이가 고정되지 않은 경우 길고 짧으므로 char () 유형을 사용하지 않는 것이 가장 좋습니다.
2. Mybatis가 Null을 깊이 이해합니다
MyBatis 프레임 워크를 제쳐두고 원래 JDBC 쿼리로 돌아가서 Oracle 유형을 데이터를 쿼리하기위한 조건으로 사용할 때 값이 정확히 동일 할 때만 데이터를 찾을 수 있습니다.
예를 들어, 테스트 테이블을 만듭니다.
테이블 t_user (user_name char (5)); t_user (user_name) 값 ( 'sgl')에 삽입;
select '"'||user_name||'"' from t_user . - 쿼리 결과는 "SGL"입니다. Oracle은 두 개의 공간을 자동으로 채우는 것을 볼 수 있습니다.
JDBC의 PrepactionStatement 방법을 통한 쿼리 데이터 :
conn = getConnection (); ps = conn.preparestatement ( "user_name =?"); ps.setString (1, "sgl"); resultSet rs = ps.ExecuteQuery ();
쿼리 조건 값 "SGL"및 데이터베이스 값 "SGL"이 같지 않기 때문에 위의 방법을 통해 데이터를 찾을 수 없습니다.
값이 "SGL"인 경우 데이터를 찾을 수 있습니다.
conn = getConnection (); ps = conn.preparestatement ( "select *에서 user_name =?"); ps.setString (1, "sgl"); - 길이가 5 비트 미만인 두 개의 공백을 추가 결과 세트 rs = ps.ExecuteQuery ();
Trim () 메소드를 사용하는 경우 다음과 같은 데이터를 쿼리 할 수도 있습니다.
conn = getConnection (); ps = conn.preparestatement ( "trim (user_name) =?"); - 먼저 데이터베이스에서 user_name을 비애 한 다음 ps.SetString (1, "sgl"); resultSet rs = ps.ExecuteQuery ();
이제 Mybatis로 돌아가서 동료의 Mapper 파일은 다음과 같습니다.
<select id = "selectByName"resultType = "com.entity.data"ParameterType = "java.lang.string"> select * data.name =#{name} </select>주요 방법 내용은 다음과 같습니다.
public static void main (string [] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext ( "ApplicationContext.xml"); DataService d = (dataService) ctx.getBean ( "dataServiceImpl"); 데이터 데이터 = d.selectbyName ( "sgl"); System.out.println (데이터);}실제로 소스 코드를 보거나 로그를 디버그 레벨로 변경하면 MyBatis의 하단에서 쿼리 문이 준비된 상태를 사용하여 사전 컴파일되고 매개 변수가 설정됩니다. 다음과 같이 MyBatis가 인쇄 한 로그를 인쇄합니다.
==> 준비 : 데이터에서 *를 선택하십시오.
==> 매개 변수 : sgl (문자열)
이전 JDBC 쿼리를 기반으로 그 이유를 알기 때문에 Mybatis의 문제를 쉽게 이해하기 쉽습니다.
또한 MySQL에서 숯 유형 필드의 값이 충분하지 않은 경우 값이 자동으로 공간으로 채워지지 않은 것 같습니다. 그럼에도 불구하고 값 길이가 고정되지 않은 경우 숯 유형을 사용하는 것이 좋습니다.
JDBC 쿼리의 전체 코드는 다음과 같습니다.
JDBC 도구 클래스 :
패키지 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.sqlection; java.sql.sqlection; java.util.arraylist; import java.util.list; import java.util.resourcebundle;/** * Pure JDBC 연결 데이터 클래스 * @Author SGL * */public class pureJDBCDAO {private static resourceBundle Bundle = ResourceBundle.getBundle ( "JDBC"); 개인 정적 int Recount = 0; / *** 연결을 가져옵니다* @return*/ private static connection getConnection () {Connection conn = null; try {class.forname (bundle.getString ( "driver className")); conn = drivermanager.getConnection (bundle.getString ( "url"), bundle.getString ( "username"), bundle.getString ( "password")); } catch (classNotFoundException e) {e.printstacktrace (); } catch (sqlexception e) {e.printstacktrace (); } 마침내 {if (null == conn && recount <5) {try {thread.sleep (10000); } catch (InterruptedException e) {e.printstacktrace (); } Recount ++; System.out.println ( "데이터베이스"+Recount+"Second Reconnect"); conn = getConnection (); }} return conn; } / ** * query data * @param sql * @return * / public static list <string []> query (string sql) {list <string []> result = new arraylist <string []> (); 연결 Conn = null; 문자 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 (); 문자열 [] 필드 = 새 문자열 [columnNum]; 문자열 fieldValue = null; for (int i = 1; i <= columnNum; i ++) {fieldValue = rs.getString (i); if (fieldValue == null) {fieldValue = ""; } 필드 [i-1] = FieldValue; } result.add (필드); }} catch (sqlexception e) {e.printstacktrace (); } 마침내 {try {if (stmt! = null) {stmt.close (); } if (conn! = null) {conn.close (); }} catch (sqlexception e) {e.printstacktrace (); }} 반환 결과; } public static list <string []> query (문자열 sql, list <string> params) {list <string []> result = new arraylist <string []> (); 연결 Conn = null; 준비된 상태 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 (); 문자열 [] 필드 = 새 문자열 [columnNum]; 문자열 fieldValue = null; for (int i = 1; i <= columnNum; i ++) {fieldValue = rs.getString (i); if (fieldValue == null) {fieldValue = ""; } 필드 [i-1] = FieldValue; } result.add (필드); }} catch (sqlexception e) {e.printstacktrace (); } 마침내 {try {if (ps! = null) {ps.close (); } if (conn! = null) {conn.close (); }} catch (sqlexception e) {e.printstacktrace (); }} 반환 결과; } / ** * SQL 문을 실행 * @param sql * / public static void execute (String SQL) {Connection Conn = null; 문자 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 (); } 마침내 {try {if (stmt! = null) {stmt.close (); } if (conn! = null) {conn.close (); }} catch (sqlexception e) {e.printstacktrace (); }}}}테스트 클래스 :
패키지 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] {rempurejdbcdao.cuery whenuer whenser whenser whense user_name =? ", arrays.aslist ("sgl ")); // 항목의 수 : 0 //list<String]]> user_name =? ", arrays.aslist ("sgl "))에서 t_user에서 from t_user에서 from t_user에서 * list=purejdbcdao.query (”); // 항목 수를 쿼리합니다. 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 Type 필드를 사용하여 Oracle 데이터베이스를 쿼리 할 때 NULL 문제를 해결하기 위해 편집기가 소개 한 솔루션입니다. 모든 사람에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 모든 사람에게 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!