عندما كان زميلي يدرس MyBatis ، واجه مشكلة أنه عند استخدام حقل نوع Char كشرط استعلام ، لم يستطع العثور على البيانات ، وأنواع أخرى منها كانت على ما يرام.
قاعدة البيانات المستخدمة هي Oracle ، ونوع حقل حالة الاستعلام هو char (50) ، ويتوافق رمز Java مع نوع السلسلة.
في وقت لاحق ، بعد استكشاف الأخطاء وإصلاحها ، كان ذلك لأنه في Oracle ، إذا لم يكن طول المحتوى لحقل نوع Char كافيًا ، فسيتم ملء الطول تلقائيًا في شكل مساحة. إذا كانت اسم الحقل char (5) ، إذا كانت القيمة SGL ، فسوف تملأ Oracle الطول تلقائيًا بالمسافات ، والقيمة النهائية هي SGL.
1. الحل:
الطريقة 1: استخدم أولاً وظيفة trim () لإزالة المسافات على جانبي القيمة ثم استخدامها كاستعلام مشروط ، مثل:
حدد * من البيانات حيث data.name =#{name}التغيير إلى:
حدد * من البيانات التي تقطعها (data.name) =#{name}الطريقة 2: قم بتغيير نوع الحقل char () إلى نوع varchar2 (). بشكل عام ، يتم استخدام نوع char () فقط عندما يكون لجميع القيم نفس الطول. على سبيل المثال ، عند استخدام مجال الجنس لتمثيل الذكور ويتم استخدام 1 لتمثيل الإناث ، يمكن استخدام char (1). إذا لم يتم إصلاح طول القيمة ، فسيكون طويلًا وقصيرًا ، فمن الأفضل عدم استخدام نوع char ().
2. افهم بعمق عودة MyBatis Null
إذا وضعنا جانباً إطار عمل MyBatis ، مرة أخرى إلى استعلام JDBC الأصلي ، عند استخدام نوع char من Oracle كشرط للاستعلام عن البيانات ، لا يمكن العثور إلا على البيانات عندما تكون القيم هي نفسها تمامًا.
على سبيل المثال ، قم بإنشاء جدول اختبار:
إنشاء Table T_USER (user_name char (5)) ؛ insert في قيم t_user (user_name) ('sgl') ؛ select '"'||user_name||'"' from t_user ؛ - نتيجة الاستعلام هي "SGL" ، يمكن ملاحظة أن Oracle يملأ مساحتين تلقائيًا
بيانات الاستعلام من خلال طريقة reparedstatement الخاصة بـ JDBC:
conn = getConnection () ؛ ps = conn.preparestatement ("SELECT * من t_user حيث 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 بتات في الطول 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 () ؛عد الآن إلى MyBatis ، ملف Mapper الخاص بالزميل كما يلي:
<حدد ID = "selectByName" resultType = "com.entity.data" parametertype = "java.lang.string"> SELECT * from data.name =#{name} </rectric>المحتوى الرئيسي هو:
public static void main (string [] args) {applicationContext ctx = new ClassPathxMlAppLicationContext ("ApplicationContext.xml") ؛ DataService d = (DataService) ctx.getBean ("dataserviceImpl") ؛ بيانات البيانات = D.SelectByName ("SGL") ؛ system.out.println (data) ؛}في الواقع ، من خلال عرض الكود المصدري أو تغيير السجل إلى مستوى التصحيح ، يمكن ملاحظة أنه في الجزء السفلي من MyBatis ، سيتم تجهيز بيان الاستعلام باستخدام reparedstatement ، ثم سيتم تعيين المعلمات. على النحو التالي ، السجل المطبوع بواسطة mybatis:
==> التحضير: حدد * من البيانات حيث data.name =؟
==> المعلمات: SGL (سلسلة)
استنادًا إلى استعلام JDBC السابق ، نحن نعرف السبب ، لذلك من السهل فهم المشكلة في MyBatis.
بالإضافة إلى ذلك ، بموجب MySQL ، عندما تكون قيمة حقل نوع Char غير كافية ، يبدو أن القيمة لا يتم ملؤها تلقائيًا بالمسافات. على الرغم من ذلك ، عندما لا يتم إصلاح طول القيمة ، لا ينصح باستخدام نوع char.
الرمز الكامل لاستعلام JDBC هو كما يلي:
فئة أدوات JDBC:
package com.songguoliang.url ؛ import java.sql.connection ؛ استيراد java.sql.drivermanager ؛ استيراد java.sql.preparedstatement ؛ import java.sql.resultset ؛ import java.sql.resultsetmeta ؛ java.util.arraylist ؛ import java.util.list ؛ import java.util.resourceBundle ؛/** * pure jdbc connect data class * uuthor sgl * */public class purejdbcdao {private static resourceBundle backdle = resourceBundle.getBundle ("jdbc") ؛ static int static sreed = 0 ؛ / *** احصل على الاتصال* @RETURN*/ private static connection getConnection () {connection conn = null ؛ حاول {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 () ؛ } أخيرًا {if (null == conn && Recount <5) {try {thread.sleep (10000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } RESOUNT ++ ؛ System.out.println ("Database"+RECONT+"Second Reconnect") ؛ conn = getConnection () ؛ }} return conn ؛ } / ** * بيانات الاستعلام * param sql * return * / قائمة ثابتة عامة <string []> Query (String sql) {list <string []> result = new ArrayList <string []> () ؛ اتصال conn = null ؛ بيان stmt = فارغة ؛ حاول {//system.out.println(" Budappurejdbcdao] بيان الاستعلام: " + sql) ؛ conn = getConnection () ؛ stmt = conn.createstatement () ؛ resultset rs = stmt.executequery (SQL) ؛ resultSetMetAdata rsmeta = rs.getMetAdata () ؛ بينما (rs.next ()) {int columnnum = rsmeta.getColumnCount () ؛ String [] Field = New String [ColumnNum] ؛ سلسلة FieldValue = null ؛ لـ (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 () ؛ }} نتيجة الإرجاع ؛ } القائمة الثابتة العامة <string []> Query (String SQL ، list <string> params) {list <string []> result = new ArrayList <string []> () ؛ اتصال conn = null ؛ أعدت PS = NULL ؛ حاول {conn = getConnection () ؛ ps = conn.preparestatement (SQL) ؛ لـ (int i = 0 ؛ i <params.size () ؛ i ++) {ps.SetString (i+1 ، params.get (i)) ؛ } resultset rs = ps.executequery () ؛ resultSetMetAdata rsmeta = rs.getMetAdata () ؛ بينما (rs.next ()) {int columnnum = rsmeta.getColumnCount () ؛ String [] Field = New String [ColumnNum] ؛ سلسلة FieldValue = null ؛ لـ (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 = فارغة ؛ حاول {//system.out.println (بيان Budappurejdbcdao stuplsql: " + 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 () ؛ }}}}فئة الاختبار:
package com.songguoliang ؛ import java.util.arrays ؛ import java.util.list ؛ import com.songguoliang.url.purejdbcdao ؛ اختبار الطبقة العامة {public static void main (string [] args) {//list<string budban user_name =؟ "، arrays.aslist (" sgl ")) ؛ // عدد الإدخالات الموجودة: 0 //list<string budaper/20slist=purejdbcdao.query("select * from t_user where user_name =؟ "، arrays.aslist (" sgl ")) ؛ // Query عدد الإدخالات: قائمة واحدة <string []> قائمة = purejdbcdao.query ("حدد * من t_user حيث تقطع (user_name) =؟" ، arrays.aslist ("sgl")) ؛ // Query عدد الإدخالات: 1 system.out.println ("الاستعلام عن عدد الإدخالات:"+list.size ()) ؛ }}لخص
ما سبق هو الحل الذي أدخله المحرر لحل مشكلة NULL عندما يستخدم MyBatis حقل نوع Char للاستعلام عن قاعدة بيانات Oracle. آمل أن يكون ذلك مفيدًا للجميع. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر على الجميع في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!