目录
一:基本概念撰述
1. SqlSessionFactory对象,只有创建了SqlSessionFactory对象,才能调用openSession()方法得到SqlSession对象。
2. dao接口的代理对象,例如StudentDao接口,需要的代理对象为:SqlSeesion.getMapper(StudentDao.class)。
3. 数据源DataSource对象,使用一个更强大、功能更多的连接池对象代替mybatis自己的PooledDataSource。
二:将Mybatis与Spring集成的相关操作步骤
1:对pom.xml文件添加相关依赖
2:创建xml文件
3.通过插件自动生成代码
4.使用注解式开发开发方式完成开发
@Repository:将Mapper类扫描后注入到Spring上下文(IOC)中定义成bean对象,通常作用在Mapper层
@Service:将实现类扫描后注入到Spring上下文(IOC)中定义成bean对象,通常作用在service的实现类上(非接口)
@Controller:将Controller类扫描后注入到Spring上下文(IOC)中定义成bean对象,通常作用在控制层,将在Spring MVC中使用
@Component:是一个泛化的概念,仅仅表示spring中的一个组件(Bean),可以作用在任何层次
@Scope:模式声明(singleton单模|prototype多模)
@Autowired:将自动在代码上下文与其匹配(默认是类型匹配)的Bean,并自动注入到相应的地方
@Resource:
@Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
指定了name或者type则根据指定的类型去匹配bean
指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错
@Transactional:在方法调用之前开启事务,在方法调用之后提交事务或者回滚事务,可以添加定任意地方
5.Spring Test+Junit完美组合
6. 使用AOP编程完成分页
将 MyBatis 与 Spring 进行整合,主要解决的问题就是将SqlSessionFactory 对象交由 Spring 来管理。所以,该整合,只需要将SqlSessionFactory 的对象生成器 SqlSessionFactoryBean 注册在 Spring 容器中,再将其注入给 Dao 的实现类即可完成整合。
实现 Spring 与 MyBatis 的整合常用的方式:扫描的 Mapper 动态代理Spring 像插线板一样,mybatis 框架是插头,可以容易的组合到一起。插线板 spring 插上 mybatis,两个框架就是一个整体。
使用mybatis,需要创建mybatis框架中的某些对象,使用这些对象,就可以使用mybatis提供的功能了。
对于mybatis执行sql语句,需要用到的对象有:
1. SqlSessionFactory对象,只有创建了SqlSessionFactory对象,才能调用openSession()方法得到SqlSession对象。
2. dao接口的代理对象,例如StudentDao接口,需要的代理对象为:SqlSeesion.getMapper(StudentDao.class)。
3. 数据源DataSource对象,使用一个更强大、功能更多的连接池对象代替mybatis自己的PooledDataSource。
在Mybatis与Spring集成中所需要添加依赖如下:
①:添加spring相关依赖(5.0.2.RELEASE)
- spring-core
- spring-beans
- spring-context
- spring-orm
- spring-tx
- spring-aspects
- spring-web
//Spring版本
5.0.2.RELEASE
org.springframework
spring-core
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-orm
${spring.version}
org.springframework
spring-tx
${spring.version}
org.springframework
spring-aspects
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-test
${spring.version}
注意:spring 5.0.1.RELEASE有冲突
②: 添加mybatis相关依赖
- mybatis核心:mybatis(3.4.5)
- Mybatis分页:pagehelper(5.1.2)
3.4.5
5.1.2
org.mybatis
mybatis
${mybatis.version}
com.github.pagehelper
pagehelper
${pagehelper.version}
③:spring整合mybatis(1.3.1)
- mybatis-spring
1.3.1
org.mybatis
mybatis-spring
${mybatis.spring.version}
④:添加dbcp2连接池
- commons-dbcp2(2.1.1)
- commons-pool2(2.4.3)
2.1.1
2.4.3
org.apache.commons
commons-dbcp2
${commons.dbcp2.version}
org.apache.commons
commons-pool2
${commons.pool2.version}
⑤:添加日志配置(2.9.1)
- log4j-core
- log4j-api
- log4j-web
2.9.1
org.apache.logging.log4j
log4j-core
${log4j2.version}
org.apache.logging.log4j
log4j-api
${log4j2.version}
⑥: 其他
- junit(4.12)
- javax.servlet-api(4.0.0)
4.13
4.0.1
junit
junit
${junit.version}
test
javax.servlet
javax.servlet-api
${servlet.version}
完整版pom.xml文件代码如下:
4.0.0
com.tangyuan
ssm
1.0-SNAPSHOT
war
ssm Maven Webapp
http://www.example.com
UTF-8
1.8
1.8
4.13
4.0.1
5.0.2.RELEASE
3.4.5
1.3.1
5.1.44
2.1.1
2.4.3
2.9.1
1.18.12
5.1.2
junit
junit
${junit.version}
test
javax.servlet
javax.servlet-api
${servlet.version}
org.springframework
spring-core
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-orm
${spring.version}
org.springframework
spring-tx
${spring.version}
org.springframework
spring-aspects
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-test
${spring.version}
mysql
mysql-connector-java
${mysql.version}
org.mybatis
mybatis
${mybatis.version}
com.github.pagehelper
pagehelper
${pagehelper.version}
org.mybatis
mybatis-spring
${mybatis.spring.version}
org.apache.commons
commons-dbcp2
${commons.dbcp2.version}
org.apache.commons
commons-pool2
${commons.pool2.version}
org.apache.logging.log4j
log4j-core
${log4j2.version}
org.apache.logging.log4j
log4j-api
${log4j2.version}
org.apache.logging.log4j
log4j-web
${log4j2.version}
org.projectlombok
lombok
${lombok.version}
provided
ssm
org.apache.maven.plugins
maven-compiler-plugin
3.7.0
${maven.compiler.target}
${project.build.sourceEncoding}
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.2
mysql
mysql-connector-java
${mysql.version}
true
(1):spring.xml文件
(2):spring-mybatis.xml(重点文件:mybatis与spring的集成配置)
①:开启注解式开发,并指定扫描包的位置
②:引入外部jdbc配置文件
③:配置dbcp2数据库连接池
④:实现spring和mybatis整合
helperDialect=mysql
ps:第四步操作用来替代以前的MybatisSessionFactoryUtils文件,让代码更加简洁明了,如果对此文件感兴趣的,可以参考以下博客:
Mybatis 快速入门第一节 入门基础_靖康之耻的博客-CSDN博客MVC全名是ModelViewCotroller,是模型(model)——视图(view)——控制器(controller)的缩写,是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码自定义MVCSSMaction(中转站-----servlet类)controller(控制层)biz(业务逻辑处理层)servicedao(数据访问层)mapperIXxxDAO.java(接口)XxxMapper.java(接口)XxxDAOImpl.java(实现类)...https://blog.csdn.net/qq_61313896/article/details/125969558
⑤:开启注解式事物配置
ps:第五步操作用来替代以前的junit4单元测试的操作代码,让测试更加便捷,如果有感兴趣的,可以参考以前的博客:
Mybatis 快速入门第一节 入门基础_靖康之耻的博客-CSDN博客MVC全名是ModelViewCotroller,是模型(model)——视图(view)——控制器(controller)的缩写,是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码自定义MVCSSMaction(中转站-----servlet类)controller(控制层)biz(业务逻辑处理层)servicedao(数据访问层)mapperIXxxDAO.java(接口)XxxMapper.java(接口)XxxDAOImpl.java(实现类)...https://blog.csdn.net/qq_61313896/article/details/125969558 将dbcp2数据库连接池通过ref方式注入到事物管理器中,只要拿到数据源,就能进行事务开启
⑥:开启动态代理
外部jdbc配置文件如下:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_shopping?useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.username=root
jdbc.password=1234
jdbc.initialSize=10
jdbc.maxTotal=100
jdbc.maxIdle=50
jdbc.minIdle=10
jdbc.maxWaitMillis=-1
我的spring-mybatis.xml文件代码如下:
helperDialect=mysql
插件的配置请参考以前的博客:
Mybatis 快速入门第一节 入门基础_靖康之耻的博客-CSDN博客MVC全名是ModelViewCotroller,是模型(model)——视图(view)——控制器(controller)的缩写,是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码自定义MVCSSMaction(中转站-----servlet类)controller(控制层)biz(业务逻辑处理层)servicedao(数据访问层)mapperIXxxDAO.java(接口)XxxMapper.java(接口)XxxDAOImpl.java(实现类)...https://blog.csdn.net/qq_61313896/article/details/125969558
generatorConfig.xml
问题:若要将mapper类注入到Spring IOC上下文容器中,方式有哪几种?
方式一:在spring-mybatis.xml文件中添加以下代码:(手动注入)
方式二:运用@Repository注解方式在mapper接口上定义:(自动注入)
因为在spring-mybatis.xm中开启了注解式开发,所以可以使用注解方式来开发
@Repository:将Mapper类扫描后注入到Spring上下文(IOC)中定义成bean对象,通常作用在Mapper层
package com.tangyuan.mapper;
import com.tangyuan.model.Book;
import org.springframework.stereotype.Repository;
import java.util.List;
//将BookMapper扫描后注入到Spring上下文(IOC)中定义成bean对象
//
@Repository
public interface BookMapper {
int deleteByPrimaryKey(Integer bid);
int insert(Book record);
int insertSelective(Book record);
Book selectByPrimaryKey(Integer bid);
int updateByPrimaryKeySelective(Book record);
int updateByPrimaryKey(Book record);
List queryBookPager(Book book);
}
@Service:将实现类扫描后注入到Spring上下文(IOC)中定义成bean对象,通常作用在service的实现类上(非接口)
package com.tangyuan.service.impl;
import com.tangyuan.service.IBookService;
import org.springframework.stereotype.Service;
/**
* @author 唐渊
* @create 2022-07-24 21:46
*/
@Service
// @Service:通常作用在业务层 与上面作用一样
// 将BookServiceImpl扫描后注入到Spring上下文(IOC)中定义成bean对象 作用于Service层的实现类上(非接口类)
public class BookServiceImpl implements IBookService {
}
@Controller:将Controller类扫描后注入到Spring上下文(IOC)中定义成bean对象,通常作用在控制层,将在Spring MVC中使用
package com.tangyuan.Controller;
import org.springframework.stereotype.Controller;
/**
* @author 唐渊
* @create 2022-07-27 15:31
*/
@Controller
public class IndexController {
}
@Component:是一个泛化的概念,仅仅表示spring中的一个组件(Bean),可以作用在任何层次
可以作用于任意一层中,将所指定的接口或类注入到Spring上下文(IOC)中定义成bean对象
温馨提示:可以将上面四个注解方式看做setter方法,定义方式后,将其扫描后注入到Spring上下文(IOC)中定义成bean对象
@Scope:模式声明(singleton单模|prototype多模)
@Autowired:将自动在代码上下文与其匹配(默认是类型匹配)的Bean,并自动注入到相应的地方
@Resource:
@Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
指定了name或者type则根据指定的类型去匹配bean
指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错
温馨提示:可以将上面两个注解方式看做getter方法,定义方式后,将从Spring IOC上下文容器中获取指定的bean对象,相当于Spring中的DI(依赖注入)
package com.tangyuan.service.impl;
import com.tangyuan.mapper.BookMapper;
import com.tangyuan.service.IBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author 唐渊
* @create 2022-07-24 21:46
*/
@Service
// @Service:通常作用在业务层 与上面作用一样
// 将BookServiceImpl扫描后注入到Spring上下文(IOC)中定义成bean对象 作用于Service层的实现类上(非接口类)
public class BookServiceImpl implements IBookService {
//自动注入
//Spring中的DI(依赖注入)
//@Autowired 根据类型匹配
@Resource //@Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配,如果找不到,就报错
private BookMapper bookMapper;
//手动注入
// public BookMapper getBookMapper() {
// return bookMapper;
// }
//
// public void setBookMapper(BookMapper bookMapper) {
// this.bookMapper = bookMapper;
// }
}
@Transactional:在方法调用之前开启事务,在方法调用之后提交事务或者回滚事务,可以添加定任意地方
@Transactional //在方法调用之前开启事务,在方法调用之后提交事务或者回滚事务
@Override
public int insert(Book record) {
//开启
return bookMapper.insert(record);
//提交或者回滚
}
①: 在工程的pom文件中增加spring-test的依赖
org.springframework
spring-test
${spring.version}
②:创建BaseTestCase,并在该类上加上两个注解
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
package com.tangyuan.service.impl;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author 唐渊
* @create 2022-07-27 11:32
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring.xml"})
public class BaseTest {
}
以前的分页代码封装繁琐,所以我们现在特地地使用AOP编程中的环绕通知来对以前的分页代码进行简化
若对以前的分页代码有兴趣的,可以参考以前的博客:
Mybatis 快速入门之 动态sql和分页_靖康之耻的博客-CSDN博客1)在BookMapper类定义方法(2)在BookMapper.xml文件中进行sql语句的编写/*有参构造方法*/(3)在iBookService类编写代码(4)实现接口所定义的方法@Override}(5)进行junit4单元测试@Test//查询返回结果集适合使用返回值是自定义实体类的情况适合使用返回值的数据类型是非自定义的,即jdk的提供的类型println);}测试结果如下查看sql语句//分页查询@Override}...https://blog.csdn.net/qq_61313896/article/details/125981873?spm=1001.2014.3001.5501
特意编写一个类,来存放用环绕通知修改的分页代码:
package com.tangyuan.aspect;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tangyuan.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;
/**
* @author 唐渊
* @create 2022-07-25 9:46
*/
@Component
@Aspect
public class PageAspect {
//环绕通知:前+后
//切入点:* *..*Service.*Pager(..) 代表多个连接点集合
//* 代表方法返回值不限
//*.. 代表包名不限
//*Service 代表以service结尾的类或者是接口
//*Pager 代表以Pager结尾的方法
// (..) 代表方法的参数不限
//适配器:通知+切入点
@Around(value = "execution(* *..*Service.*Pager(..))")
public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
//获取目标的执行参数
Object[] params = joinPoint.getArgs();
//定义pagebean对象
PageBean pageBean = null;
//循环参数
for (Object param : params) {
//判断参数的类型是否是pagebean
if (param instanceof PageBean) {
pageBean = (PageBean) param;
break;
}
}
//判断是否分页
if (null != pageBean && pageBean.isPagination())
PageHelper.startPage(pageBean.getPage(), pageBean.getRows());
//执行目标方法
Object returnValue = joinPoint.proceed(params);
if (null != pageBean && pageBean.isPagination()){
if (returnValue instanceof List){
List list = (List) returnValue;
PageInfo pageInfo = new PageInfo(list);
pageBean.setTotal(pageInfo.getTotal()+"");
}
}
return returnValue;
}
}
方法测试:
@Test
public void queryBookPager(){
PageBean pageBean=new PageBean();
List books = bookService.queryBookPager(Book.builder().build(),pageBean);
System.out.println("总记录数:"+pageBean.getTotal());
books.forEach(System.out::println);
}
}
查看sql语句:
本人刚涉及此方面,博客可能有些地方不好,欢迎各位大佬前来一起讨论斧正