Menurut ide halaman berikut, mudah untuk mengimplementasikan desain multi-tenant mybita.
Gunakan pencegat yang disediakan oleh Mybatis. Pernyataan SQL paged diproses menjadi SQL paged yang berbeda melalui enkapsulasi.
Contoh ini telah menerapkan fungsi pagination MySQL dan Oracle. Perhatikan paket kutipan berikut dan jangan mengutipnya secara tidak benar.
impor java.sql.connection; impor java.sql.preparedstatement; impor java.sql.resultset; impor java.sql.sqlexception; impor java.util.list; import java.util.properties; impor org.apache.ibatis.executor.execut.util. org.apache.ibatis.executor.statement.RoutingStatementHandler; import org.apache.ibatis.executor.statement.statementhandler; org.apache.ibatis.plugin.interceptor; impor org.apache.iathis.plugin.intercepts; impor org.apache.iatis.plugin.invokasi; impor org.apache.ibatis.plugin.plugin; impor org.apache.ibatis.plugin.signature; org.apache.iathis.scripting.defaults.defaultparameterhandler; import com.yidao.utils.page; import com.yidao.utils.reflecthelper;/** * * Pagination Interceptor, digunakan untuk mencegat operasi yang memerlukan query paging dan kemudian membuat ini mengecat mereka. * Prinsip paging mybatis diimplementasikan menggunakan pencegat: * untuk menggunakan JDBC untuk beroperasi pada database, Anda harus memiliki objek pernyataan yang sesuai. Sebelum MyBatis menjalankan pernyataan SQL, itu akan menghasilkan objek pernyataan yang berisi pernyataan SQL, dan pernyataan SQL yang sesuai* dihasilkan sebelum pernyataan, sehingga kita dapat mulai dengan pernyataan SQL yang digunakan untuk menghasilkan pernyataan sebelum menghasilkan pernyataan. Dalam pernyataan MyBatis Pernyataan dihasilkan oleh * Metode Persiapan dari Objek RoutingStatementHandler. Oleh karena itu, salah satu ide untuk menggunakan interseptor untuk mengimplementasikan paging mybatis adalah untuk mencegat metode persiapan dari antarmuka Pernyataan Penajian, dan kemudian mengubah pernyataan SQL ke dalam pernyataan SQL kueri pagination yang sesuai dalam metode pencegat, dan kemudian memanggil metode persiapan objek * Pernyataan Penjara, yaitu doa panggilan. (). * Untuk pagination, salah satu operasi yang perlu kita lakukan di Interceptor adalah menghitung jumlah total catatan yang memenuhi persyaratan saat ini. Ini dengan mendapatkan pernyataan SQL asli, mengubahnya ke pernyataan statistik yang sesuai, dan kemudian mengganti parameter dalam pernyataan SQL menggunakan parameter yang dienkapsulasi MyBatis dan pengaturan * parameter. Kemudian, pernyataan SQL menanyakan jumlah catatan dieksekusi untuk menghitung jumlah total catatan. * */ @Intercepts ({ @Signature (type = SympantionHandler.class, Method = "Persiapkan", args = {connection.class})}) kelas publik PageInterceptor mengimplementasikan interceptor {private string dialect = ""; // dialek database Private String pagesqlid = ""; // ID yang perlu dicegat di mapper.xml (pencocokan reguler) Intercept Obyek (Doa Doa) Melempar lempar {// Sebenarnya hanya ada dua kelas implementasi untuk Pernyataan Handler, satu RoutingStatementHandler, dan yang lainnya adalah kelas abstrak Basestatementhandler. // BasestatementHandler memiliki tiga subclass, yaitu SimpleStatementHandler, PrepiedStatementHandler dan CallablestAtementhandler. // SimpleStatementHandler digunakan untuk memproses pernyataan, disiapkan Handler menangani persiapan disiapkan, dan callablestatementhandler adalah // memproses callablestatement. Mybatis membuat RoutingStatementhandler saat memproses pernyataan SQL. Di RoutingStatementHandler, ada properti delegasi dari // Jenis Pernyataan Teman. RoutingStatementHandler akan membuat Basestatementhandler yang sesuai sesuai dengan pernyataan yang berbeda, yaitu, SimpleStatementHandler, // PreparedStateMentHandler atau CallablestatementHandler. Di RoutingStateMentHandler, semua metode antarmuka pernyataan Handler diimplementasikan oleh delegasi yang sesuai dengan delegasi yang dipanggil. // Kami telah menandai interseptor hanya mencegat metode persiapan antarmuka Pernyataan HiShandler dengan @Signature di kelas PageInceptor. Karena mybatis hanya membungkusnya melalui metode plugin interceptor saat membangun RoutingStatementHandler, sehingga objek target yang kita selesaikan di sini haruslah objek RoutingStateMentHandler. if (Invocation.getTarget () instanceof routingstatementhandler) {routingstatementhandler pernyataanhandler = (routingstatementhandler) Invocation.getTarget (); Pernyataan Delegasi = (Pernyataan Tulisan) Reflecthelper.GetFieldValue (Pernyataan Handler, "Delegate"); BoundSQL BoundSQL = delegate.getBoundSQL (); Objek obj = boundsql.getParameterObject (); if (obj instance dari halaman <?>) {page <?> page = (halaman <?>) obj; // Ambil properti mappedstatement dari Basestatementhandler dari kelas Delegate Parent MappedStatement MappedStatement = (MappedStatement) reflecthelper.getFieldValue (delegasi, "mappedstatement"); // Parameter metode persiapan yang dicegat adalah koneksi objek koneksi koneksi = (koneksi) Invocation.getArgs () [0]; // Dapatkan pernyataan SQL yang saat ini dieksekusi, yaitu pernyataan SQL yang kami tulis langsung dalam string pernyataan pemetaan mapper SQL = BoundSQL.GetSQL (); // Atur jumlah total catatan untuk objek parameter halaman saat ini this.setTotalRecord (halaman, mappedstatement, koneksi); // Dapatkan Pernyataan SQL Paged String PAGESQL = this.getPagesQL (halaman, SQL); // Gunakan refleksi untuk mengatur atribut SQL yang sesuai dengan BoundSQL saat ini untuk membuat pernyataan SQL Paged yang baik untuk US Reflecthelper.SetFieldValue (BoundSQL, "SQL", PAGESQL); }} return Invocation.proed (); } /*** Atur jumlah total catatan untuk halaman objek parameter saat ini** @param halaman Mapper Mapping Pernyataan* @param MappedStatement Mapper Mapping Pernyataan* @param koneksi saat ini koneksi database* /private void setTotalRecord (halaman <?> Page, mappedstatement mappedStatement, koneksi koneksi) {// dapatkan batas yang sesuai. BoundSQL ini sebenarnya adalah objek yang sama dengan BoundSQL yang kami peroleh dengan menggunakan Pernyataan Handler. // BoundSQL dalam delegasi juga diperoleh melalui metode MappedStatement.getBoundSQL (ParamoBJ). BoundSQL BoundSQL = MappedStatement.getBoundSQL (halaman); // Dapatkan string pernyataan SQL yang sesuai sql = boundsql.getsql (); // Dapatkan pernyataan SQL yang sesuai yang menghitung jumlah total catatan dengan menanyakan string pernyataan SQL CountSQL = this.getCountsql (SQL); // Dapatkan peta parameter yang sesuai melalui Daftar BoundSQL <Parametermapping> parameterMappings = boundSQL.GetParametermappings (); // Gunakan konfigurasi, pernyataan SQL CountSQL untuk catatan kueri, parameter pemetaan hubungan parametermappings dan halaman objek parameter untuk membuat objek BoundSQL yang sesuai dengan catatan kueri. BoundSQL CountBoundSQL = BoundSQL baru (MappedStatement.GetConfiguration (), CountSQL, Parametermappings, halaman); // Buat objek ParameterHandler untuk mengatur parameter melalui MappedStatement, Parameter Object Page dan Objek BoundSQL CountBoundSQL. ParameterHandler ParameterHandler = New DefaultParameterHandler (MappedStatement, Page, CountboundSQL); // Buat objek yang disiapkan yang sesuai dengan CountSQL melalui koneksi. PSTMT Persiapan PSTMT = NULL; Hasil rs = null; coba {pstmt = connection.preparestatement (countsql); // atur parameter parameterhandler untuk objek disiapkan melalui parameterHandler.setParameters (PSTMT); // Kemudian dieksekusi untuk mendapatkan jumlah total catatan dan mendapatkan hasilnya. RS = PSTMT.ExecuteQuery (); if (rs.next ()) {int totalRecord = rs.getint (1); // Tetapkan jumlah total catatan untuk objek halaman parameter saat ini. }} catch (sqlexception e) {e.printstacktrace (); } akhirnya {coba {if (rs! = null) rs.close (); if (pstmt! = null) pstmt.close (); } catch (sqlexception e) {e.printstacktrace (); }}} / ** * Pernyataan SQL yang memperoleh jumlah total catatan yang sesuai dalam kueri * @param sql * @return * / string privat getCountSql (string sql) {int index = sql.indexof ("from"); return "pilih count (*)" + sql.substring (index); } /*** Dapatkan pernyataan SQL kueri pagination yang sesuai berdasarkan objek halaman. Hanya dua jenis database yang dibuat di sini, MySQL dan Oracle * tidak ada database lain yang paging * * @param halaman paging objek * @param sql pernyataan sql asli * @return */ string private getPagesql (halaman <?>, String sql) {stringbuffer sqlbuffer = new stringBuffer (sql); if ("mysql" .equalSignorecase (dialek)) {return getMysqlpagesql (halaman, sqlbuffer); } lain jika ("oracle" .equalsignorecase (dialek)) {return getoraclePagesQl (halaman, sqlbuffer); } return sqlbuffer.toString (); } / *** Dapatkan pernyataan kueri paged untuk database mysql* objek paging halaman @param* @param sqlbuffer Objek StringBuffer yang berisi pernyataan SQL asli* @return MySQL Paging Petugas* Posisi catatan di MySQL dimulai dari 0. // System.out.println ("halaman:"+page.getPage ()+"--------"+page.getRows ()); int offset = (page.getPage () - 1) * page.getRows (); sqlbuffer.append ("limit") .append (offset) .append (","). append (page.getrows ()); return sqlbuffer.tostring (); } / *** Dapatkan Pernyataan Kueri Paged untuk Oracle Database* @Param Page Paging Object* @param SQLBuffer Objek StringBuffer yang berisi pernyataan SQL asli* @Return Pagination Pernyataan Kueri untuk Oracle Database* / Private String getoraclePagesQL (halaman <?> Halaman, stringbuffer sqlbuffer sqlbuffer sqlbuffer) {page <?> Page, stringbuffer sqlbuffer sqlbuffer sqlbuffer) {page <?> Page, stringbuffer sqlbuffer sqlbuffer sqlbuffer) {page <?> Page, stringbuffer SQLBUFFER SQLBUFFER) Oracle Pagination dilakukan melalui rownum, dan Rownum dimulai dari 1 int offset = (page.getPage () - 1) * page.getRows () + 1; sqlbuffer.insert (0, "pilih u.*, rownum r from ("). lampai (") u di mana rownum <"). lampai (offset + page.getrows ()); sqlbuffer.insert (0, "pilih * from (") .Append (") di mana r> =") .Append (offset); // Pernyataan SQL di atas terlihat seperti ini: // Pilih * dari (pilih u. *, Rownum r dari (pilih * dari t_user) u di mana rownum <31) di mana r> = 16 return sqlbuffer.toString (); } / *** Metode untuk merangkum objek asli yang sesuai dengan plugin Interceptor* / Public Object (objek arg0) {// TODO Metode yang dihasilkan secara otomatis Stub if (arg0 instanceof pernyataanHandler) {return plugin.wrap (arg0, this); } else {return arg0; }} / *** Setel properti yang ditetapkan saat mendaftarkan interceptor* / public void setProperties (properti p) {} public string getDialect () {return dialect; } public void setDialect (string dialek) {this.dialect = dialek; } public String getPagesQLID () {return pagesqlid; } public void setPagesQLID (String pagesqlid) {this.pagesqlid = pagesqlid; }} Konfigurasi XML:
<!-Konfigurasi Pemrograman Antarmuka MyBatis-> <Bean> <!-Basepackage menentukan paket yang akan dipindai. Mapper di bawah paket ini akan dicari. Beberapa paket dapat ditentukan, dipisahkan oleh koma atau titik koma-> <nama properti = "basepackage" value = "com.yidao.mybatis.dao" /> <nama properti = "sqlSessionFactoryBeanName" value = "sqlsessionfactory" /< /beAn> <!-mybaton = "mybaton = mybatcepning = mybaton = mybator = mybator = my-mybator = my-my-myceptory" <name properti = "dialek" value = "mysql"/> <!-mencegat pernyataan dengan ID yang berisi karakter kueri dalam file mapper.xml-> <properti name = "pagesqlid" value = ".*kueri $"/> </bean>
Kelas halaman
Paket com.yidao.utils;/** Lihat sendiri, bidang apa yang diperlukan untuk ditambahkan ke dalamnya*/halaman kelas publik {Private Integer Rows; halaman bilangan bulat pribadi = 1; Integer Privat Total Record; Public Integer getRows () {Return Rows; } public void setRows (baris integer) {this.rows = baris; } public integer getPage () {return page; } public void setPage (halaman integer) {this.page = halaman; } public integer getTotalRecord () {return TotalRecord; } public void setTotalRecord (Integer TotalRecord) {this.totalRecord = TotalRecord; }} Kelas Reflecthelper
Paket com.yidao.utils; import java.lang.reflect.field; impor org.apache.commons.lang3.reflect.fieldutils; kelas publik reflecthelper {public static objek getFieldValue (objek obj, string fieldName) {if (obj == null) {return null) {return null); } Field targetfield = getTargetField (obj.getClass (), fieldName); coba {return fieldutils.readfield (Targetfield, obj, true); } catch (ilegalAccessException e) {e.printstacktrace (); } return null; } public static field getTargetField (class <?> targetClass, string fieldName) {field field = null; coba {if (targetclass == null) {return field; } if (object.class.equals (targetClass)) {return field; } field = fieldutils.getDeclaredfield (targetClass, fieldname, true); if (field == null) {field = getTargetField (targetclass.getSuperclass (), fieldName); }} catch (Exception e) {} bidang pengembalian; } public static void setFieldValue (objek obj, string fieldName, nilai objek) {if (null == obj) {return;} field targetfield = getTargetfield (obj.getClass (), fieldName); coba {fieldutils.writefield (Targetfield, OBJ, nilai); } catch (ilegalAccessException e) {e.printstacktrace (); }}}Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.