Existem muitas limitações ao usar o Mybatis sozinho (como não ser capaz de implementar transações abrangendo várias sessões), e muitos sistemas de negócios são originalmente transações gerenciadas pela primavera, para que o Mybatis seja melhor integrado à primavera.
Requisitos de versão
projeto | Versão | Endereço para download | ilustrar |
mybatis | 3.0 e acima | https://github.com/mybatis/mybatis-3/releases | |
primavera | 3.0 e acima | http://projects.spring.io/spring-framework/ | |
mybatis-spring | 1.0 e acima | https://github.com/mybatis/spring/releases |
<!-varredura automática de pacotes comerciais-> <Contexto: componente-cacan back-package = "com.xxx.service"/> <!-fonte de dados-> <jee: jndi-llookup id = "jndidataSource"/jndi-name = "java: comp/env/jdbc/dataSource"/ <Nome da propriedade = "DataSource" ref = "JndidataSource"/> </bean> <!-Configure coisas baseadas em anotação AOP-> <tx: transação orientada por anotação
Integração única
<!-Integração de mybatis-> <bean id = "sqlSessionFactory"> <propriedade name = "DataSource" ref = "jndidataSource" /> <nome da propriedade = "configLocation" value = "Classpath: /mybatis/mybatis-config.xml = (! value = "com.xxx.dto" /> < /bean> <!-Crie Dao Bean (basta fornecer interfaces, mas não classes de implementação)-> <bean id = "userdao"> <names name = "mapperInterfacer")
Devemos não apenas entender como usá -lo, mas também entendemos por que o usamos assim.
O SQLSessionFactoryBean é um feijão de fábrica, e sua função é analisar as configurações (fonte de dados, alias etc.).
MapperFactoryBean é um feijão de fábrica. No recipiente de primavera, os feijões de fábrica têm usos especiais. Quando a mola injeta grãos de fábrica em outros grãos, ele não injeta o próprio feijão de fábrica, mas chama o método GetObject do feijão. Vamos dar uma olhada no que esse método GetObject faz:
public t getObject () lança exceção {return getsqlSession (). getMapper (this.mapperInterface); }Depois de ver isso, você deve entender que esse método é o mesmo de quando usamos o Mybatis sozinho. Primeiro, obtemos um objeto SQLSession e, em seguida, obtemos o objeto Mapper do SQLSession (contra o mapeador é um objeto proxy, que proxies a interface da interface do mapeador, e essa interface é a interface DAO fornecida pelo usuário). Naturalmente, a injeção final na camada de negócios é esse objeto de mapeador.
De um modo geral, há mais de um projeto. Se você tiver vários projetos, configure -os em sequência de acordo com a configuração acima.
Como usar atualizações em lote
A seção anterior falou sobre como injetar um objeto de mapeador na camada de negócios. O comportamento do mapeador depende da configuração. O Mybatis usa uma única atualização por padrão (ou seja, o ExecutionType padrão é simples em vez de lote). Obviamente, podemos modificar o comportamento padrão modificando o arquivo de configuração Mybatis, mas se quisermos apenas um ou vários mapeadores para usar atualizações em lote, isso não poderá ser feito. Neste momento, precisamos usar a tecnologia de modelo:
<!-personalizar o comportamento de mybatis através de modelos-> lt; bean id = "sqlSessionTemplatesImple"> <construtor-arg index = "0" ref = "sqlsessfactory"/> <!-atualização em um modo único-> <constror-arg Índice = "1" value = "simples"/> <! lt; bean id = "sqlSessionTemplateBatch"> <construtor-arg index = "0" ref = "sqlSessionFactory"/> <!-Atualização em um modo em lote-> <construtor-arg index = "1" value = "Batch"/> </bean>
Aqui, o autor define dois objetos de modelo, um usando uma única atualização e outra usando a atualização em lote. Depois de termos o modelo, podemos mudar a maneira como o Mapper se comporta:
<bean id = "userdao"> <propriedade name = "mapperInterface" value = "com.xxx.dao.userdao" /> <propriedade name = "sqlsessionTemplate" ref = "sqlSessionTemplateBatch" /> < /bean>
Diferente da configuração do mapeador na seção anterior, não há necessidade de configurar a propriedade SQLSessionFactory aqui, você só precisa configurar o SQLSessionTemplate (a propriedade SQLSessionFactory foi configurada no modelo).
Simplifique a configuração dos mapeadores com varredura automática
Como você pode ver no capítulo anterior, nosso DAO precisa ser configurado um por um no arquivo de configuração. Se houver muitos DAO, o arquivo de configuração será muito grande, o que será mais doloroso de gerenciar. Felizmente, a equipe Mybatis também percebeu isso. Eles usaram a função de varredura automática fornecida pelo Spring para encapsular uma classe de ferramentas que digitaliza automaticamente, para que possamos usar essa função para simplificar a configuração:
<!-Crie Bean Mapepper usando varredura automática (modo de atualização única)-> <Bean> <propriedade name = "BasEpackage" value = "com.xxx.dao" /> <propriedade name = "sqlsessionTemplateBeanName" value = "sqlSessionTemImplexxxx /> names) < /bean> <!-Crie o mapeador usando varredura automática (modo de atualização em lote)-> <Bean> <propriedade name = "BasEpackage" value = "com.xxx.dao" /> <propriedades name = "sqlSessionTemplateBeanName" Value = "sqlSessionTemplateBatch" /> (NamenName = = =) " value = "com.xxx.dao.batchdao" /> < /bean>
Não vou falar sobre a tecnologia da primavera envolvida no próprio MapperScannerConfigurer. Se você estiver interessado e tiver uma boa compreensão dos princípios da primavera, pode verificar seu código -fonte. Vamos nos concentrar em suas três propriedades:
Além de usar a filtragem de interface, você também pode usar a filtragem de anotação:
<!-Crie Bean Mapper usando varredura automática (modo de atualização em lote)-> <Bean> <propriedade name = "BasEpackage" value = "com.xxx.dao" /> <names name = "sqlsessionTemplateBeanName" value = "sqlSessionTemplateBatch" /> (names) </ Bean>
AnoTationClass: Somente quando a anotação estiver configurada será digitalizada pelo scanner, e o BasePackage é a função da mesma.
Deve -se notar que apenas uma das duas condições de filtro pode ser correspondida.
Exemplo: Gerenciamento de transações
Defina uma classe de entidade: Emp.java
pacote com.lixing.scm.entity; public class EMP {private string ID; nome de string privado; sexo privado de cordas; private Int Age; telefone de corda privada; public string getId () {return id; } public void setId (string id) {this.id = id; } public string getName () {return name; } public void setName (nome da string) {this.name = name; } public string getSex () {return Sex; } public void SetSex (sexo de string) {this.sex = sexo; } public int getage () {Age de retorno; } public void setage (int Age) {this.age = Age; } public string getphone () {return telefone; } public void setPhone (string telefone) {this.phone = telefone; }} Defina a interface de operação interna: Empmapper.java
pacote com.lixing.scm.test.mapper; importar java.util.list; importar java.util.map; importar com.lixing.scm.entity.emp; interface pública empmapper {void insertemp (emp emp); Lista <EMP> getallemp (); EMP getById (string ID); void Deleteemp (string ID); void updateemp (map <string, objeto> map);} Defina o arquivo de mapeamento da interface de operação da classe de entidade: Empmapper.xml
<? xml versão = "1.0" coding = "utf-8"?> <! namespace = "com.lixing.scm.test.mapper.empmapper"> <parametermap type = "com.lixing.scm.entity.emp" id = "parameTerMapeMp"> <parâmetro de propriedade = "id"/> <parameter Propriedade = "name"/> <parâmetro de propriedade "/"/> <parâmetro <resultMap type="com.lixing.scm.entity.Emp" id="resultMapEmp"> <result property="id" column="id"/> <result property="name" column="name"/> <result property="sex" column="sex"/> <result property="age"/> <result property="age" column="age"/> <result property="phone"/> </resultMap> <insert id = "insertemp" parameTerMap = "parameTerMapeMp"> inserir no emp (id, nome, sexo, idade, telefone) valores (?,?,?,?) </insert> <select id = "getallemp" resultMap = "resultMapemp"> select * de EMP </select> <dds = "getById" De empado onde id =#{value} </select> <delete id = "deleteemp" parameterType = "string"> exclua do emp. Onde id =#{value} </lete> <update id = "updateemp" parametertype = "java.util.map"> atualizar emp definido nome =#{nome}, sexo =#{sex}, idade =#{idade}, telefone =#{telefone} onde id =#{id} </puta> </mapper> spring3.0.6 Definição: ApplicationContext.xml <? xml versão = "1.0" coding = "utf-8"? xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tc-3.0.xsd http://wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.spring-tx-3.0.xsch http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!--> <Contexto: AnoTation-Config/> <Contexto: Component-Scan Base-Package =" Com.lixing.ERTM.Test.*"/> <! value = "ClassPath: jdbc.properties" /> </ Bean> <bean id = "myDataSource" destrow-method = "close"> <propriedade name = "driverClassName" value = "$ {jdbc.driverclassName}" /> <nome da propriedade = " /" value = "$ {{JDB" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- SqlSessionFactory --> <bean id="sqlSessionFactory"> <property name="dataSource" ref="MyDataSource" /> </bean> <!-- ScanMapperFiles --> <bean> <Propriedade name = "BasEpackage" value = "com.lixing.scm.test.mapper" /> </shean> <!- ================================================================================================================== --> <bean name = "transactionManager"> <propriedade name = "DataSource" ref = "myDataSource"> </propriedade> </bean> <tx: conselhos id = "usertxadvice" transação-manager = "transação como"> <TX: atribututes> <-tx: nome do método = "delate*" propagação rollback para = "java.lang.Exception" no rollback-for = "java.lang.runtimeException" /> <tx: método name = "insert*" propagation = "requerir" read -ly = "false" rollback para = "java.lang.RuntimeException" /> <TX: Method) rollback for = "java.lang.exception"/> <tx: método name = "find*" propagation = "suporta"/> <tx: método name = "get*" propagation = "suporta"/> <tx: name "select*" "suportes"/> </tx: atributes> </tx = " Expression = "Execution (public*com.lixing.scm.test.service. Autowire = "Byname"/> <bean id = "empervice" AutoWire = "Byname"/> </ Beans> Interface Dao: empdao.java
pacote com.lixing.scm.test.dao; importar java.util.list; importar java.util.map; importar com.lixing.scm.entity.emp; interface pública empdao {void insertemp (EMP EMP); Lista <EMP> getallemp (); EMP getById (string ID); void Deleteemp (string ID); void updateemp (map <string, objeto> map);} Classe de implementação da interface dao: empdaoimpl.java
pacote com.lixing.scm.test.dao.impl; importar java.util.list; importar java.util.map; importar com.lixing.scm.entity.emp; import com.lixing.spSp.Test.Dao.empdao; import.lixing.aSP.Papper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.Mapper.MapPer.Mapper.MapMPMPMPMPMPMO; Empmapper Empmapper; // injete um empmapper aqui // Este Empmapper é gerado automaticamente por Spring // não precisamos definir manualmente @Override public void insertemp (emp) {this.empmapper.insertemp (EMP); lançar a nova RuntimeTimeException ("Erro"); // O teste lança RUNTimeException // Exceção Para ver se o banco de dados possui registros} @Override public void Deleteemp (String ID) {this.empmapper.deleteemp (id); } @Override Public List <Emp> getallemp () {return this.empmapper.getallemp (); } @Override public emp getByid (string id) {return this.empmapper.getbyid (id); } @Override public void updateemp (map <string, object> map) {this.empmapper.updateemp (map); } public empmapper getempmapper () {return empmapper; } public void setempmapper (empmapper empmapper) {this.empmapper = empmapper; }} Interface da camada de serviço: EmpService.java
pacote com.lixing.scm.test.service; importar com.lixing.scm.entity.emp; interface pública Empservice {void insertemp (emp);} Classe de implementação da interface da camada de serviço: EmpserviceImpl.java
pacote com.lixing.scm.test.service.impl; importar com.lixing.scm.entity.emp; importar com.lixing.scm.test.dao.empdao; importação com.lixing.scm.test.service.empService; a classe pública EmpsiceImpl Empsere; @Override public void insertemp (EMP EMP) {EMPDAO.INSERTEMP (EMP); } public empdao getempdao () {return empdao; } public void setempdao (empdao empdao) {this.empdao = empdao; }} Classe de teste: testempService.java
importar org.junit.test; importar org.springframework.context.applicationContext; importar org.springframework.context.support.classPathXMLApplicationContext; import.lixing.scm.entity.emp; import.lixing.sscm.testrice; testtraSAction () {EMP EMP = new EMP (); EMP.SETID ("00000003"); Emp.setName ("某某某"); EMP.Setrage (50); Emp.SetSex ("masculino"); Emp.setphone ("566666"); ApplicationContext ctx = new ClassPathXMLApplicationContext ("ClassPath: ApplicationContext.xml"); Service empService = ctx.getBean (Empservice.class); Service.Insertemp (EMP); }}