Cuando mi colega estaba estudiando mybatis, se encontró con un problema de que al usar el campo tipo Char como condición de consulta, no pudo encontrar los datos, y otros tipos de ellos estaban bien.
La base de datos utilizada es Oracle, el tipo de campo de condición de consulta es Char (50) y el código Java corresponde al tipo de cadena.
Más tarde, después de la investigación, fue porque en Oracle, si la longitud de contenido del campo Tipo de char no es suficiente, la longitud se llenará automáticamente en el espacio. Si el nombre de campo Char (5), si el valor es SGL, Oracle llenará automáticamente la longitud con espacios, y el valor final es SGL.
1. Solución:
Método 1: Primero use la función TRIM () para eliminar los espacios en ambos lados del valor y luego úselo como una consulta condicional, como:
Seleccione * de Data Where data.name =#{name}Cambio a:
Seleccione * de Data Where Trim (data.name) =#{name}Método 2: Cambie el tipo de campo Char () al tipo varchar2 (). En términos generales, el tipo de char () se usa solo cuando todos los valores tienen la misma longitud. Por ejemplo, cuando el campo de género se usa para representar el hombre y 1 se usa para representar a la mujer, se puede usar char (1). Si la longitud del valor no es fija, es larga y corta, es mejor no usar el tipo Char ().
2. Entiendo profundamente MyBatis Devuelve nulo
Dejando a un lado el marco mybatis, volviendo a la consulta JDBC original, cuando se usa el tipo de oráculo Char como condición para consultar datos, los datos solo se pueden encontrar cuando los valores son exactamente los mismos.
Por ejemplo, cree una tabla de prueba:
Crear tabla t_user (user_name char (5)); insertar en t_user (user_name) valores ('sgl'); select '"'||user_name||'"' from t_user ; - El resultado de la consulta es "SGL", se puede ver que Oracle llena automáticamente dos espacios
Datos de consulta a través del método preparado de JDBC:
conn = getConnection (); ps = conn.prepareStatement ("Seleccione * de t_user donde user_name =?"); ps.setString (1, "sgl"); resultset rs = ps.exCuteQuery ();Los datos no se pueden encontrar a través del método anterior, porque el valor de la condición de consulta "SGL" y el valor de la base de datos "SGL" no son iguales.
Si el valor es "SGL", puede encontrar los datos:
conn = getConnection (); ps = conn.prepareStatement ("Seleccione * de t_user donde user_name =?"); ps.setString (1, "sgl"); - Agregue dos espacios de menos de 5 bits de longitud de resultados RS = Ps.ExecuteQuery ();Si usa el método TRIM (), también puede consultar los datos, como:
conn = getConnection (); ps = conn.prepareStatement ("Seleccione * de t_user donde TRIM (user_name) =?"); - Primero desprecie el User_Name en la base de datos y luego compare Ps.SetString (1, "SGL"); ResultSet rs = Ps.ExecuteQuery ();Ahora de vuelta a MyBatis, el archivo mapeador del colega es el siguiente:
<select id = "selectbyName" resultType = "com.entity.data" parametertype = "java.lang.string"> Seleccionar * de datos donde data.name =#{name} </select>El contenido del método principal es:
public static void main (string [] args) {applicationContext ctx = new ClassPathXMLApPlicationContext ("ApplicationContext.xml"); DataService d = (DataService) ctx.getBean ("DataServiceImpl"); Datos datos = D.SelectByName ("SGL"); System.out.println (datos);}De hecho, al ver el código fuente o cambiar el registro al nivel de depuración, se puede ver que en la parte inferior de MyBatis, la instrucción de consulta se precompilará usando PrepareStatement, y luego se establecerán los parámetros. Como sigue, el registro impreso por myBatis:
==> Preparación: Seleccionar * de Data Where Data.name =?
==> Parámetros: SGL (String)
Basado en la consulta JDBC anterior, sabemos la razón, por lo que es fácil entender el problema en MyBatis.
Además, en MySQL, cuando el valor del campo Tipo de char es insuficiente, parece que el valor no se llena automáticamente con espacios. A pesar de esto, cuando la longitud del valor no se fija, no se recomienda usar el tipo de char.
El código completo para la consulta JDBC es el siguiente:
Clase de herramienta JDBC:
paquete com.songguoliang.url; import java.sql.connection; import java.sql.drivermanager; import java.sql.preparedStatement; import java.sql.resultSet; import java.sql.resultMetMetMeMen; import java.sql.sqllexception; import java.sqlatement; importación; java.util.arrayList; import java.util.list; import java.util.resourceBundle;/** * clase de datos de conexión pura jdbc * @author sgl * */public class purajdbcdao {private static recurscebundle bundle = recourceBundle.getbundle ("jdbc"); privado estático int Cuott = 0; / *** Obtenga la conexión* @return*/ private Static Connection getConnection () {Connection conn = null; intente {class.forname (Bundle.getString ("DriverClassName")); conn = drivermanager.getConnection (bundle.getString ("url"), bunddle.getString ("username"), bundle.getString ("contraseña")); } catch (ClassNotFoundException e) {E.PrintStackTrace (); } Catch (Sqlexception e) {E.PrintStackTrace (); } Finalmente {if (null == conn && recount <5) {try {thread.sleep (10000); } catch (InterruptedException e) {E.PrintStackTrace (); } Cuenta ++; System.out.println ("Base de datos"+REPORT+"Segundo reconexión"); conn = getConnection (); }} return Conn; } / ** * Datos de consulta * @param sql * @return * / public static list <String []> Query (String Sql) {list <String []> result = new ArrayList <String []> (); Conexión conn = nulo; Instrucción stmt = null; Pruebe la declaración de consulta {//system.out.println("ighpureJdbcdao]: " + sql); conn = getConnection (); stmt = conn.createStatement (); ResultSet rs = stmt.executeQuery (sql); ResultSetMetadata rsmeta = rs.getMetadata (); while (rs.next ()) {int columnnum = rsmeta.getColumnCount (); Cadena [] campo = new String [columnNum]; String FieldValue = NULL; for (int i = 1; i <= columnnum; i ++) {fieldValue = rs.getString (i); if (FieldValue == NULL) {FieldValue = ""; } campo [i-1] = fieldValue; } resultado.Add (campo); }} Catch (SQLException e) {E.PrintStackTrace (); } finalmente {try {if (stmt! = null) {stmt.close (); } if (conn! = null) {conn.close (); }} Catch (SQLException e) {E.PrintStackTrace (); }} Resultado de retorno; } public static list <String []> Query (String SQL, List <String> Params) {List <String []> result = new ArrayList <String []> (); Conexión conn = nulo; Preparado PS = NULL; intente {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 (); Cadena [] campo = new String [columnNum]; String FieldValue = NULL; for (int i = 1; i <= columnnum; i ++) {fieldValue = rs.getString (i); if (FieldValue == NULL) {FieldValue = ""; } campo [i-1] = fieldValue; } resultado.Add (campo); }} Catch (SQLException e) {E.PrintStackTrace (); } finalmente {try {if (ps! = null) {ps.close (); } if (conn! = null) {conn.close (); }} Catch (SQLException e) {E.PrintStackTrace (); }} Resultado de retorno; } / ** * Ejecutar la instrucción SQL * @param sql * / public static void ejecute (string sql) {Connection conn = null; Instrucción stmt = null; Pruebe {//system.out.println("…PureJdbcdaofont>SQL Declaración: " + sql); conn = getConnection (); conn.setAutOcommit (falso); stmt = conn.createStatement (); stmt.execute (SQL); conn.commit (); } catch (sqlexception e) {try {conn.rollback (); } catch (sqlexception e1) {e1.printstackTrace (); } E.PrintStackTrace (); } finalmente {try {if (stmt! = null) {stmt.close (); } if (conn! = null) {conn.close (); }} Catch (SQLException e) {E.PrintStackTrace (); }}}}Clase de prueba:
paquete com.songguoliang; import java.util.arrays; import java.util.list; import com.songguoliang.url.purejdbcdao; public class test {public static void main (string [] string) {//list <string§> list=purejdbcdao.query( general * SELECT user_name =? ", arrays.aslist (" sgl ")); // Número de entradas encontradas: 0 //list<String[font>>List=pureJdbcdao.Query("Select * de t_user donde user_name =? ", Arrays.aslist (" sgl ")); // Consulta el número de entradas: 1 Lista <String []> List = PureJdbcdao.Query ("Seleccione * de T_user donde Trim (user_name) =?", Arrays.aslist ("Sgl")); // Consulta el número de entradas: 1 System.out.println ("Consulta el número de entradas:"+list.size ()); }}Resumir
Lo anterior es la solución introducida por el editor para resolver el problema de NULL cuando MyBatis usa el campo Tipo Char para consultar la base de datos Oracle. Espero que sea útil para todos. Si tiene alguna pregunta, déjame un mensaje y el editor responderá a todos a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!