للأسف ، لم أكتب أي شيء لفترة طويلة مؤخرًا. بسبب أسباب العمل ، اتصلت بإطار ORM الأساسي الذي طورته الشركة. لقد وجدت بطريق الخطأ أنه عند استدعاء عمليات JDBC ، يشير الإطار إلى SimpleJDBCtemplate في السبات. فكرت هنا في تغليف JDBC بسيط استخدمته عندما كنت في الكلية. الآن سأقوم بنشر الرمز ومشاركته معك:
فئة التكوين: اقرأ ملف تكوين اتصال قاعدة البيانات ضمن نفس الحزمة ، بحيث يكون أفضل لاعتبارات التعميم.
package com.tly.dbutil ؛ import java.io.ioException ؛ import java.util.properties ؛ config config {private static properties prop = new properties () ؛ static {try {// load dbconfig.properties configuration file prop.load (config.classourceasStream ("dbConfig.Properties")) ؛ } catch (ioException e) {// todo acto catch block e.printstacktrace () ؛ }} // قم بتعيين سلسلة نهائية ثابتة ثابتة class_name = prop.getProperty ("class_name") ؛ public static final string database_url = prop.getProperty ("database_url") ؛ Static Final Final Server_ip = prop.getProperty ("server_ip") ؛ Static Final Final Server_port = prop.getProperty ("server_port") ؛ Static Final String Database_sid = prop.getProperty ("database_sid") ؛ username username static static static static = prop.getProperty ("اسم المستخدم") ؛ كلمة مرور السلسلة النهائية الثابتة = prop.getProperty ("كلمة المرور") ؛ }dbConfig.properties: ملف تكوين قاعدة البيانات ، يمكنك أيضًا استخدام تنسيق XML ، وما إلى ذلك ، الانتباه إلى موقع الاتصال في الملف في فئة التكوين
class_name = com.mysql.jdbc.driverdatabase_url = jdbc: mysqlserver_ip = localHostserver_port = 3306Database_Sid = staffusername = rootpassword = 1
التالي هو CONNECTION CONNECTION CLASS DBCONN
package com.employees.dbutil ؛ استيراد java.sql.connection ؛ استيراد java.sql.drivermanager ؛ استيراد java.sql.preparedstatement ؛ استيراد java.sql.resultset ؛ استيراد java.sql.sqlexception ؛ public dbconn { Private ReparedStatement PSTMT = NULL ؛ نتائج خاصة RS = فارغة ؛ // Four Methods // method1: إنشاء اتصال إلى قاعدة البيانات العامة getConntion () {try {// 1: تحميل برنامج تشغيل الاتصال ، java reflection principle class.forname (config.class_name) ؛ // 2: قم بإنشاء كائن واجهة اتصال للحصول على كائن اتصال لقاعدة بيانات MySQL. ثلاث معلمات: سلسلة اتصال URL حساب كلمة المرور url = config.database_url+": //"+config.server_ip+":"+config.server_port+"/"+config.database_sid ؛ conn = drivermanager.getConnection (url ، config.username ، config.password) ؛ } catch (classNotFoundException e) {E.PrintStackTrace () ؛ } catch (sqlexception e) {E.PrintStackTrace () ؛ } return conn ؛ }. } catch (sqlexception e) {E.PrintStackTrace () ؛ }} if (pstmt! = null) {try {pstmt.close () ؛ } catch (sqlexception e) {E.PrintStackTrace () ؛ }} if (conn! = null) {try {conn.close () ؛ } catch (sqlexception e) {E.PrintStackTrace () ؛ }}} // method3: الطريقة المستخدمة خصيصًا لإرسال عبارات إضافة وحذف وتعديل البيانات العامة execother (preparedStatement PSTMT) {try {// 1. استخدم كائن العبارة لإرسال عبارة SQL int intedrows = pstmt.executeupdate () ؛ // 2. إرجاع النتيجة التي تم إرجاعها. } catch (sqlexception e) {E.PrintStackTrace () ؛ العودة -1 ؛ }} // method4: خصيصًا لإرسال عبارات الاستعلام عن ResultSet execquery (preparedStatement PSTMT) {try {// 1. استخدم كائن العبارة لإرسال عبارة SQL RS = PSTMT.Executequery () ؛ // 2. إرجاع النتيجة إرجاع روبية ؛ } catch (sqlexception e) {E.PrintStackTrace () ؛ العودة لاغية. }}}عادة ، يمكن أن يؤدي استخدام الكود أعلاه إلى حل بعض تطبيقات CRUD البسيطة ، ولكن هناك العديد من القيود. على سبيل المثال ، في كل مرة يقوم فيها البرنامج بالاتصال ، سيزيد من العبء على النظام ، ولا توجد معاملات ، ولا توجد بيانات بيانات ، وما إلى ذلك. اليوم رأيت صديقًا في الحديقة يكتب مقالًا في الحديقة باستخدام انعكاس لحل Crud مباشرة في معلمات الكائن. لقد كتبت هذا من قبل ، لكنني لم أنتهي منه. أريد أن أكتب dbutil عام. أخيرًا ، لقد درستها ووجدت أنها تقترب من SimpleJDBCtemplate في السبات ، لذلك ذهبت لرؤية رمز المصدر من السبات. بالإضافة إلى ذلك ، كانت هناك بعض الأشياء خلال تلك الفترة ، ولم يكن لدي وقت ، لذلك تركت هذه المسألة خاملة. الآن أعوض هذا الشيء وأراجعه بنفسي.
فئة على أساس
package com.employees.dao ؛ استيراد java.io.inputstream ؛ استيراد java.lang.reflect.method ؛ استيراد java.lang.perameterizedtype ؛ استيراد java.sql.connection ؛ استيراد java.sql.date ؛ استيراد java.sql.preparedstement ؛ java.util.arraylist ؛ import java.util.iterator ؛ import java.util.list ؛ import com.employees.dbutil.dbconn ؛ public class repondao <t> {dbconn conn = new dbconn () ؛ اتصال الاتصال الخاص = فارغ ؛ suppressWarnings ("غير مستخدم") الطبقة الخاصة <T> perfectClass ؛ suppressWarnings ("غير محدد") public arendao () {initConnection () ؛ // الحصول على المعلمة نوع المعلمة typetype = (parameterizedType) getClass (). getGenericSuperClass () ؛ perferenceClass = (class <t>) type.getActualTyPearguments () [0] ؛ } / *** الحصول على اتصال قاعدة البيانات* / public void initConnection () {connection = conn.getConntion () ؛ } /** * Save * /public void save (t intity) resws {// sql state ، insert في اسم الجدول (String sql = "insert in" + entity.getClass (). getSimplename (). iter = list.iterator () ؛ SQL.SubString (0 ، sql.lastindexof ("،" ،)) +")) القيم (؛ // stand resert resert sql premomipiled insert في اسم الجدول (المعرف ، الاسم ، البريد الإلكتروني) (؟ ،؟ ،؟ ،؟ الاسم (الاسم ، البريد الإلكتروني) القيم (؟ ،؟ ،؟) ؛ // احصل على المرجع إلى عبارة الكائن المسبق لإعداده = اتصال. preparestatement (SQL) ؛ int i = 0 ؛ // انقل المؤشر إلى السطر الأخير من Iterator إلى السطر الأول. iter = list.iterator () ؛ بينما (iter.hasnext ()) {method method = iter.next () ؛ // يحدد هذا في البداية نوع قيمة الإرجاع ، لأن بعض تنسيقات قيمة الحقل يجب تغييرها عند تخزينها في قاعدة البيانات. على سبيل المثال ، السلسلة ، عبارة SQL هي "+abc+" 'if (method.getReturnType (). getSimplename (). indexof ("string")! = -1) {state.setString (++ i ، this.getString (method ، ectity)) ؛ } آخر إذا (method.getReturnType (). getSimplename (). indexof ("date")! = -1) {stitpt.setDate (++ i ، this.getDate (method ، ectity)) ؛ } آخر إذا (method.getReturnType (). getSimplename (). indexof ("inputStream")! = -1) {stitpt.setasciistream (++ i ، this.getBlob (method ، unitity) ، 1440) ؛ } آخر {state.setInt (++ i ، this.getInt (method ، ectity)) ؛ }} // تنفيذ conn.execother (بيان) ؛ // closeConn () ؛ } / ** * تعديل * / تحديث باطل عام (كيان t) يلقي الاستثناء {String sql = "update" + entity.getClass (). getSimplename (). tolowercase () + "set" ؛ // احصل على جميع مجموعات كائنات الأسلوب من قائمة الفئة هذه <Tepron> list = this.matchpojomethods (الكيان ، "get") ؛ // كائن الطريقة المؤقتة ، المسؤولة عن تكرار كائن طريقة الموضة. طريقة tempmethod = null ؛ // لأن المعرف ليس من الضروري تعديله عند التعديل ، يجب إضافة المعلمات من أجل نقل المعرف إلى النهاية. طريقة idmethod = null ؛ iterator <Tepray> iter = list.iterator () ؛ بينما (iter.hasnext ()) {tempmethod = iter.next () ؛ // إذا كان اسم الطريقة يحتوي على سلسلة معرف وطول 2 ، فإنه يعتبر معرفًا. if (tempmethod.getName (). lastIndexof ("id")! = -1 && tempmethod.getName (). substring (3) .Length () == 2) {// حفظ كائن حقل المعرف في متغير وحذفه في المجموعة. idmethod = tempmethod ؛ iter.remove () ؛ // إذا تمت إزالة اسم الأسلوب وكان سلسلة/الحصول على سلسلة غير متوافقة مع pojo + "id" (الحالة غير حساسة) ، فإنه يعتبر معرفًا} آخر إذا ((estity.getClass (). getSimplename () + "id"). aseassignorecase (tempmethod.getName (). string (3))) iter.remove () ؛ }} // نقل المؤشر التكراري إلى الموضع الأول iter = list.iterator () ؛ بينما (iter.hasnext ()) {tempmethod = iter.next () ؛ sql + = tempmethod.getName (). substring (3) .ToLowerCase () + "=؟ ،" ؛ } // قم بإزالة آخر واحد ، الرمز sql = sql.substring (0 ، sql.lastindexof ("،")) ؛ // إضافة شرط sql + = "أين" + idmethod.getName (). substring (3) .ToLowerCase () + "=؟" ؛ // تم الانتهاء من الربط SQL ، طباعة SQL Dates System.out.println (SQL) ؛ reparedStatement بيان = this.connection.preparestatement (SQL) ؛ int i = 0 ؛ iter = list.iterator () ؛ بينما (iter.hasnext ()) {method method = iter.next () ؛ // يحدد هذا في البداية نوع قيمة الإرجاع ، لأن بعض تنسيقات قيمة الحقل يجب تغييرها عند تخزينها في قاعدة البيانات ، على سبيل المثال ، سلسلة ، SQL عبارة "+ABC+" 'if (method.getReturntype (). } آخر إذا (method.getReturnType (). getSimplename (). indexof ("date")! = -1) {stitpt.SetString (++ i ، this.getString (method ، ectity)) ؛ } آخر إذا (method.getReturnType (). getSimplename (). indexof ("date")! = -1) {stitpt.setDate (++ i ، this.getDate (method ، ectity)) ؛ } آخر إذا (method.getReturnType (). getSimplename (). indexof ("inputStream")! = -1) {stitpt.setasciistream (++ i ، this.getBlob (method ، unitity) ، 1440) ؛ } آخر {state.setInt (++ i ، this.getInt (method ، ectity)) ؛ }} // إضافة قيمة إلى حقل المعرف if (idmethod.getReturnType (). getSimplename (). indexof ("string")! = -1) {state.setString (++ i ، this.getString (idmethod ، untity)) ؛ } آخر {state.setInt (++ i ، this.getInt (idmethod ، untity)) ؛ } // تنفيذ عبارة SQL state.executeupdate () ؛ // أغلق عبارة الكائن المسبق. // أغلق connection.close () ؛ } / ** * delete * / public void delete (t intity) يرمي الاستثناء {String sql = "delete from" + entity.getClass (). getSimplename (). // تخزين كائن الحقل مع سلسلة "المعرف" idmethod = null ؛ // الحصول على كائن الحقل مع قائمة "المعرف" السلسلة <Mething> list = this.matchpojomethods (الكيان ، "GET") ؛ iterator <Tepray> iter = list.iterator () ؛ بينما (iter.hasnext ()) {method tempmethod = iter.next () ؛ // إذا كان اسم الطريقة يحتوي على سلسلة المعرف والطول 2 ، فإنه يعتبر معرفًا. if (tempmethod.getName (). lastIndexof ("id")! = -1 && tempmethod.getName (). substring (3) .Length () == 2) {// حفظ كائن حقل المعرف في متغير وحذفه في المجموعة. idmethod = tempmethod ؛ iter.remove () ؛ // إذا تمت إزالة اسم الطريقة وسلسلة SET/GET غير متوافقة مع POJO + "id" (حالة غير حساسة) ، فإنه يعتبر معرفًا} آخر إذا ((estity.getClass (). getSimplename () iter.remove () ؛ }} sql + = idmethod.getName (). substring (3) .ToLowerCase () + "=؟" ؛ reparedStatement بيان = this.connection.preparestatement (SQL) ؛ // إضافة قيمة إلى حقل المعرف int i = 0 ؛ if (idmethod.getReturnType (). getSimplename (). indexof ("string")! = -1) {stitpt.SetString (++ i ، this.getString (idmethod ، untity)) ؛ } آخر {state.setInt (++ i ، this.getInt (idmethod ، untity)) ؛ } // تنفيذ conn.execother (بيان) ؛ // closeConn () ؛ } / *** Query by id* / public t findbyid (كائن كائن) يلقي استثناء {string sql = "select* from" + perfectClass.getSimplename (). tolowercase () + "where" ؛ // استخدم مُنشئ الفئة الفرعية للحصول على النوع المحدد للنوع المعلمات. على سبيل المثال ، على أساس <T> ، أي ، الحصول على نوع محدد من الكيان t = perfectistclass.newinstance () ؛ // تخزين كائن الأسلوب الذي يخزن المفتاح الأساسي لـ pojo (أو الجدول الذي يتم تشغيله) طريقة idmethod = null ؛ قائمة <Method> list = this.matchpojomethods (الكيان ، "set") ؛ iterator <Tepray> iter = list.iterator () ؛ // filter للحصول على كائن الطريقة بينما (iter.hasNext ()) {method tempmethod = iter.next () ؛ if (tempmethod.getName (). indexof ("id")! = -1 && tempMethod.getName (). } آخر if ((entity.getClass (). getSimplename () + "id"). equalsIngInoreCase (tempmethod.getName (). substring (3))) {idmethod = tempmethod ؛ }} // يتم تحويل الحرف الأول إلى SQL += idmethod.getName (). substring (3،4) .ToLowerCase () +idmethod.getName (). substring (4) +"=؟" ؛ // بعد بيان التغليف ، قم بطباعة SQL Dates System.out.println (SQL) ؛ // احصل على بيان ConnectionStatement = this.connection.preparestatement (SQL) ؛ . } آخر إذا (Object eastyof string) {statle.setString (1 ، (string) object) ؛ } // تنفيذ SQL للحصول على مجموعة نتائج الاستعلام. resultset rs = conn.execquery (بيان) ؛ // سجل ، سجلات تسجيل إلى عدد الحقول int i = 0 ؛ // أوجه المؤشر إلى السطر الأول من iterator iter = list.iterator () ؛ // مغلف بينما (rs.next ()) {بينما (iter.hasNext ()) {method method = iter.next () ؛ if (method.getParameterTypes () [0] .getSimplename (). indexof ("string")! = -1) {// لأنه في مجموعة القائمة ، يكون ترتيب كائن الطريقة المراد استرداده غير متسق مع ترتيب حقل قاعدة البيانات (على سبيل المثال: الطريقة الأولى من القائمة هي setDate ، وتأخذ قاعدة البيانات "123". this.SetString (الطريقة ، الكيان ، Rs.GetString (method.getName (). substring (3) .ToLowerCase ())) ؛ } if if (method.getParameterTypes () [0] .getSimplename (). indexof ("Date")! = -1) {this.setDate (method ، untity ، rs.getDate (method.getName (). substring (3) .tolowercase ())) ؛ } آخر إذا (method.getParameterTypes () [0] .getSimplename (). indexof ("inputStream")! = -1) {this.setBlob (الطريقة ، الكيان ، Rs.GetBlob (method.getName (). } آخر {this.setint (الطريقة ، الكيان ، rs.getInt (method.getName (). substring (3) .ToLowerCase ())) ؛ }}} // أغلق مجموعة النتائج rs.close () ؛ // أغلق عبارة الكائن المسبق. كيان العودة ؛ } /*** تصفية جميع كائنات الطريقة مع السلاسل الواردة في فئة POJO الحالية وإرجاع مجموعة القائمة. */قائمة خاصة <Method> MatchPoJomethods (T intity ، String MethodName) {// الحصول على جميع طريقة كائنات طريقة pojo الحالية [] طرق = entity.getClass (). getDeclaredMethods () ؛ // قائمة الحاوية تخزن جميع كائنات الأسلوب مع الحصول على قائمة السلسلة <Method> list = new ArrayList <Method> () ؛ // تصفية جميع كائنات الأسلوب مع الحصول على سلاسل في فئة pojo الحالية وتخزينها في حاوية القائمة (int index = 0 ؛ index <methods.length ؛ index ++) {if (methods [index] .getName (). indexof (methodName)! = -1) {list.add (methods [index]) ؛ }} قائمة الإرجاع ؛ } /*** تقوم الطريقة بإرجاع قيمة عبارة SQL عندما يكون النوع int أو عدد صحيح. المقابلة للحصول على *// integer getint (طريقة الطريقة ، كيان t) يلقي الاستثناء {return (integer) method.invoke (الكيان ، كائن جديد [] {}) ؛ } /*** تقوم الطريقة بإرجاع قيمة تجميع عبارة SQL عندما يكون النوع سلسلة. على سبيل المثال ، "ABC" ، المقابلة لـ GET */ Public String GetString (طريقة الطريقة ، كيان t) يلقي الاستثناء {return (String) method.invoke (Entity ، Object [] {}) ؛ } /*** تقوم الطريقة بإرجاع قيمة عبارة SQL التي تم تجميعها عند نوع النقطة. المقابلة للحصول على */ public inputstream getBlob (طريقة الطريقة ، كيان t) يلقي الاستثناء {return (inputStream) method.invoke (الكيان ، كائن جديد [] {}) ؛ } / ** * تقوم الطريقة بإرجاع قيمة عبارة SQL التي تم تجميعها عند نوع التاريخ ، المقابل للحصول على * / Gublic Date GetDate (طريقة الطريقة ، كيان t) يرمي الاستثناء {return (date) method.invoke (الكيان ، كائن جديد [] {}) ؛ } / ** * عندما يكون نوع المعلمة صحيحًا أو int ، قم بتعيين المعلمات لحقل الكيان ، المقابل للمعرفة * / public integer setInt (طريقة الطريقة ، الكيان ، integer arg) يلقي الاستثناء {return (integer) method.invoke (الكيان ، كائن جديد [] {arg}) ؛ } / ** * عندما يكون نوع المعلمة عبارة عن سلسلة ، قم بتعيين المعلمات لحقل الكيان ، المقابل ل Set * / public String SetString (طريقة الطريقة ، الكيان ، السلسلة ARG) يلقي الاستثناء {return (سلسلة) method.invoke (الكيان ، كائن جديد [] {arg}) ؛ } / ** * عندما يكون نوع المعلمة هو inputStream ، قم بتعيين المعلمات لحقل الكيان ، المقابل للمعيين * / public inputStream setBlob (طريقة الطريقة ، الكيان ، inputstream arg) يلقي الاستثناء {return (inputStream) method.invoke (الكيان ، كائن جديد [] {arg}) ؛ } / ** * عندما يكون نوع المعلمة هو التاريخ ، قم بتعيين المعلمات لحقل الكيان ، المقابل للمعيين * / تاريخ الموعد العام (طريقة الطريقة ، الكيان ، تاريخ ARG) يرمي الاستثناء {return (date) method.invoke (الكيان ، كائن جديد [] {arg}) ؛ }}يرث الموظفون doendao ، ويمكنهم استخدام طريقة الفئة الأصل مباشرة ، وإضافة إعادة استخدام الرمز
package com.employees.dao ؛ استيراد java.util.arraylist ؛ استيراد java.util.list ؛ استيراد com.employees.po.employees ؛ الموظفين العامين العامين يمتدون على استثناء (الموظفين) ؛ العودة صحيح. } // إضافة معلومات الموظف إلى القائمة العامة للجدول <الموظفين> AddEmpultS (int id) يلقي استثناء {list <formist> lstemployees = new ArrayList <mosts> () ؛ الموظفون الموظفون = findById (id) ؛ // قم بتحميل البيانات المرفقة حاليًا في lstemployees.add (الموظفين) ؛ إرجاع lstemployees. } public void releteemp (كيان الموظفين النهائيين) يلقي الاستثناء {this.delete (untity) ؛ } public void updateemp (كيان الموظفين النهائيين) يلقي الاستثناء {this.update (untity) ؛ }}لن أقوم بنشر رمز طبقة PO ، الآن استخدم JUNIT4 لإجراء اختبار
package com.employees.dao ؛ استيراد org.junit.test ؛ استيراد com.employees.po.employees ؛ الموظفين العامين العامين {test public void testadd () rems {الموظفين emp = new staff () ؛ Emp.SetPname ("tly") ؛ emp.setpsex ("ذكر") ؛ emp.setpbeliefs ("xxxxx") ؛ Emp.SetPaddr ("Tianhe") ؛ Emp.SetPhobby ("Play Basketball") ؛ Emp.SetPsubject ("الكمبيوتر") ؛ Emp.Setptel ("123456") ؛ الموظفين dao = موظفين جدد () ؛ dao.addemplyees (EMP) ؛ } test public void testupdate () يلقي استثناء {staffdao dao = new amploydao () ؛ الموظفين EMP = dao.findbyid (14) ؛ Emp.Setptel ("999999") ؛ dao.updateemp (EMP) ؛ } test public void testDelete () يلقي استثناء {staffdao dao = new amploydao () ؛ الموظفين EMP = dao.findbyid (15) ؛ dao.deleteemp (EMP) ؛ }}بعد الاختبار ، يمكن أن تعمل هذه الطرق الثلاثة بشكل طبيعي ، حيث يهرع الوقت. يتم استخدام بعض الرموز من قبل الأصدقاء الآخرين. قد لا تعتبر بعض الأماكن شاملة للغاية أو أن بعض الرموز ستكون زائدة عن الحاجة. لم تتم كتابة عملية CRUD العامة في مقرها بشكل كامل. إذا كان أي صديق مهتمًا ، فيمكنك كتابته مرة أخرى ، مثل الاستعلام ، وتشغيل الدُفعات ، إلخ. إذا مر الاختبار ، تذكر أن ترسل لي نسخة ، هاها
تعبئة JDBC Auxiliary Packagiary (مثال) Simple and General هي كل المحتوى الذي أشاركه معك. آمل أن تتمكن من إعطائك مرجعًا وآمل أن تتمكن من دعم wulin.com أكثر.