Objectives:
- Mybatis and spring integration
- Aop integration pagehelper plug-in
1, Mybatis and spring integration
Comparison of hibernate and spring integration
1. Import pom dependencies
1.1 add spring related dependencies (5.0.2.RELEASE)
spring-core
spring-beans
spring-context
spring-orm
spring-tx
spring-aspects
spring-web
1.2 add dependency related to mybatis
Mybatis core: mybatis(3.4.5)
Mybatis paging: pagehelper(5.1.2)
1.3 spring integration mybatis(1.3.1)
mybatis-spring
1.4 adding dbcp2 connection pool
commons-dbcp2(2.1.1)
commons-pool2(2.4.3)
1.5 add log configuration (2.9.1)
log4j-core
log4j-api
log4j-web
1.6 others
junit(4.12)
javax.servlet-api(4.0.0)
lombok(1.18.2)
Note: use mybatis generator plug-in to add pom file support
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>NEW</artifactId> <groupId>com.xhy</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>SSM</artifactId> <packaging>war</packaging> <name>SSM Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version> <!--add to jar Package dependency--> <!--1.spring 5.0.2.RELEASE relevant--> <spring.version>5.0.2.RELEASE</spring.version> <!--2.mybatis relevant--> <mybatis.version>3.4.5</mybatis.version> <!--mysql--> <mysql.version>5.1.44</mysql.version> <!--pagehelper paging jar rely on--> <pagehelper.version>5.1.2</pagehelper.version> <!--mybatis And spring integrate jar rely on--> <mybatis.spring.version>1.3.1</mybatis.spring.version> <!--3.dbcp2 Connection pool related druid--> <commons.dbcp2.version>2.1.1</commons.dbcp2.version> <commons.pool2.version>2.4.3</commons.pool2.version> <!--4.log Log correlation--> <log4j2.version>2.9.1</log4j2.version> <!--5.other--> <junit.version>4.12</junit.version> <servlet.version>4.0.0</servlet.version> <lombok.version>1.18.2</lombok.version> </properties> <dependencies> <!--1.spring relevant--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!--2.mybatis relevant--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <!--pagehelper Paging plug-in jar Package dependency--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>${pagehelper.version}</version> </dependency> <!--mybatis And spring integrate jar Package dependency--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis.spring.version}</version> </dependency> <!--3.dbcp2 Connection pool related--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>${commons.dbcp2.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>${commons.pool2.version}</version> </dependency> <!--4.log Log dependent dependencies--> <!--core log4j2jar package--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${log4j2.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>${log4j2.version}</version> </dependency> <!--web The project needs to include log4j-web,wrong web The project does not require--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>${log4j2.version}</version> </dependency> <!--5.other--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>SSM</finalName> <resources> <!--solve mybatis-generator-maven-plugin The runtime did not XxxMapper.xml File put target Problems with folders--> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <!--solve mybatis-generator-maven-plugin The runtime did not jdbc.properites File put target Problems with folders--> <resource> <directory>src/main/resources</directory> <includes> <include>jdbc.properties</include> <include>*.xml</include> </includes> </resource> </resources> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> <configuration> <source>${maven.compiler.source}</source> <target>${maven.compiler.target}</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <dependencies> <!--use Mybatis-generator Plug ins cannot use too high versions mysql drive --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> </dependencies> <configuration> <overwrite>true</overwrite> </configuration> </plugin> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
2. Use mybatis reverse engineering to generate model layer by layer code
Import the configuration file of reverse engineering in the first introduction to mybatis
Import all java files from the previous section
3. Write the configuration file ApplicationContext mybatis xml
①. step
3.1 annotated development
Open annotation
<!-- 1. Annotated Development -- >
<!-- Annotation driven -- >
<context:annotation-config/>
<!-- Inject bean s with annotations and specify the search range: com javaxl. SSM and grandchild package -- >
<context:component-scan base-package="com.javaxl.ssm"/>
3.2 importing external jdbc configuration files
<context:property-placeholder location="classpath:jdbc.properties"/>
3.3 configuring dbcp2 database connection pool
3.4 integration of spring and mybatis
3.5 annotation configuration
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="data Source" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
3.6 enable dynamic agent
<aop:aspectj-autoproxy/>
3.7 annotated development
@ Repository: declare DAO class as Bean
@ Service: usually works in the business layer
@ constreller: it usually acts on the control layer and will be used in Spring MVC
@ Component: is a generalized concept. It only represents a Component (Bean) in spring and can act at any level
@ Scope: schema declaration (singleton|prototype)
@ Autowired: the Bean that matches it in the code context (type matching by default) will be automatically injected into the corresponding place
@Resource:
1) there is nothing behind @ Resource. By default, the bean is matched through the name attribute. If it cannot be found, match it by type
2) if name or type is specified, the bean will be matched according to the specified type
3) if name and type are specified, bean s will be matched according to the specified name and type. Any mismatch will result in an error
* question: @ Autowired and @ Resource are different:
1) @ Autowired performs bean matching in byType mode by default, and @ Resource performs bean matching in byName mode by default
2) @ Autowired is the annotation of Spring and @ Resource is the annotation of J2EE. When you look at the imported annotation, the package names of the two annotations will be clear
Spring belongs to a third party, and J2EE is Java's own thing. Therefore, it is recommended to use @ Resource annotation to reduce the coupling between code and spring.
@Transactional
Note: I personally feel that annotated transactions are more troublesome and need to write more things than previous declarative transactions
applicationContext-mybatis.xml
<?xml version="1.0" encoding="UTF-8"?> <beans 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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--1. Annotated development --> <!-- Annotation driven --> <context:annotation-config/> <!-- Annotation injection bean,And specify the search range: com.xhy.ssm And children and grandchildren--> <context:component-scan base-package="com.xhy"/> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <!--Number of initial connections--> <property name="initialSize" value="10"/> <!--Maximum number of active connections--> <property name="maxTotal" value="100"/> <!--Maximum number of free connections--> <property name="maxIdle" value="50"/> <!--Minimum number of free connections--> <property name="minIdle" value="10"/> <!--Set to-1 If no connection is available, the connection pool will wait indefinitely until the connection is obtained.--> <!--If set to N(Milliseconds), the connection pool waits N Milliseconds. If it cannot wait, an exception is thrown--> <property name="maxWaitMillis" value="-1"/> </bean> <!--4. spring and MyBatis integration --> <!--1) establish sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- specify data source --> <property name="dataSource" ref="dataSource"/> <!-- Automatic scanning XxxMapping.xml Documents,**Arbitrary path --> <property name="mapperLocations" value="classpath*:com/xhy/**/mapper/*.xml"/> <!-- Specify alias -- > <property name="typeAliasesPackage" value="com/xhy/ssm/**/model"/> <!--to configure pagehelper plug-in unit--> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <value> helperDialect=mysql </value> </property> </bean> </array> </property> </bean> <!--2) Automatic scanning com/xhy/ssm/**/mapper All xmapper interfaces (actually DAO interfaces) under and implement these interfaces, -- > <!-- You can directly use the dao interface in the program without obtaining the sqlsession object -- > <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--basePackage Property is the package path of the mapper interface file. -- > <!--You can use semicolons or commas as as separators to set more than one package path -- > <property name="basePackage" value="com/xhy/ssm/**/mapper"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <aop:aspectj-autoproxy/> </beans>
Control the ApplicationContext of the consolidation profile xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--integration mybits--> <import resource="applicationContext-mybatis.xml"></import> </beans>
4. Perfect combination of spring test + JUnit
Add the dependency of spring test in the pom file of the project
Already joined
Add comments in BookServiceImplTest2:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:applicationContext-mybatis.xml"})
Annotate BookServiceImpl in the service layer
Add annotation without writing get/set constructor
Then add notes to bookservice in BookServiceImplTest2:
Test:
II. Aop integrated pagehelper plug-in
No coding required for pagination before the plug-in:
Summary and analysis:
1. Define paging method, which must pass at least two parameters
2. Key points of pagination:
①pageBean
②pageHelper
3. Logical sequence of codes
*PgaeHelper.startpage: start paging
Normal business query
*Process query result set
1. What needs to be considered in the section
*PgaeHelper.startpage , start paging , and * processing query result sets need to be added to the surround notification
2. Rules (* pager) should be defined on the facet class. Only paging methods can enter the facet class
3. You must judge whether * pager passed pagebean
Coding phase:
1. Get the parameter list of the proxy method and traverse it. If the list contains pagebean, assign a value to the pagebean
2. Core code
*PgaeHelper.startpage: start paging
*Process query result set
code:
Add comments: @ around ("execution (* *. * service. * pager (..)")
Syntax structure: execution (method modifier, method return value, method class matching method name (formal parameter table in method), exception thrown by method declaration)
"*": represents an arbitrary type of parameter;
“..”: Represents zero or more parameters of any type.
package com.xhy.aspect; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.xhy.util.PageBean; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import java.util.List; public class PagerAspect { @Around("execution(* *..*Service.*Pager(..))") public Object invoke(ProceedingJoinPoint args) throws Throwable { Object[] params = args.getArgs(); PageBean pageBean = null; for (Object param : params) { if(param instanceof PageBean){ pageBean = (PageBean)param; break; } } if(pageBean != null && pageBean.isPagination()) PageHelper.startPage(pageBean.getPage(),pageBean.getRows()); Object list = args.proceed(params); if(null != pageBean && pageBean.isPagination()){ PageInfo pageInfo = new PageInfo((List) list); pageBean.setTotal(pageInfo.getTotal()+""); } return list; } }
Operation results: