注:整合就直接使用dao的接口,不需要dao的实现类
Spring和MyBatis的整合步骤
- 建立Web工程,加入Spring和MyBatis的有关JAR
- 建立开发目录结构,创建实体类
- 创建数据访问接口
- 创建数据访问接口的实现类
- 配置SQL映射语句文件
- 配置MyBatis应用配置文件
- 配置Spring应用配置文件
要在Spring中使用MyBatis,需要在Spring的配置文件中定义一些类
- SqlSessionFactoryBean --- 为整合应用提供SqlSession对象资源
- SqlSessionTemplate --- 负责管理MyBatis的SqlSession,调用SQL映射语句,实现对数据库的访问
- MapperFactoryBean --- 根据指定Mapper接口生成Bean实例
- MapperScannerConfigurer --- 根据指定包批量扫描Mapper接口并生成实例
使用MapperFactoryBean注入映射器
采用数据映射器(MapperFactoryBean)的方式完成对数据库操作
- 根据Mapper接口获取Mapper对象,它封装了原有的SqlSession.getMapper()功能的实现
- 映射器对应的SQL映射文件与映射器的类路径相同,该映射文件可以自动被MapperFactoryBean解析
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--指定映射器,只能是接口类型-->
<property name="mapperInterface" value="cn.smbms.dao.user.UserMapper"/>
<!--注入SqlSessionFactory以提供SqlSessionTemplate实例-->
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
若映射器很多的话,相应的配置项也会很多,如何简化配置工作量?
MapperScannerConfigurer
- 自动扫描指定包下的Mapper接口,并将它们直接注册为MapperFactoryBean
- MapperScannerConfigurer递归扫描基准包下所有接口,若它们在SQL映射文件中定义过,则动态注册为MapperFactoryBean,如此即可批量产生映射器实现类
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指定扫描的基准包-->
<property name="basePackage" value="cn.smbms.dao" />
</bean>
MapperScannerConfigurer 与@Autowired注解或@Resource注解配合使用,自动创建映射器实现并注入给业务组件,能够最大限度地减少DAO组件与业务组件的编码和配置工作
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired // 或 @Resource
private UserMapper userMapper;
//……代码省略
}
<!-- 省略数据源、 SqlSessionFactoryBean的相关配置 -->
<!-- 配置DAO -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.smbms.dao" />
</bean>
<!-- 配置扫描注解定义的业务Bean -->
<context:component-scan base-package="cn.smbms.service" />
一、pom.xml配置添加jar依赖
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.gwj</groupId>
<artifactId>bill</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>bill 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>
<!-- mysql版本 -->
<mysql.version>8.0.16</mysql.version>
<!-- log4j日志包版本号 -->
<slf4j.version>1.7.18</slf4j.version>
<log4j.version>1.2.17</log4j.version>
<!-- spring版本号 -->
<spring.version>5.1.8.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- 添加mysql驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
<!-- 添加日志相关jar包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>
<!-- 添加spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</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-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!--aop-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!--aspect依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- DBCP连接池-->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
</project>
二、创建数据访问接口及实现类
package cn.gwj.dao;
/*
Created by IntelliJ IDEA.
Package:cn.gwj.dao
User:1093499975@qq.com
Date:2019/7/9 0009
Time:14:27
*/
import cn.gwj.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserDao {
/**
* 通过userCode获取User
* @param userCode
* @return
* @throws Exception
*/
public User getLoginUser(String userCode)throws Exception;
}
package cn.gwj.dao;
import cn.gwj.entity.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Repository;
import java.util.List;
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{
@Override
public User getLoginUser(String userCode) throws Exception {
return this.getSqlSession().getMapper(UserDao.class).getLoginUser(userCode);
}
}
package cn.gwj.service.user;
import cn.gwj.entity.User;
public interface UserService {
public User login(String userCode, String userPassword);
}
package cn.gwj.service.user;
import cn.gwj.dao.UserDao;
import cn.gwj.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService{
@Override
public User login(String userCode, String userPassword) {
// TODO Auto-generated method stub
User user = null;
try {
//user = userDao.getLoginUser(userCode);
user = userDao.getLoginUser(userCode);
System.out.println("实现类:"+user.getUserPassword());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//MybatisUtil.closeSqlSession(sqlSession);
}
//匹配密码
if(null != user){
if(!user.getUserPassword().equals(userPassword))
user = null;
}
return user;
}
}
三、配置SQL映射语句文件UserDao.xml(mybatis)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--cn.cxh.dao.UserDao 接口-->
<mapper namespace="cn.gwj.dao.UserDao">
<!--结果集映射-->
<resultMap id="userMap" type="User">
<!--property是查询的实体类属性,column相当于数据库查询的结果集名称-->
<!--id为主键-->
<id property="id" column="id"/>
<result property="userCode" column="userCode"/>
<result property="userName" column="userName"/>
<result property="userPassword" column="userPassword"/>
<!--一对一关系,内部映射-->
<!--javaType对应的实体类-->
<!--<association property="role" javaType="Role">-->
<!--<id property="id" column="userRole"/>-->
<!--<result property="roleCode" column="roleCode"/>-->
<!--<result property="roleName" column="roleName"/>-->
<!--</association>-->
<!--外部映射-->
<association property="role" resultMap="roleMap"/>
</resultMap>
<resultMap id="roleMap" type="Role">
<id property="id" column="userRole"/>
<result property="roleCode" column="roleCode"/>
<result property="roleName" column="roleName"/>
</resultMap>
<select id="getLoginUser" parameterType="String" resultMap="userMap">
select * from smbms_user where userCode=#{userCode}
</select>
<!--id指定的是方法名称,resultType是返回的数据类型-->
<select id="count" resultType="int">
select count(1) from smbms_user
</select>
<!--<select id="selectAll" resultType="cn.gwj.entity.User">-->
<!--select * from smbms_user-->
<!--</select>-->
<select id="selectAll" resultType="User">
select * from smbms_user
</select>
<select id="selectUserByName" resultMap="userMap" parameterType="String">
select * from smbms_user where userName like concat('%',#{name},'%')
</select>
<select id="getUserList" resultMap="userMap">
select u.*,r.roleCode,r.roleName from smbms_user u
left join smbms_role r on u.userRole=r.id
where userName=#{userName} or userRole=#{userRole}
limit #{currentPageNo},#{PageSize}
</select>
<select id="add" parameterType="User">
insert into smbms_user(userCode,userName,userPassword) values(#{userCode},#{userName},#{userPassward})
</select>
<select id="modify" parameterType="User">
update smbms_user set userCode=#{userCode},userName=#{userName},userPassword=#{userPassword}
</select>
<!--接口方法多个参数,在接口方法传参时使用@param("参数名称") 注解值的类型-->
<select id="updatePwd">
update smbms_user set userPassword=#{pwd}
where id=#{id}
</select>
<select id="deleteUserById" parameterType="int">
delete from smbms_user where id=#{id}
</select>
</mapper>
四、mybatis配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--配置mybatis的log实现为LOG4J-->
<setting name="logImpl" value="LOG4J"/>
<!--关闭延迟加载-->
<setting name="lazyLoadingEnabled" value="false"/>
<!--禁止自动匹配,默认自动匹配,但是实体属性名和数据库字段名一致,resultType无效-->
<setting name="autoMappingBehavior" value="NONE"/>
</settings>
<!--指定别名-->
<typeAliases>
<package name="cn.gwj.entity" />
<!--<typeAlias type="cn.gwj.entity.User" alias="User"/>-->
<package name="cn.gwj.dao" />
</typeAliases>
<!--将mapper文件加入到配置文件中-->
<mappers>
<mapper resource="cn/gwj/dao/UserDao.xml"></mapper>
</mappers>
</configuration>
五、Spring的配置文件
1.教程
<?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:p="http://www.springframework.org/schema/p"
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.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!-- <property name="url">
<value><![CDATA[jdbc:mysql://127.0.0.1:3306/smbms?
useUnicode=true&characterEncoding=utf-8]]></value>
</property> -->
<property name="url" value="jdbc:mysql://127.0.0.1:3306/smbms?
useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 引用数据源组件 -->
<property name="dataSource" ref="dataSource" />
<!-- 引用MyBatis配置文件中的配置 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 配置SQL映射文件信息 -->
<property name="mapperLocations">
<list>
<value>classpath:cn/smbms/dao/**/*.xml</value>
</list>
</property>
</bean>
<!-- 配置mapper 映射dao-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指明sqlSessionFactoryBean的名字 可要可不要-->
<!-- 指明工厂sqlSessionFactoryBean的名字-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 指明接口的包-->
<property name="basePackage" value="cn.gwj.dao"/>
</bean>
<!-- 配置业务Bean -->
<bean id="userService" class="cn.smbms.service.user.UserServiceImpl"/>
<!-- 声明切面类-->
<bean class="cn.gwj.aop.AopLogger"/>
<!-- 开启使用注解驱动切面-->
<aop:aspectj-autoproxy/>
</beans>
2.实例
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!--使用扫描注解注入的包-->
<context:component-scan base-package="cn.gwj"/>
<!-- 配置数据源、连接池-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///smbms?useUnicode=true&charcaterEncoding=utf-8e&useSSL=falsee&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
<!-- 配置SqlSessionFactoryBean-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 引用数据源组件-->
<property name="dataSource" ref="dataSource"/>
<!-- 引用MyBatis配置文件中的配置-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 配置SQL映射文件信息-->
<property name="mapperLocations">
<!-- mapperLocations是Resource[]类型-->
<list>
<value>classpath:cn/gwj/dao/**/*.xml</value>
</list>
</property>
</bean>
<!-- 配置dao-->
<!-- <bean class="cn.gwj.dao.UserDaoImpl">-->
<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory"/>-->
<!-- </bean>-->
<!-- 配置业务bean-->
<bean class="cn.gwj.service.user.UserServiceImpl"/>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指明工厂sqlSessionFactoryBean的名字-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--指明接口的包-->
<property name="basePackage" value="cn.gwj.dao"/>
</bean>
<!-- </aop:config>-->
<!-- 声明切面类-->
<bean class="cn.gwj.aop.AopLogger"/>
<!-- 开启使用注解驱动切面-->
<aop:aspectj-autoproxy/>
</beans>
六、测试
package cn.gwj.aop;
import cn.gwj.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Arrays;
/**
* 增强类
*/
@Aspect
public class AopLogger {
private Logger logger=Logger.getLogger(AopLogger.class);
@Pointcut("execution(* cn.gwj.service..*.*(..))")
public void pt(){}
@Before("pt()")
public void before(JoinPoint jp){
logger.info("前置增强-执行了"+jp.getTarget()+"的"+jp.getSignature().getName()
+"的方法,传入了参数"+ Arrays.toString(jp.getArgs()));
}
@AfterReturning(pointcut = "pt()",returning = "result")
public void after(JoinPoint jp,Object result){
logger.info("后置增强执行了"+jp.getTarget()+"的"+jp.getSignature().getName()
+"的方法,返回值"+ result);
}
@After("pt()")
public void aft(JoinPoint jp){
// SqlSession sqlSession=(SqlSession)jp.getArgs()[0];
// MyBatisUtil.closeSqlSession(sqlSession);
logger.info("最终增强-执行了"+jp.getTarget()+"的"+jp.getSignature().getName()
+"的方法");
}
@AfterThrowing(pointcut = "pt()",throwing = "e")
public void exc(JoinPoint jp,RuntimeException e){
logger.info("异常增强-执行了"+jp.getTarget()+"的"+jp.getSignature().getName()
+"的方法,异常"+ e);
}
@Around("pt()")
public Object around(ProceedingJoinPoint pj) throws Throwable {
logger.info(
"前置增强-执行了"+pj.getTarget()+"的"+pj.getSignature().getName()+"方法。方法传参"+Arrays.toString(pj.getArgs())
);
try{
Object result=pj.proceed();
logger.info(
"后置增强-执行了"+pj.getTarget()+"的"+pj.getSignature().getName()
+"的方法,返回值"+ result
);
return result;
}catch (Throwable e){
logger.error("环绕增强"+pj.getSignature().getName()+"方法发生异常。");
throw e;
}finally {
logger.info("环绕增强-"+pj.getSignature().getName()+"方法结束执行。");
}
}
}
package cn.gwj.dao;
import cn.gwj.entity.User;
import cn.gwj.service.user.UserService;
import cn.gwj.service.user.UserServiceImpl;
import cn.gwj.util.MyBatisUtil;
import javafx.application.Application;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.ArrayList;
import java.util.List;
/*
Created by IntelliJ IDEA.
Package:cn.gwj.dao
User:1093499975@qq.com
Date:2019/7/6 0006
Time:15:59
*/
public class UserDaoTest {
private Logger logger=Logger.getLogger(UserDaoTest.class);
@Test
public void testAop2() throws Exception {
// 通过ClassPathXmlApplicationContext实例化Spring的上下文
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-config.xml");
UserService userService=(UserService) applicationContext.getBean("userService");
User user= userService.login("admin","1234567");
logger.info( user.getUserName());
}
}
七、结果
07-13 10:28:40[INFO]cn.gwj.aop.AopLogger
-前置增强-执行了cn.gwj.service.user.UserServiceImpl@3b5fad2d的login方法。方法传参[admin, 1234567]
07-13 10:28:40[INFO]cn.gwj.aop.AopLogger
-前置增强-执行了cn.gwj.service.user.UserServiceImpl@3b5fad2d的login的方法,传入了参数[admin, 1234567]
实现类:1234567
07-13 10:28:40[INFO]cn.gwj.aop.AopLogger
-后置增强-执行了cn.gwj.service.user.UserServiceImpl@3b5fad2d的login的方法,返回值cn.gwj.entity.User@4ce7fffa
07-13 10:28:40[INFO]cn.gwj.aop.AopLogger
-环绕增强-login方法结束执行。
07-13 10:28:40[INFO]cn.gwj.aop.AopLogger
-最终增强-执行了cn.gwj.service.user.UserServiceImpl@3b5fad2d的login的方法
07-13 10:28:40[INFO]cn.gwj.aop.AopLogger
-后置增强执行了cn.gwj.service.user.UserServiceImpl@3b5fad2d的login的方法,返回值cn.gwj.entity.User@4ce7fffa
07-13 10:28:40[INFO]cn.gwj.dao.UserDaoTest
-系统管理员
Process finished with exit code 0