Quando meu colega estudava Mybatis, ele encontrou um problema de que, ao usar o campo do tipo Char como condição de consulta, ele não conseguiu encontrar os dados e outros tipos deles estavam bem.
O banco de dados usado é o Oracle, o tipo de campo da condição de consulta é char (50) e o código Java corresponde ao tipo de string.
Posteriormente, após a investigação, foi porque no Oracle, se o comprimento do conteúdo do campo do tipo de char não for suficiente, o comprimento será automaticamente preenchido no espaço. Se o nome do campo Char (5), se o valor for SGL, o Oracle preencherá automaticamente o comprimento com espaços e o valor final será SGL.
1. Solução:
Método 1: primeiro use a função TRIM () para remover os espaços em ambos os lados do valor e depois use -o como uma consulta condicional, como:
Selecione * FROM dados onde data.name =#{nome}Mudar para:
Selecione * FRO
Método 2: Altere o tipo de campo char () para varchar2 () tipo. De um modo geral, o tipo de char () é usado apenas quando todos os valores têm o mesmo comprimento. Por exemplo, quando o campo de gênero é usado para representar masculino e 1 é usado para representar feminino, o char (1) pode ser usado. Se o comprimento do valor não for fixo, é longo e curto, é melhor não usar o tipo char ().
2. Entenda profundamente Mybatis retorna nulo
Deixando de lado a estrutura Mybatis, de volta à consulta JDBC original, ao usar o tipo de char como uma condição para consultar dados, os dados só podem ser encontrados quando os valores são exatamente os mesmos.
Por exemplo, crie uma tabela de teste:
Criar tabela T_USER (user_name char (5)); inserir em t_user (user_name) valores ('sgl'); select '"'||user_name||'"' from t_user ; - O resultado da consulta é "SGL", pode-se ver que o Oracle preenche automaticamente dois espaços
Dados de consulta através do método preparado da JDBC:
Conn = getConnection (); ps = Conn.Preparestatement ("Selecione * de T_USER onde user_name =?"); Ps.SetString (1, "sgl"); ResultSet rs = Ps.executeQuery ();Os dados não podem ser encontrados através do método acima, porque o valor da condição de consulta "SGL" e o valor do banco de dados "SGL" não são iguais.
Se o valor for "SGL", você poderá encontrar os dados:
Conn = getConnection (); ps = Conn.Preparestatement ("Selecione * de T_USER onde user_name =?"); Ps.SetString (1, "SGL"); - Adicione dois espaços com menos de 5 bits no comprimento ResultSet rs = ps.executeQuery ();Se você usar o método TRIM (), também poderá consultar os dados, como:
Conn = getConnection (); ps = Conn.Preparestatement ("Selecione * FROM T_USER WHERE TRIM (user_name) =?"); - Primeiro despace o user_name no banco de dados e, em seguida, compare o PS.SetString (1, "sgl"); ResultSet rs = ps.executeQuery ();Agora, de volta a Mybatis, o arquivo de mapas do colega é o seguinte:
<select id = "selectbyName" resultType = "com.entity.data" parameterType = "java.lang.string"> selecione * de dados onde data.name =#{name} </leclect>O conteúdo principal do método é:
public static void main (string [] args) {ApplicationContext ctx = new ClassPathXMLApplicationContext ("ApplicationContext.xml"); DataService D = (DataService) ctx.getBean ("DataServiceImpl"); Dados de dados = d.SelectByName ("SGL"); System.out.println (dados);}De fato, ao visualizar o código -fonte ou alterar o nível de log para o nível de depuração, pode -se ver que, na parte inferior do mybatis, a declaração de consulta será pré -compilada usando o preparado estatamento e, em seguida, os parâmetros serão definidos. Da seguinte forma, o log impresso por mybatis:
==> Preparação: Selecione * FROM dados onde data.name =?
==> parâmetros: sgl (string)
Com base na consulta JDBC anterior, sabemos o motivo, por isso é fácil entender o problema em Mybatis.
Além disso, em MySQL, quando o valor do campo do tipo de char é insuficiente, parece que o valor não é automaticamente preenchido com espaços. Apesar disso, quando o comprimento do valor não é corrigido, não é recomendável usar o tipo de char.
O código completo para a consulta JDBC é o seguinte:
Classe de ferramentas 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; importar java.util.list; importar java.util.resourcebundle;/** * pura classe de dados de conexão jdbc * @author sgl * */public class Purejdbcdao {private static Resource Bunge = ResourceBun.get.getBLen. private static int recont = 0; / *** Obtenha a conexão* @return*/ conexão estática privada getConnection () {conexão conn = null; tente {Class.ForName (putcle.getString ("DriverClassName")); Conn = DriverManager.getConnection (putadle.getString ("url"), putcle.getString ("nome de usuário"), bundle.getString ("senha")); } catch (classNotFoundException e) {e.printStackTrace (); } catch (sqLexception e) {e.printStackTrace (); } finalmente {if (null == Conn && Recunda <5) {try {thread.sleep (10000); } catch (interruptedException e) {e.printStackTrace (); } recontagem ++; System.out.println ("banco de dados"+recontagem+"Segunda reconexão"); Conn = getConnection (); }} retornar Conn; } / ** * Dados de consulta * @param sql * @return * / list estática pública <string []> query (string sql) {list <string []> resultado = new ArrayList <string []> (); Conexão conn = null; Instrução stmt = null; tente {//system.out.println("purejdbcdao] declaração de consulta: " + 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 = ""; } 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 (); }} Retornar resultado; } Lista estática pública <string []> Query (string sql, list <string> params) {list <string []> resultado = new ArrayList <string []> (); Conexão conn = null; Preparado estatement ps = null; tente {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 = ""; } campo [i-1] = fieldValue; } resultado.add (campo); }} catch (sqLexception e) {e.printStackTrace (); } finalmente {tente {if (ps! = null) {ps.close (); } if (conn! = null) {Conn.Close (); }} catch (sqLexception e) {e.printStackTrace (); }} Retornar resultado; } / ** * Execute a instrução SQL * @param sql * / public static void Execute (string sql) {conexão conn = null; Instrução stmt = null; tente {//system.out.println("purejdbcdao] declaração: " + sql); Conn = getConnection (); Conn.SetAutocomit (false); 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 (); }}}}Classe de teste:
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 ")); // Número de entradas encontradas: 0 //list<STRINGVO> >List=pureJdbcdao.Query("select * de t_user onde user_name =? ", Arrays.aslist (" sgl ")); // consulta o número de entradas: 1 list <string []> list = purejdbcdao.query ("selecione * de t_user where trim (user_name) =?", Arrays.aslist ("sgl")); // Consulta o número de entradas: 1 System.out.println ("Consulte o número de entradas:"+list.size ()); }}Resumir
O exposto acima é a solução introduzida pelo editor para resolver o problema do NULL quando o Mybatis usa o campo Char Type para consultar o banco de dados Oracle. Espero que seja útil para todos. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a todos a tempo. Muito obrigado pelo seu apoio ao site wulin.com!