1、MyBatis与Spring的整合
MyBatis是一款优秀的ORM框架。Spring是一款集控制反转、依赖注入与切面编程于一身的Java框架。下面将介绍MyBatis与Spring的整合。
1.1 下载依赖的jar包
(1)MyBatis框架相关的jar包
由于是要与Spring框架整合,所有除了下载MyBatis的jar包之外,还需要下载MyBatis与Spring整合的jar包。
(2)Spirng框架相关的jar包
除了下载Spring框架包,还需要下载aspectjweaver.jar包,aspectjweaver是spring AOP的切入点表达式需要用的包。spring配置中的<aop:config>节点需要引入aspectjweaver.jar。
(3)JDBC驱动jar包
由于本实例使用的是MySQL数据库,所有需要下载MySQL的JDBC驱动jar包。
(4)DBCP数据库连接池的jar包
在本实例中,使用DBCP作为数据库连接池的管理,所以需要下载DBCP数据库连接池相关的jar包。包括:commons-dbcp2.jar、commons-pool2.jar。
(5)Junit4测试的jar包
在本实例中,使用Junit4作为测试,需要下载Junit4测试的j相关jar包,包括:junit-4.jar、hamcrest-core.jar。
注意:junit-4.10以上的版本中不包含hamcrest-core.jar,需要自己下载,在下面的地址中包含有:junit-4.13.jar和hamcrest-core.jar
Junit4下载地址
如果使用Maven,则pom.xml文件配置如下:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.2.3.RELEASE</spring.version>
<logging.log4j.version>2.13.0</logging.log4j.version>
<dbcp.pool.version>2.7.0</dbcp.pool.version>
</properties>
<dependencies>
<!-- servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Spring框架 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</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-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- SpringMVC依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- MyBatis框架 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!-- MyBatis与Spring整合 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!-- MySQL的JDBC数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<!-- DBCP数据库连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${dbcp.pool.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>${dbcp.pool.version}</version>
</dependency>
<!-- Log4j2日志记录框架 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${logging.log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${logging.log4j.version}</version>
</dependency>
<!-- junit4单元测试框架 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
1.2 创建项目工程
使用IntelliJ IDEA创建一个名为“MyBatisAndSpring”的工程,项目结构图如下:
(1)在src源码目录下,创建如下包和类/接口。
包 | 说明 | 类型 | 创建类/接口 |
---|---|---|---|
com.pjb.sm.dao | 数据库访问接口层 | 接口 | UserDao.java |
com.pjb.sm.service | 业务逻辑接口层 | 接口 | UserService.java |
com.pjb.sm.service.impl | 业务逻辑实现类层 | 类 | UserServiceImpl.java |
com.pjb.sm.entity | 实体层 | 类 | User.java |
com.pjb.sm.test | 测试层 | 类 | UserTest.java |
(2)在src源码目录下,创建resources目录,并设置为资源目录,用于存放所有的配置资源文件。
将resources目录设置为项目的资源目录:菜单:File → Project Structure,设置如下:
在resources目录中,创建如下目录与文件:
文件 | 说明 |
---|---|
db.properties | 数据库连接配置文件。 |
log4j2.xml | Log4j2日志配置文件。 |
mybatis/mybatis-config.xml | MyBatis全局配置文件。 |
spring/applicationContext.xml | Spring核心配置文件。 |
mapping/UserMapper.xml | 用户信息Mapper配置文件。 |
2、项目配置文件
2.1 编写db.properties数据库连接配置文件
编写db.properties数据库连接配置文件,配置包含数据库的驱动,数据库的连接地址,登录名、登录密码、数据库连接池信息。具体配置信息如下:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_admin?useSSL=false&
jdbc.username=root
jdbc.password=123456
dbcp.pool.maxTotal=10
dbcp.pool.maxIdle=5
2.2 编写Spring配置文件
在spring目录下,创建applicationContext.xml配置文件,这是Spring核心配置文件。在其中加载数据库连接配置文件“db.properties”中的数据,建立数据源,配置sqlSessionFactory会话工厂对象,具体配置信息如下:
<?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: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/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- 1.加载用于数据库配置的属性文件 -->
<context:property-placeholder location="classpath:resources/db.properties"/>
<!-- 2.包扫描:dao,service -->
<context:component-scan base-package="com.pjb.sm.dao,com.pjb.sm.service"/>
<!-- 3.dataSource数据源,使用DBCP数据库连接池 -->
<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}"/>
<!-- 连接池的最大数据库连接数,设置默认值0表示无限 -->
<property name="maxTotal" value="${dbcp.pool.maxTotal:0}"/>
<!-- 最大空闲数,即数据库连接的最大空闲时间。当超过空闲时间时,数据库连接将被标记为不可用,然后被释放,设置默认值0表示无限 -->
<property name="maxIdle" value="${dbcp.pool.maxIdle:0}"/>
</bean>
<!-- 4.配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
<!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
<!-- 扫描entity包 使用别名 -->
<property name="typeAliasesPackage" value="com.pjb.sm.entity" />
<!-- 扫描sql配置文件:mapper需要的xml文件 -->
<property name="mapperLocations" value="classpath:mapping/*.xml" />
</bean>
<!-- 5.事务管理 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事务通知 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="all*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 配置事务的代理 -->
<aop:config>
<!-- 定义一个切面 -->
<aop:pointcut id="allManagerMethod" expression="execution(* com.pjb.sm.service.impl.*.*(..))"/>
<!-- 将事务通知与切面组合 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>
<!-- 6.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 给出需要扫描Dao接口包 -->
<property name="basePackage" value="com.pjb.sm.dao" />
</bean>
</beans>
其中,<context:property-placeholder>标签,该配置用于读取工程中的静态属性文件,然后在其他配置项中使用时,就可以采用“${属性名}”的方式获取该属性文件中的配置参数值。
2.3 编写MyBatis配置文件
在mybatis目录下,创建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>
<!-- 全局配置参数 -->
<settings>
<!-- 指定 MyBatis 所用日志的具体实现,未指定时将自动查找 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 开启自动驼峰命名规则(camel case)映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启延时加载开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消极加载(即按需加载),默认值就是false -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 打开全局缓存开关(二级环境),默认值就是true -->
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 别名定义 -->
<typeAliases>
<package name="com.pjb.sm.entity"/>
</typeAliases>
</configuration>
在该配置文件中,在setting 配置中设置了一些延迟加载和缓存的开关信息,然后使用<typeAliases>标签设置了一个package的别名扫描路径,在该路径下的Java实体类都可以拥有一个别名(即首字母小写的类名)。
小贴士:有了Spring托管数据源,在MyBatis配置文件中仅需要关注性能化的配置。
2.4 编写Log4j2日志配置文件
在resources目录下,创建log4j2.xml配置文件,用于配置Log4j2日志的相关配置,具体配置信息如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- log4j2 配置文件 -->
<!-- 日志级别 trace<debug<info<warn<error<fatal -->
<configuration status="debug">
<!-- 自定义属性 -->
<Properties>
<!-- 日志格式(控制台) -->
<Property name="pattern1">[%-5p] %d %c - %m%n</Property>
<!-- 日志格式(文件) -->
<Property name="pattern2">
=========================================%n 日志级别:%p%n 日志时间:%d%n 所属类名:%c%n 所属线程:%t%n 日志信息:%m%n
</Property>
<!-- 日志文件路径 -->
<Property name="filePath">logs/myLog.log</Property>
</Properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${pattern1}"/>
</Console>
<RollingFile name="RollingFile" fileName="${filePath}"
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout pattern="${pattern2}"/>
<SizeBasedTriggeringPolicy size="5 MB"/>
</RollingFile>
</appenders>
<loggers>
<root level="debug">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFile"/>
</root>
</loggers>
</configuration>
3、综合实例
【实例】MyBatis与Spring的框架整合后,实现用户信息的增删改查操作。
(1)创建数据库表
在MySQL数据库中创建用户信息表(tb_user),并添加数据。
-- 创建“用户信息”数据表
CREATE TABLE IF NOT EXISTS tb_user
(
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号',
user_name VARCHAR(50) NOT NULL COMMENT '用户姓名',
blog_url VARCHAR(50) NOT NULL COMMENT '博客地址',
remark VARCHAR(50) COMMENT '备注'
) COMMENT = '用户信息表';
-- 添加数据
INSERT INTO tb_user(user_name,blog_url,remark) VALUES('pan_junbiao的博客','https://blog.csdn.net/pan_junbiao','您好,欢迎访问 pan_junbiao的博客');
(2)编写持久化类(Entity层)
在com.pjb.sm.entity包下,创建用户信息的持久化类(User.java)。
package com.pjb.sm.entity;
import org.springframework.stereotype.Component;
/**
* 用户信息的持久化类
* @author pan_junbiao
**/
@Component
public class User
{
private int Id; //用户ID
private String userName; //用户姓名
private String blogUrl; //博客地址
private String remark; //备注
public int getId()
{
return Id;
}
public void setId(int id)
{
Id = id;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getBlogUrl()
{
return blogUrl;
}
public void setBlogUrl(String blogUrl)
{
this.blogUrl = blogUrl;
}
public String getRemark()
{
return remark;
}
public void setRemark(String remark)
{
this.remark = remark;
}
}
(3)编写Mapper配置文件
在mapping目录下,创建用户信息Mapper配置文件(UserMapper.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">
<mapper namespace="com.pjb.sm.dao.UserDao">
<!-- 新增用户 -->
<insert id="addUser" parameterType="user">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO tb_user(user_name,blog_url,remark)
VALUES(#{userName},#{blogUrl},#{remark})
</insert>
<!-- 修改用户 -->
<update id="updateUser" parameterType="user">
UPDATE tb_user SET user_name = #{userName} ,blog_url=#{blogUrl} ,remark=#{remark} WHERE id = #{id}
</update>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
DELETE FROM tb_user WHERE id = #{id}
</delete>
<!-- 查询用户 -->
<select id="queryUserById" parameterType="int" resultType="user">
SELECT * FROM tb_user WHERE id = #{id}
</select>
</mapper>
(4)实现数据库访问接口层(Dao层)
在com.pjb.sm.dao包下,创建用户信息数据库访问接口(UserDao.java)。
package com.pjb.sm.dao;
import com.pjb.sm.entity.User;
/**
* 用户信息数据库访问接口
* Mapper动态代理接口
* @author pan_junbiao
**/
public interface UserDao
{
/**
* 查询用户
*/
public User queryUserById(int id);
/**
* 新增用户
*/
public int addUser(User user);
/**
* 修改用户
*/
public int updateUser(User user);
/**
* 删除用户
*/
public int deleteUser(int id);
}
(5)实现业务逻辑层(Service层)
在com.pjb.sm.service包下,创建用户信息业务逻辑接口(UserService.java)。
package com.pjb.sm.service;
import com.pjb.sm.entity.User;
/**
* 用户信息业务逻辑接口
* @author pan_junbiao
**/
public interface UserService
{
/**
* 查询用户
*/
public User queryUserById(int id);
/**
* 新增用户
*/
public int addUser(User user);
/**
* 修改用户
*/
public int updateUser(User user);
/**
* 删除用户
*/
public int deleteUser(int id);
}
在com.pjb.sm.service.impl包下,创建用户信息业务逻辑类(UserServiceImpl.java)。
package com.pjb.sm.service.impl;
import com.pjb.sm.dao.UserDao;
import com.pjb.sm.entity.User;
import com.pjb.sm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 用户信息业务逻辑类
* @author pan_junbiao
**/
@Service
public class UserServiceImpl implements UserService
{
@Autowired
private UserDao userDao;
/**
* 查询用户
*/
public User queryUserById(int id)
{
User user = userDao.queryUserById(id);
return user;
}
/**
* 新增用户
*/
public int addUser(User user)
{
int result = userDao.addUser(user);
return result;
}
/**
* 修改用户
*/
public int updateUser(User user)
{
int result = userDao.updateUser(user);
return result;
}
/**
* 删除用户
*/
public int deleteUser(int id)
{
int result = userDao.deleteUser(id);
return result;
}
}
注意:引入Dao的注解 @Autowired 及 Service 实现类的暴露注解 @Service。
(6)编写测试方法(Test层)
在com.pjb.sm.test包下,创建用户信息业务逻辑测试类(UserTest.java)。
package com.pjb.sm.test;
import com.pjb.sm.entity.User;
import com.pjb.sm.service.UserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 用户信息业务逻辑测试类
* @author pan_junbiao
**/
public class UserTest
{
private ApplicationContext applicationContext;
Logger logger = LogManager.getLogger(UserTest.class);
private UserService userService;
@Before
public void setUp() throws Exception
{
//获取Spring配置文件对象
applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
//通过配置资源对象获取UserServiceImpl对象
userService = (UserService)applicationContext.getBean("userServiceImpl");
}
@After
public void tearDown() throws Exception
{
}
/**
* 查询用户
*/
@Test
public void queryUserById()
{
//查询用户编号为1的用户信息
User user = userService.queryUserById(1);
//打印结果
if (user != null)
{
System.out.println("用户编号:" + user.getId());
System.out.println("用户姓名:" + user.getUserName());
System.out.println("博客地址:" + user.getBlogUrl());
System.out.println("备注信息:" + user.getRemark());
}
}
/**
* 新增用户
*/
@Test
public void addUser()
{
//创建新用户
User user = new User();
user.setUserName("pan_junbiao的博客");
user.setBlogUrl("https://blog.csdn.net/pan_junbiao");
user.setRemark("您好,欢迎访问 pan_junbiao的博客");
//执行新增方法
int result = userService.addUser(user);
//打印结果
System.out.println("执行结果:"+result);
System.out.println("自增主键:"+user.getId());
}
}
执行查询用户方法
日志输出信息:SQL查询语句、查询参数、返回的记录数。
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@885e7ff]
JDBC Connection [595556720, URL=jdbc:mysql://localhost:3306/db_admin?useSSL=false&, UserName=root@localhost, MySQL Connector/J] will be managed by Spring
==> Preparing: SELECT * FROM tb_user WHERE id = ?
==> Parameters: 1(Integer)
<== Columns: id, user_name, blog_url, remark
<== Row: 1, pan_junbiao的博客, https://blog.csdn.net/pan_junbiao, 您好,欢迎访问 pan_junbiao的博客
<== Total: 1
执行结果: