1、整合环境搭建
1.1 准备所需JAR包
要实现MyBatis与Spring的整合,需要这两个框架的JAR包,还需要其他的JAR包来配合使用,整合时所需准备的JAR包具体如下:
1.Spring框架所需的JAR包
注意:核心容器依赖的commons-logging的JAR在MyBatis框架的lib包中已经包含!
2.MyBatis框架所需的JAR包
3.MyBatis与Spring整合的中间JAR
•https://mvnrepository.com/artifact/org.mybatis/mybatis-spring下载最新的版本
4.数据库驱动JAR(MySQL)
•mysql-connector-java-8.0.25.jar
5.数据源所需JAR(DBCP)
• commons-dbcp2-2.6.0.jar
• commons-pool2-2.6.2.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>org.example</groupId>
<artifactId>shopping</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>shopping 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.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- Spring-test测试 -->
<!-- -->
<!-- 会把core、beans、context、expression、aop、web等的依赖都自动加载进来。-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- 切面 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- 数据层 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.9</version>
</dependency>
<!--整合mybatis和spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!-- 事务 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- log4j日志 以及和slf4j整合需要的包 log4j已经不再更新 start-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
<build>
</build>
</project>
1.2 编写配置文件
1.创建项目,引入JAR包
在idea中,创建一个名称为springMyBatis的Web项目,将全部JAR包添加到项目的lib目录中,并发布到类路径下。
2.编写db.properties
为什么?
properties是配置文件,主要的作用是通过修改配置文件可以方便的修改代码中的参数,实现不用改class文件即可灵活变更参数。
解释:java运行中java文件会变成class文件,之后无法通过反编译找到原样的代码,这样的话,如果java类中某个参数变更,就很难灵活的实现参数修改,这个时候properties 文件就能很灵活的实现配置,减少代码的维护成本和提高开发效率。
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
jdbc.maxTotal=30 //数据库连接池的最大连接数
jdbc.maxIdle=10 //数据库连接池的最大空闲连接数
jdbc.initialSize=5 //数据库连接池的初始化连接数
3.编写Spring配置文件applicationContext.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"
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">
<!--<context:component-scan base-package="com.tjise.bean"/>-->
<!-- 加载数据库连接信息的属性文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 初始连接数,默认为0-->
<property name="initialSize" value="10"/>
<!-- 最大连接数,默认为8-->
<property name="maxActive" value="30"/>
<!-- 最小闲置数-->
<property name="minIdle" value="10"/>
<!-- 获取连接的最大等待时间,单位为毫秒-->
<property name="maxWait" value="60000"/>
<!-- 缓存PreparedStatement,默认为false-->
<property name="poolPreparedStatements" value="false"/>
<!-- 缓存PreparedStatement的最大数量,默认-1(不缓存)。大于0时会自动开启缓存PreparedStatement,所以可以省略上一句设置-->
<property name="maxOpenPreparedStatements" value="20"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置SessionFactory的Bean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 指定MyBatis配置文件的位置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 给实体类起别名 -->
<!-- <property name="typeAliasesPackage" value="com.congratulation.www.pojo"/>-->
</bean>
<!-- Mapper代理开发(基于MapperFactoryBean) -->
<!-- <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
<!-- <property name="mapperInterface" value="com.congratulation.www.mapper.UserMapper" />-->
<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" />-->
<!-- </bean>-->
<!-- Mapper代理开发(基于MapperScannerConfigurer) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.congratulation.www.mapper"/>
</bean>
<!--实例化Dao -->
<!-- <bean id="brandMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
<!-- <property name="mapperInterface" value="com.congratulation.www.mapper.BrandMapper"/>-->
<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory"/>-->
<!-- </bean>-->
<!-- <bean id="customerDao" class="com.sise.dao.impl.CustomerDaoImpl">-->
<!-- <!– 注入SqlSessionFactory对象实例–>-->
<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" />-->
<!-- </bean>-->
<!-- <!– Mapper代理开发(基于MapperFactoryBean) –>-->
<!-- <bean id="customerMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
<!-- <property name="mapperInterface" value="com.sise.mapper.CustomerMapper" />-->
<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" />-->
<!-- </bean>-->
<!-- Mapper代理开发(基于MapperScannerConfigurer) -->
<!-- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.sise.mapper" />
</bean> -->
<!-- 开启扫描 -->
<context:component-scan base-package="com.congratulation.www"/>
</beans>
4.编写MyBatis配置文件mybatis-config.xml
<?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>
<!-- 开启延迟加载 该项默认为false,即所有关联属性都会在初始化时加载
true表示延迟按需加载 -->
<settings>
<setting name="aggressiveLazyLoading" value="false"/>
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启二级缓存 -->
<!-- <setting name="cacheEnabled" value="true"/>-->
</settings>
<typeAliases>
<package name="com.congratulation.www.pojo"/>
</typeAliases>
<mappers>
<package name="com.congratulation.www.mapper"/>
</mappers>
</configuration>
5.引入log4j.properties
为什么?详细看这里
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.congratulation.www=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%m%l%p%r%n
#配置信息如下所示,按需修改
#
####将日志信息输出到控制台###
#
#log4j.appender.stdout=org.apache.log4j.ConsoleAppender(输出至控制台)
#
#log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#
#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%m%l%p%r%n
#
####把日志信息输出到文件中###
#
#log4j.appender.file=org.apache.log4j.FileAppender(输出至文件)
#
#log4j.appender.file.File=sysInfo.log(日志文件的名称)
#
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#
#log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%m%l%p%r%n(日志信息的格式)
#
####设置日志的优先级别###
#
#log4j.rootLogger=error,stdout,file
2、传统DAO方式的开发整合
使用mybatis-spring包中的SqlSessionTemplate类或SqlSessionDaoSupport类来实现。
SqlSessionTemplate : mybatis -spring 的核心类 ,负责 管理 MyBatis 的 SqlSession , 调用其 SQL 方法 (它会 保证使用的 SqlSession 和当前 Spring 的事务是相关 的),它 还 管理 MyBatis 的生命周期,包含必要的关闭、提交和回滚操作。
SqlSessionDaoSupport : 一个 抽象支持类 ,继承 了 DaoSupport 类, 主要 是 作为 DAO 的基类来使用 。可通过其 getSqlSession () 方法来获取所需的 SqlSession 。
接下来,以 SqlSessionDaoSupport 类的使用为例,来讲解下传统的 DAO 开发方式整合的实现
接口:
public interface BrandMapper {
public Brand findBrandById(int id);
}
实现类
public class BrandMapperImpl extends SqlSessionDaoSupport
implements BrandMapper {
@Override
public Brand findBrandById(int id) {
return this.getSqlSession().selectOne("com",id);
}
}
这个就不写了感兴趣的小伙伴可以去了解一下
3、Mapper接口方式的开发整合
userMapper接口
public interface UserMapper {
/**
* 查询所有用户
* @return list<User>
*/
List<User> selectAllUsers();
/**
* 添加一个用户
* @param user
*/
void addUser(User user);
}
UserMaper的xml
<?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">
<!-- namespace属性相当于映射文件的名称 属性值任意
接口代理方式,属性值要写成接口的完整类名-->
<mapper namespace="com.congratulation.www.mapper.UserMapper">
<insert id="addUser" parameterType="user">
insert into tb_user(username, password) values (#{username},#{password})
</insert>
<select id="selectAllUsers" resultType="User">
select * from tb_user;
</select>
</mapper>
UserService接口
public interface UserService {
/**
* 添加用户
* @param user
*/
public void addUser(User user);
List<User> selectAllUsers();
}
UserService的实现类UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public List<User> selectAllUsers() {
return userMapper.selectAllUsers();
}
@Override
@Transactional(readOnly = false)
public void addUser(User user) {
userMapper.addUser(user);
int i = 1 / 0;
System.out.println("添加成功");
}
}
UserServiceImpl的测试类
class UserServiceImplTest {
ApplicationContext act;
@BeforeEach
public void setup() {
act = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void testSelectAllUsers(){
UserService userServiceImpl = (UserService) act.getBean("userServiceImpl");
List<User> users = userServiceImpl.selectAllUsers();
for (User user : users) {
System.out.println(user.toString());
}
}
}
输出结果
4、测试事务
UserService的实现类UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public List<User> selectAllUsers() {
return userMapper.selectAllUsers();
}
@Override
@Transactional(readOnly = false)
public void addUser(User user) {
userMapper.addUser(user);
int i = 1 / 0;
System.out.println("添加成功");
}
}
class UserServiceImplTest {
private Logger logger = Logger.getLogger(UserServiceImplTest.class);
ApplicationContext act;
@BeforeEach
public void setup() {
act = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void testSelectAllUsers() {
UserService userServiceImpl = (UserService) act.getBean("userServiceImpl");
List<User> users = userServiceImpl.selectAllUsers();
for (User user : users) {
logger.debug("testSelectAllUsers id:" + user.getId()
+ "and username" + user.getUsername() + "and password" + user.getPassword());
}
}
@Test
public void testAddUser(){
UserService userServiceImpl = (UserService) act.getBean("userServiceImpl");
User user = new User();
user.setId(1);
user.setUsername("林汉涛");
user.setPassword("1223");
userServiceImpl.addUser(user);
}
}