Lorsque mon collègue étudiait Mybatis, il a rencontré un problème que lors de l'utilisation du champ de type char comme condition de requête, il n'a pas pu trouver les données, et d'autres types d'entre eux étaient OK.
La base de données utilisée est Oracle, le type de champ de condition de requête est char (50) et le code Java correspond au type de chaîne.
Plus tard, après le dépannage, c'était parce que dans Oracle, si la longueur du contenu du champ de type char ne suffit, la longueur sera automatiquement remplie de la forme de l'espace. Si le nom de champ Char (5), si la valeur est SGL, alors Oracle remplira automatiquement la longueur d'espaces et que la valeur finale est SGL.
1. Solution:
Méthode 1: Utilisez d'abord la fonction TRIM () pour éliminer les espaces des deux côtés de la valeur, puis l'utiliser comme requête conditionnelle, telle que:
Sélectionnez * dans les données où data.name = # {nom}Passer à:
Sélectionnez * dans les données où TRIM (data.name) = # {nom}Méthode 2: Modifiez le type de champ char () en VARCHAR2 (). D'une manière générale, le type Char () n'est utilisé que lorsque toutes les valeurs ont la même longueur. Par exemple, lorsque le champ de genre est utilisé pour représenter les mâles et que 1 est utilisé pour représenter les femmes, le char (1) peut être utilisé. Si la longueur de la valeur n'est pas fixe, elle est longue et courte, il est préférable de ne pas utiliser le type char ().
2. Comprendre profondément que Mybatis revient nul
En mettant de côté le framework MyBatis, retour à la requête JDBC d'origine, lors de l'utilisation du type d'oracle char comme condition pour requérir des données, les données ne peuvent être trouvées que lorsque les valeurs sont exactement les mêmes.
Par exemple, créez un tableau de test:
créer la table t_user (user_name char (5)); insérer dans t_user (user_name) valeurs ('sgl'); select '"'||user_name||'"' from t_user ; - Le résultat de la requête est "SGL", on peut voir qu'Oracle remplit automatiquement deux espaces
Données de requête via la méthode de préparation de JDBC:
Conn = getConnection (); ps = conn.prepareStatement ("SELECT * FROM T_USER WHERE USER_NAME =?"); Ps.SetString (1, "SGL"); ResultSet rs = ps.ExecuteQuery ();Les données ne peuvent pas être trouvées via la méthode ci-dessus, car la valeur de la condition de requête "SGL" et la valeur de la base de données "SGL" ne sont pas égales.
Si la valeur est "SGL", vous pouvez trouver les données:
Conn = getConnection (); ps = conn.prepareStatement ("SELECT * FROM T_USER WHERE USER_NAME =?"); Ps.SetString (1, "SGL"); - Ajouter deux espaces inférieurs à 5 bits de longueur ResultSet RS = ps.ExecuteQuery ();Si vous utilisez la méthode TRIM (), vous pouvez également interroger les données, telles que:
Conn = getConnection (); ps = conn.prepareStatement ("SELECT * FROM T_USER WHERE TRIM (USER_NAME) =?"); - Dépacez d'abord le nom de l'utilisateur dans la base de données, puis comparez Ps.SetString (1, "SGL"); resultSet rs = ps.ExecuteQuery ();Maintenant de retour à Mybatis, le fichier de mappeur du collègue est le suivant:
<select id = "selectByname" resultType = "com.entity.data" paramètreType = "java.lang.string"> select * from data où data.name = # {name} </lect>Le contenu de la méthode principale est:
public static void main (String [] args) {applicationContext ctx = new ClassPathxmlApplicationContext ("ApplicationContext.xml"); DataService d = (dataService) ctx.getBean ("dataServiceImpl"); Données de données = D.SelectByName ("SGL"); System.out.println (données);}En fait, en visualisant le code source ou en modifiant le niveau du journal en termes de débogage, on peut voir qu'au bas de MyBatis, l'instruction de requête sera précompilée à l'aide de PreadStatement, puis les paramètres seront définis. Comme suit, le journal imprimé par Mybatis:
==> Préparation: sélectionnez * dans les données où data.name =?
==> Paramètres: SGL (String)
Sur la base de la requête JDBC précédente, nous connaissons la raison, il est donc facile de comprendre le problème dans MyBatis.
De plus, sous MySQL, lorsque la valeur du champ de type char est insuffisante, il semble que la valeur ne soit pas automatiquement remplie d'espaces. Malgré cela, lorsque la longueur de valeur n'est pas fixe, il n'est pas recommandé d'utiliser le type de char.
Le code complet de la requête JDBC est le suivant:
Classe d'outils JDBC:
package com.songguoliang.url; import java.sql.connection; import java.sql.drivermanager; import java.sql.preparedstatement; import java.sql.resultTset; import java.sql.resultMetadata; import java.sql.sqexception; java.util.arraylist; Importer java.util.list; import java.util.resourcebundle; / ** * pure jdbc de connexion Classe de données * @author sgl * * / public class purejdbcdao {private static ResourceBundle bundle = ResourceBundle.getBundle ("jdbc"); RECOURS INT STATIQUE PRIVÉ = 0; / ** * Obtenez la connexion * @return * / connexion statique privée getConnection () {connexion conn = null; try {class.forname (bundle.getString ("DriverClassName")); Conn = driverManager.getConnection (bundle.getString ("url"), bundle.getString ("username"), bundle.getString ("mot de passe")); } catch (classNotFoundException e) {e.printStackTrace (); } catch (sqlexception e) {e.printStackTrace (); } enfin {if (null == Conn && recompouche <5) {try {Thread.Sleep (10000); } catch (InterruptedException e) {e.printStackTrace (); } recomptage ++; System.out.println ("base de données" + recomptage + "Deuxième reconnect"); Conn = getConnection (); }} return conn; } / ** * Données de requête * @param sql * @return * / public static list <String []> Query (String sql) {list <String []> result = new ArrayList <String []> (); Connexion conn = null; Déclaration stmt = null; Essayez {//system.out.println("@purejdbcdao] Instruction de requête: "+ sql); Conn = getConnection (); STMT = Conn.CreateStatement (); ResultSet rs = stmt.ExecuteQuery (SQL); ResultSetMetAdata rsmeta = Rs.GetMetAdata (); while (Rs.Next ()) {int colnnnum = rsmeta.getColumnCount (); String [] field = new String [ColumnNum]; String fieldValue = null; for (int i = 1; i <= colnumnnum; i ++) {fieldValue = Rs.getString (i); if (fieldvalue == null) {fieldvalue = ""; } field [i-1] = fieldvalue; } result.add (champ); }} catch (sqlexception e) {e.printStackTrace (); } enfin {try {if (stmt! = null) {stmt.close (); } if (conn! = null) {conn.close (); }} catch (sqlexception e) {e.printStackTrace (); }} Retour Résultat; } public static list <string []> requête (String sql, list <string> params) {list <string []> result = new ArrayList <String []> (); Connexion conn = null; PréparedStatement PS = null; essayez {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 colnnnum = rsmeta.getColumnCount (); String [] field = new String [ColumnNum]; String fieldValue = null; for (int i = 1; i <= colnumnnum; i ++) {fieldValue = Rs.getString (i); if (fieldvalue == null) {fieldvalue = ""; } field [i-1] = fieldvalue; } result.add (champ); }} catch (sqlexception e) {e.printStackTrace (); } enfin {try {if (ps! = null) {ps.close (); } if (conn! = null) {conn.close (); }} catch (sqlexception e) {e.printStackTrace (); }} Retour Résultat; } / ** * EXECUTE SQL Instruction * @param sql * / public static void execute (String sql) {connection Conn = null; Déclaration stmt = null; Essayez {//system.out.println("@purejdbcdao 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 (); } enfin {try {if (stmt! = null) {stmt.close (); } if (conn! = null) {conn.close (); }} catch (sqlexception e) {e.printStackTrace (); }}}}Classe de test:
package com.songguoliang; import java.util.arrays; import java.util.list; import com.songguoliang.url.purejdbcdao; test public test {public static void Main (String [] args) {//list<string fichon user_name =? ", arrays.aslist (" sgl ")); // Nombre d'entrées trouvées: 0 //List<String · LALD>list=purejdbcdao.Query("Select * de t_user où user_name =? ", Arrays.aslist (" sgl ")); // requête le nombre d'entrées: 1 liste <string []> list = purejdbcdao.query ("select * from t_user où trim (user_name) =?", Arrays.aslist ("sgl")); // interroge le nombre d'entrées: 1 System.out.println ("Requête le nombre d'entrées:" + list.size ()); }}Résumer
Ce qui précède est la solution introduite par l'éditeur pour résoudre le problème de Null lorsque MyBatis utilise le champ de type char pour interroger la base de données Oracle. J'espère que ce sera utile à tout le monde. Si vous avez des questions, veuillez me laisser un message et l'éditeur répondra à tout le monde à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!