มีข้อ จำกัด มากมายเมื่อใช้ mybatis เพียงอย่างเดียว (เช่นไม่สามารถใช้ธุรกรรมที่ครอบคลุมหลายเซสชัน) และระบบธุรกิจจำนวนมากเป็นธุรกรรมที่จัดการโดยฤดูใบไม้ผลิดังนั้น Mybatis จึงรวมเข้ากับฤดูใบไม้ผลิได้ดีที่สุด
ข้อกำหนดเวอร์ชัน
โครงการ | รุ่น | ดาวน์โหลดที่อยู่ | อธิบาย |
mybatis | 3.0 ขึ้นไป | https://github.com/mybatis/mybatis-3/releases | |
ฤดูใบไม้ผลิ | 3.0 ขึ้นไป | http://projects.spring.io/spring-framework/ | |
MyBatis-Spring | 1.0 ขึ้นไป | https://github.com/mybatis/spring/releases |
<!-การสแกนแบบอัตโนมัติของแพ็คเกจธุรกิจ-> <บริบท: คอมโพเนนต์-สแกนฐานแพคเกจ = "com.xxx.service"/> <!-แหล่งข้อมูล-> <jee: jndi-lookup id = "jndidataSource" jndi-name = "java: comp/env/env/jdbc/data > <property name = "dataSource" ref = "jndidataSource"/> </ebean> <!-กำหนดค่าสิ่งที่ใช้คำอธิบายประกอบ AOP-> <tx: การทำธุรกรรมที่ขับเคลื่อนด้วยคำอธิบายประกอบ
การบูรณาการเดียว
<!-การรวม MyBatis-> <bean id = "SQLSessionFactory"> <property name = "DataSource" ref = "jndidataSource" /> <property name = "การกำหนดค่า" value = "classpath: /mybatis/mybatis-config.xml" value = "com.xxx.dto" /> </ebean> <!-สร้างถั่ว dao (เพียงแค่ให้อินเทอร์เฟซ แต่ไม่ใช่คลาสการใช้งาน)-> <bean id = "userdao"> <property name = "mapperinterface" value = "com.xxx.dao.userdao" /> <
เราต้องไม่เข้าใจวิธีการใช้ แต่ยังเข้าใจว่าทำไมเราถึงใช้มันเช่นนี้
SQLSessionFactoryBean เป็นถั่วจากโรงงานและฟังก์ชั่นของมันคือการแยกวิเคราะห์การกำหนดค่า (แหล่งข้อมูลนามแฝง ฯลฯ )
MapperFactoryBean เป็นถั่วโรงงาน ในคอนเทนเนอร์ฤดูใบไม้ผลิถั่วโรงงานมีการใช้งานพิเศษ เมื่อฤดูใบไม้ผลิฉีดถั่วจากโรงงานเข้าไปในถั่วอื่นมันไม่ได้ฉีดถั่วจากโรงงาน แต่เรียกวิธี getObject ของถั่ว ลองมาดูกันว่าวิธี getObject นี้ทำอะไร:
สาธารณะ t getObject () โยนข้อยกเว้น {return getSqlSession (). getMapper (this.MapperInterface); -หลังจากเห็นสิ่งนี้คุณควรเข้าใจว่าวิธีนี้เหมือนกับเมื่อเราใช้ mybatis เพียงอย่างเดียว ก่อนอื่นเราจะได้รับวัตถุ SQLSession จากนั้นรับวัตถุ MAPPER จาก SQLSession (เทียบกับ Mapper เป็นวัตถุพร็อกซีซึ่งพร็อกซีอินเตอร์เฟสอินเตอร์เฟส Mapper และอินเทอร์เฟซนี้เป็นอินเทอร์เฟซ DAO ที่ผู้ใช้ให้ไว้) โดยธรรมชาติแล้วการฉีดเข้าสู่ชั้นธุรกิจครั้งสุดท้ายคือวัตถุ Mapper นี้
โดยทั่วไปการพูดมีมากกว่าหนึ่งโครงการ หากคุณมีหลายโครงการให้กำหนดค่าตามลำดับตามการกำหนดค่าข้างต้น
วิธีใช้การอัปเดตแบทช์
ส่วนก่อนหน้านี้พูดคุยเกี่ยวกับวิธีการฉีดวัตถุ Mapper ลงในชั้นธุรกิจ พฤติกรรมของผู้ทำแผนที่ขึ้นอยู่กับการกำหนดค่า MyBatis ใช้การอัปเดตเดียวโดยค่าเริ่มต้น (นั่นคือ Executortype เริ่มต้นง่ายแทนที่จะเป็นแบทช์) แน่นอนเราสามารถแก้ไขพฤติกรรมเริ่มต้นได้โดยการแก้ไขไฟล์การกำหนดค่า MyBatis แต่ถ้าเราต้องการเพียงหนึ่งหรือหลายตัวที่ใช้การอัปเดตแบตช์ก็ไม่สามารถทำได้ ในเวลานี้เราต้องใช้เทคโนโลยีเทมเพลต:
<!-ปรับแต่งพฤติกรรมของ mybatis ผ่านเทมเพลต-> lt; bean id = "sqlsessiontemplatesimple"> <constructor-Arg index = "0" ref = "sqlsessionfactory"/> <! lt; bean id = "sqlsessiontemplatebatch"> <constructor-arg index = "0" ref = "sqlsessionfactory"/> <!-อัปเดตในโหมดแบทช์-> <constructor-Arg index = "1" value = "batch"
ที่นี่ผู้เขียนกำหนดวัตถุเทมเพลตสองชิ้นโดยใช้การอัปเดตเพียงครั้งเดียวและอีกอันหนึ่งโดยใช้การอัปเดตแบทช์ หลังจากที่เรามีแม่แบบเราสามารถเปลี่ยนวิธีการทำแผนที่:
<bean id = "userdao"> <property name = "mapperinterface" value = "com.xxx.dao.userdao" /> <property name = "SQLSessionTemplate" REF = "SQLSessionTemplateBatch" /> </epean>
แตกต่างจากการกำหนดค่า Mapper ในส่วนก่อนหน้าไม่จำเป็นต้องกำหนดค่าคุณสมบัติ SQLSessionFactory ที่นี่คุณจะต้องกำหนดค่า SQLSessionTemplate (คุณสมบัติ SQLSessionFactory ได้รับการกำหนดค่าในเทมเพลต)
ทำให้การกำหนดค่าของ mappers ง่ายขึ้นด้วยการสแกนอัตโนมัติ
อย่างที่คุณเห็นในบทก่อนหน้า DAO ของเราจะต้องได้รับการกำหนดค่าทีละคนในไฟล์การกำหนดค่า หากมี DAO จำนวนมากไฟล์การกำหนดค่าจะมีขนาดใหญ่มากซึ่งจะเจ็บปวดมากขึ้นในการจัดการ โชคดีที่ทีม MyBatis ก็ตระหนักถึงสิ่งนี้เช่นกัน พวกเขาใช้ฟังก์ชั่นการสแกนอัตโนมัติที่จัดทำโดยฤดูใบไม้ผลิเพื่อห่อหุ้มคลาสเครื่องมือที่สแกนโดยอัตโนมัติเพื่อให้เราสามารถใช้ฟังก์ชั่นนี้เพื่อทำให้การกำหนดค่าง่ายขึ้น:
<!-สร้าง Mapper Bean โดยใช้การสแกนอัตโนมัติ (โหมดการอัปเดตเดี่ยว)-> <bean> <property name = "basepackage" value = "com.xxx.dao" /> <name property = "SQLSessionTemplateBeanName" value.sessessionTemplatesimple " /> < </epean> <!-สร้าง Mapper Bean โดยใช้การสแกนอัตโนมัติ (โหมดการอัปเดตแบทช์)-> <bean> <property name = "basepackage" value = "com.xxx.dao" /> <property name = "sqlsessionTemplateBeanName" value = "sqlSessionTemplateBatch" /> value = "com.xxx.dao.batchdao" /> </ebean>
ฉันจะไม่พูดถึงเทคโนโลยีฤดูใบไม้ผลิที่เกี่ยวข้องกับ MapperscannerConfigurer หากคุณสนใจและมีความเข้าใจที่ดีเกี่ยวกับหลักการของฤดูใบไม้ผลิคุณสามารถตรวจสอบซอร์สโค้ดได้ มามุ่งเน้นไปที่คุณสมบัติทั้งสาม:
นอกเหนือจากการใช้การกรองอินเทอร์เฟซคุณยังสามารถใช้การกรองคำอธิบายประกอบ:
<!-สร้าง Mapper Bean โดยใช้การสแกนอัตโนมัติ (โหมดอัปเดตแบบแบทช์)-> <Bean> <property name = "basepackage" value = "com.xxx.dao" /> <property name = "SQLSessionTemplateBeanName" value.DantEntation " </ebean>
AnnotationClass: เฉพาะเมื่อมีการกำหนดค่าคำอธิบายประกอบจะถูกสแกนโดยสแกนเนอร์และ basepackage เป็นฟังก์ชั่นเดียวกัน
ควรสังเกตว่ามีเพียงหนึ่งในสองเงื่อนไขตัวกรองเท่านั้นที่สามารถจับคู่ได้
ตัวอย่าง: การจัดการธุรกรรม
กำหนดคลาสเอนทิตี: emp.java
แพ็คเกจ com.lixing.scm.entity; ระดับสาธารณะ EMP {รหัสสตริงส่วนตัว; ชื่อสตริงส่วนตัว; เซ็กซ์สตริงส่วนตัว; อายุ int ส่วนตัว; โทรศัพท์สตริงส่วนตัว สตริงสาธารณะ getId () {return id; } โมฆะสาธารณะ setId (รหัสสตริง) {this.id = id; } สตริงสาธารณะ getName () {ชื่อคืน; } โมฆะสาธารณะ setName (ชื่อสตริง) {this.name = name; } Public String getSex () {return sex; } โมฆะสาธารณะ setsex (String sex) {this.sex = sex; } public int getage () {return Age; } การตั้งค่าโมฆะสาธารณะ (อายุ int) {this.age = อายุ; } สตริงสาธารณะ getphone () {ส่งคืนโทรศัพท์; } โมฆะสาธารณะ setphone (โทรศัพท์สตริง) {this.phone = โทรศัพท์; - กำหนดอินเทอร์เฟซการทำงานภายใน: empmapper.java
แพ็คเกจ com.lixing.scm.test.mapper; นำเข้า java.util.list; นำเข้า java.util.map; นำเข้า com.lixing.scm.entity.emp; อินเตอร์เฟสสาธารณะ empmapper {void insertemp (EMP EMP); รายการ <EMP> getAlleMP (); EMP getById (รหัสสตริง); เป็นโมฆะ DELETEEMP (String ID); เป็นโมฆะ UpdateMP (แผนที่ <สตริงวัตถุ> แผนที่);} กำหนดไฟล์การแมปสำหรับอินเทอร์เฟซการทำงานของคลาสเอนทิตี: empmapper.xml
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <! doctype mapper สาธารณะ "-// mybatis.org//dtd mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" namespace = "com.lixing.scm.test.mapper.empmapper"> <parametermap type = "com.lixing.scm.entity.emp" id = "parameterMapemp"> <พารามิเตอร์คุณสมบัติ = "id"/> <พารามิเตอร์คุณสมบัติ = "ชื่อ"/> <พารามิเตอร์ <resultmap type = "com.lixing.scm.entity.emp" id = "resultmapemp"> <property result = "id" คอลัมน์ = "id"/> <property result = "name" คอลัมน์ = "name"/> <property = "sex" = "sex"/> <property result = "อายุ"/> < id = "insertEmp" parameterMap = "parameterMapemp"> แทรกลงใน emp (id, ชื่อ, เพศ, อายุ, โทรศัพท์) ค่า (?,?,?,?,?) </แทรก> <select id = "getAlleMp" selectmap = "parametmap" จาก emp โดยที่ id =#{value} </select> <delete id = "deleteemp" parameterType = "String"> ลบจาก EMP โดยที่ id =#{value} </deLete> <update id = "updateemp" parameterType = "java.util.map" name =#{name}, sex =#{sex}, age =#{อายุ}, โทรศัพท์ =#{โทรศัพท์} โดยที่ id =#{id} </update> </mapper> spring3.0.6 คำจำกัดความ: applicationcontext.xml <? xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: บริบท = "http:/ xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalocation = "http:/ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!--> <บริบท: Annotation-config/> <บริบท: Component-Scan base-package =" com.scm.scm.test.*"/> <! value = "classpath: jdbc.properties" /> </ebean> <bean id = "myDataSource" destroy-method = "ปิด"> <property name = "driverclassName" value = "$ {jdbc.driverclassName}" value = "$ {jdbc.username}" /> <property name = "password" value = "$ {jdbc.password}" /> </ebean> <!-sqlsessionfactory-> <bean id = "sqlsessionfactory"> <property name = "dataSource" <property name = "basepackage" value = "com.lixing.scm.test.mapper" /> </ebean> <!-! - <bean name = "transactionManager"> <property name = "dataSource" ref = "myDataSource"> </property> </epean> <tx: idead id = "usertxadvice" transaction-manager = "transactionManager"> <tx: attributes> <tx Rollback-for = "java.lang.exception" no-rollback-for = "java.lang.runtimeException" /> <tx: method name = "Insert*" การแพร่กระจาย = "จำเป็น" read-only = "false" method*adplack-for-for-for RollBack-for = "java.lang.exception"/> <tx: method name = "ค้นหา*" การแพร่กระจาย = "สนับสนุน"/> <tx: method name = "get*" การแพร่กระจาย = "สนับสนุน"/> <tx: method = "select*" propagation = "สนับสนุน"/> expression = "การดำเนินการ (สาธารณะ*com.lixing.scm.test.service.*.*(.. ))" /> <!-การควบคุมการทำธุรกรรมในระดับการบริการ-> <aop: ที่ปรึกษา pointcut-ref = "pc" ref = "usertxadvice" /> < /aop: <bean id = "empservice" autoWire = "byname"/> </ebeans> อินเทอร์เฟซ Dao: empdao.java
แพ็คเกจ com.lixing.scm.test.dao; นำเข้า java.util.list; นำเข้า java.util.map; นำเข้า com.lixing.scm.entity.emp; อินเตอร์เฟสสาธารณะ empdao {void insertemp (EMP EMP); รายการ <EMP> getAlleMP (); EMP getById (รหัสสตริง); เป็นโมฆะ DELETEEMP (String ID); เป็นโมฆะ UpdateMP (แผนที่ <สตริงวัตถุ> แผนที่);} คลาสการใช้งานอินเทอร์เฟซ DAO: empdaoimpl.java
แพ็คเกจ com.lixing.scm.test.dao.impl; นำเข้า java.util.list; นำเข้า java.util.map; นำเข้า com.lixing.scm.entity.emp; นำเข้า com.lixing.scm.test.dao.empdao; นำเข้า com.lixing.scm.test. Empmapper ส่วนตัว Empmapper; // ฉีด empmapper ที่นี่ // empmapper นี้ถูกสร้างขึ้นโดยอัตโนมัติโดยฤดูใบไม้ผลิ // เราไม่จำเป็นต้องกำหนด @Override โมฆะสาธารณะ insertemp (EMP EMP) {this.empmapper.insertemp (EMP); โยน runtimeException ใหม่ ("ข้อผิดพลาด"); // ทดสอบการโยน runtimeException // ข้อยกเว้นเพื่อดูว่าฐานข้อมูลมีบันทึก} @Override โมฆะสาธารณะ deleteemp (String ID) {this.empmapper.deleteemp (ID); } @Override รายการสาธารณะ <Emp> getAlleMp () {return this.empmapper.getAllemp (); } @Override สาธารณะ emp getById (รหัสสตริง) {return this.empmapper.getById (id); } @Override โมฆะสาธารณะอัพเดท (แผนที่ <สตริงวัตถุ> แผนที่) {this.empmapper.updateemp (แผนที่); } สาธารณะ empmapper getempmapper () {return empmapper; } โมฆะสาธารณะ setempmapper (empmapper empmapper) {this.empmapper = empmapper; - อินเทอร์เฟซเลเยอร์บริการ: empservice.java
แพ็คเกจ com.lixing.scm.test.service; นำเข้า com.lixing.scm.entity.emp; อินเตอร์เฟสสาธารณะ empservice {void insertemp (EMP EMP);} คลาสการใช้งาน Layer Interface: empserviceimpl.java
แพ็คเกจ com.lixing.scm.test.service.impl; นำเข้า com.lixing.scm.entity.emp; นำเข้า com.lixing.scm.test.dao.empdao; นำเข้า com.lixing.scm.test.service.empservice; @Override โมฆะสาธารณะ InserTEMP (EMP EMP) {Empdao.insertemp (EMP); } สาธารณะ empdao getempdao () {return empdao; } โมฆะสาธารณะ setempdao (empdao empdao) {this.empdao = empdao; - คลาสทดสอบ: testempservice.java
นำเข้า org.junit.test; นำเข้า org.springframework.context.applicationContext; นำเข้า org.springframework.context.support.classpathxmlapplicationContext; นำเข้า com.lixing.scm.entity.emp; testtrasaction () {emp emp = new emp (); emp.setId ("00000003"); emp.setName ("某某某"); EMP.Setage (50); emp.setsex ("ชาย"); emp.setphone ("5666666"); ApplicationContext ctx = ใหม่ classpathxmlapplicationContext ("classpath: applicationcontext.xml"); บริการ Empservice = ctx.getBean (empservice.class); Service.inSertemp (EMP); -