Secara umum, memodifikasi kode sumber kerangka kerja sangat berisiko, dan jangan memodifikasinya kecuali itu mutlak diperlukan. Tetapi hari ini saya dengan hati -hati merekonstruksi kelas SQLSessionFactoryBean yang secara resmi disediakan oleh Mybatis, yang terintegrasi dengan Spring. Pertama, ia memiliki mentalitas coba -coba, dan kedua, ia memiliki kebutuhan yang realistis.
Izinkan saya menjelaskan dua poin terlebih dahulu:
Secara umum, refactoring mengacu pada mengoptimalkan kode tanpa mengubah fungsi, tetapi refactoring yang disebutkan dalam artikel ini juga mencakup penambahan fungsi.
Paket Jar Utama (Versi) yang digunakan dalam artikel ini: Spring-*-4.3.3.release.jar, mybatis-3.4.1.jar, mybatis-spring-1.3.0.jar
Mari kita mulai dengan integrasi mybatis dan musim semi.
1. Mengintegrasikan mybatis dan musim semi
<bean id = "sqlSessionFactory" p: DataSource-ref = "DataSource" p: configLocation = "classpath: mybatis/mybatis-config.xml"> <name properti = "mapperlocations"> <rray> <value> cladementpath*: **/*.
The key class of integration is org.mybatis.spring.SqlSessionFactoryBean, which is a factory bean used to generate Mybatis global session factory SqlSessionFactory (that is, the factory bean that generates the session factory), and SqlSessionFactory is used to generate session SqlSession object (SqlSessionFactory is equivalent to DataSource, SQLSession setara dengan koneksi).
Di mana properti (dikonfigurasi menggunakan namespace atau elemen anak properti):
DataSource adalah sumber data, yang dapat dikonfigurasi menggunakan DBCP, C3P0, DRUID, JNDI-Lookup dan metode lainnya.
ConfigLocation adalah konfigurasi global mesin MyBatis, yang digunakan untuk memodifikasi perilaku mybatis.
MapperLocations adalah file konfigurasi skrip SQLMapper (mode) yang perlu dimuat mybatis.
Tentu saja, ada banyak atribut lain, jadi saya tidak akan memberikan contoh di sini.
2. Mengapa merekonstruksi
1. Optimalisasi kode sumber
Fungsi SQLSessionFactoryBean adalah untuk menghasilkan SQLSessionFactory. Mari kita lihat metode ini (sqlSessionFactoryBean.java line 384-538): /*** Bangun {@code sqlSessionFactory} instance. ** Implementasi default menggunakan mybatis {@code xmlConfigBuilder {@code {@code {@code {@code. 1.3.0, dapat ditentukan instance {@link configuration} secara langsung (tanpa file konfigurasi). ** @return sqlSessionFactory* @throws ioException jika memuat file konfigurasi gagal* configuration sqlsessionfactory {non -lrowsfacpory (). (this.configuration! = null) {configuration = this.configuration; if (configuration.getVariable () == null) {configuration.setVariables (this.configurationproperties);}} if ife (configuration. (this.configlocation! = null) {xmlConfigBuilder = new XmlConfigBuilder (this.configlocation.getInputStream (), null, this.configurationproperties); configuration = xmlConfigBuilder.getConfiguration ();} {owe {apigereDe (); {Logger.debug ("Properti` configuration` atau 'configLocation' tidak ditentukan, menggunakan konfigurasi mybatis default ");} configuration = configuration baru (); configuration.setVariable (this.configurationProperties);} if (this.objectfactory! = Null) {configuration.setObures);} if (this.objectFactory! = Null) {metriguration.setObures); (this.objectWrapperFactory! = null) {configuration.setObjectWrapPory (this.objectWrapperfactory);} if (this.vfs! = null) {configuration.setvfsimpl (this.vfs);} if (haslength (this.typealiSespackage) {oPackage) {packacke) {{{haspack] {this.typeaLiSespackage)) {this.aspackage)) {this.typeAsespackage)) {this. TokenizeToStringArray (this.typealiSespackage, configurableApplicationContext.config_location_delimiters); untuk (string packagetoscan: TypealiSpackageArray) {configuration.gettypealisregistry (). registeraliases (packagetoscan, typealisuSupertype == null? objek.class: typealisupertype); if (logger.isdebugenabled ()) oPyber (if logger.isdebugeGeGed ()) {) {if logger. untuk alias ");}}} if (! isEmpty (this.typealiases)) {for (class <?> Typealias: this.typealiases) {configuration.gettypealiSregistry ().“ Typealias); if (logger.isdebugenabled (). + "'");}}} If (! Isempty (this.plugins)) {for (plugin interceptor: this.plugins) {configuration.addinterceptor (plugin); if (logger.isdebugeNabled ()) {logger.debug ("plugin terdaftar:" " + + + + + +" + " +" + " +" " +" " +" " + {logger {" ") (hasLength (this.typehandlerspackage)) {string [] typeHandLersPackageArray = TokenizeToStringArray (this.typehandlerspackage, configurableApplicationContext.config_location_delimiters); untuk (String Packagetoscan: TypeHandLersPackageArray) {configuration.gettypehandlerregistry (). Register (packageToScan); if (logger.isdebugeNabled ()) {logger.debug ("Paket yang dipindai: '" + PackageToscan + "untuk tipe tangan"); (!!! (this.databaseidprovider! = null) {// fix #64 set databaseid sebelum parse mapper xmlstry {configuration.setDatabaseid (this.databaseidprovider.getDatabaseid (thereoCeoCeoCeoCeoCeoCeoCeoCeoCeoCeoCeoCeoCeoCeoCeoCEICE (SQELEODEOOD (SQLEXEDE E)); ; {configuration.addcache (this.cache);} if (xmlConfigBuilder! = null) {coba {xmlconfigBuilder.parse (); if (logger.isdebugeNabled () {parsePon (logger.isdebugePabled () {parsePon. + "'");}} catch (Exception ex) {throw new NestedioException ("Gagal Parse Config Resource:" + this.configlocation, ex);} akhirnya {errorContext.instance (). RESET ();}} if (this.transactionFactory == null) {this.trans ini SpringManagedTransactionFactory ();} configuration.setenvironment (lingkungan baru (this.environment, this.transactionFactory, this.dataSource)); if (! Isempty (this.mapperlocations)) {for (sumber daya mapperlocation: this.mapperlocations (this.mapperlocations)) {for (sumber daya mapperlocation: this.mapperlocations) {ifedm (Mullocing = nullocation: nullocation: this.mapperlocations) {ifedm (mapper = nullocation = nullocation: this xmlmapperbuilder = xmlmapperbuilder baru (mapperlocation.getInputStream (), konfigurasi, mapperlocation.tostring (), configuration.getsqlFragments ()); xmlmapperbuilder.parse ();} catch (pengecualian e) {throw nestedbuilder.parse ();} catch (pengecualian e) {throw nested nested nested -nested (); "'", e);} akhirnya {errorContext.Instance (). reset ();} if (logger.isdebugeNabled ()) {logger.debug ("file mapper parsed:'" + mapperlocation + "');}}} {if (if logger.isde.) 'MapperLocations' tidak ditentukan atau tidak ada sumber daya yang cocok ditemukan ");}} kembalikan this.sqlSessionFactoryBuilder.build (konfigurasi);}Meskipun Mybatis adalah kerangka kerja lapisan kegigihan yang sangat baik, jujur saja, kode ini memang tidak terlalu baik dan memiliki banyak ruang untuk rekonstruksi dan optimasi.
2. Ekspansi fungsional
(1) Gunakan skema untuk memverifikasi sqlmapper
<!-Mode DTD-> <? Xml Version = "1.0" encoding = "UTF-8"?> <! Doctype mapper public "-// mybatis.org//dtd mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dapper.dapper.dkapper.dkapper.dkper.dtd/ mybatis-3-mapper namespace = "org.dysd.dao.mybatis.config.iexampledao"> </mapper> <!-mode skema-> <? Xml versi = "1.0" encoding = "UTF-8"?> <Mapper xmlns: XSI = "http:/ww23. xmlns = "http://dysd.org/schema/sqlmapper" xsi: schemalocation = "http://dysd.org/schema/sqlmapper http://dysd.org/schema/sqlmapper.xsd "namespace =" org.dysd.dao.mybatis.config.iexampledao "> </mapper>
Sekilas, menggunakan skema lebih rumit, tetapi jika dikombinasikan dengan IDE, petunjuk otomatis menggunakan skema lebih ramah dan informasi verifikasi lebih jelas. Pada saat yang sama, ini juga membuka jendela bagi pengembang lain untuk memungkinkan mereka menyesuaikan namespace berdasarkan namespace yang ada, seperti memperkenalkan tag <OGNL>, menggunakan ekspresi OGNL untuk mengonfigurasi pernyataan SQL, dll.
(2) Kustomisasi konfigurasi. SQLSessionFactoryBean telah memberikan lebih banyak parameter untuk konfigurasi khusus, tetapi masih mungkin untuk membutuhkan lebih banyak pengaturan yang dipersonalisasi, seperti:
A. Atur jenis hasil default. Untuk elemen <Colly> yang tidak menetapkan Hasil dan Hasil Hasil, Anda dapat mengatur tipe pengembalian default untuk memetakan setelah penguraian, sehingga menyederhanakan konfigurasi SQLMapper.
<!-Sebelum disederhanakan-> <pilih id = "pilih" resultType = "map"> pilih * dari table_name di mana field1 = #{field1, jdbctype = varchar} </selection> <!-Setelah disederhanakan-> <pilih id = "pilih"> dari tabel_name di mana field1 = #{field1, jdbctype = varcharB. Perluas analisis parameter asli Mybatis. Implementasi parsing asli adalah defaultParameterHandler. Implementasi ini dapat diwarisi dan diperluas. Misalnya, untuk ekspresi properti diawali dengan spel:, gunakan spel untuk mengevaluasi nilainya.
(3) Untuk ekstensi lain, silakan merujuk ke blog penulis sebelumnya tentang MyBatis Extension
3. Kelayakan Rekonstruksi
(1) dalam hal ruang lingkup pengaruh kode
Di bawah ini adalah struktur warisan SQLSessionFactoryBean
Dari sini kita dapat melihat bahwa sistem warisan SQLSessionFactoryBean tidak rumit, dan tidak mewarisi kelas orang tua lainnya. Ini hanya mengimplementasikan tiga antarmuka di musim semi (EventListener di JDK hanyalah logo). Selain itu, SQLSessionFactoryBean ditujukan untuk pengguna pengembangan akhir, tanpa subkelas dan tidak ada kelas lain yang menyebutnya, sehingga sangat kecil dalam hal ruang lingkup dampak kode.
(2) Dalam implementasi rekonstruksi, Anda dapat membuat SchemasqlSessionFactoryBean baru, dan kemudian kode sepenuhnya menyalin SQLSessionFactoryBean di awal, memodifikasi nama paket dan nama kelas, dan kemudian menggunakan ini sebagai dasar untuk rekonstruksi. Ini relatif sederhana.
(3) Dalam aplikasi terintegrasi, Anda hanya perlu memodifikasi atribut kelas dalam konfigurasi dan pegas yang terintegrasi.
Di atas adalah refactoring dari SQLSessionFactoryBean yang terintegrasi dengan mybatis dan musim semi yang diperkenalkan kepada Anda. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!