Spring整合MyBatis小结
MyBatis在Spring中的配置
我们在Spring中写项目需要运用到数据库时,现在一般用的是MyBatis的框架来帮助我们书写代码,但是学习了SSM就要知道M指的就是MyBatis,在此,在Spring中如何去配置MyBatis环境小结。
准备环境
首先我们需要准备的就是相关Jar包:
Mybatis相关Jar包:
Spring核心Jar包以及整合MyBatis的Jar包:
其中mybatis-spring-1.2.1.jar
包需要去官网下载。
配置环境
将上诉Jar包都导入lib下并添加到项目环境中。
项目结构:
应用
分好项目结构就可以开始编写代码,这个测试项目,用最简单的控制台来模拟用户登录(MVC设计模式)。实现物理解耦和逻辑解耦。
UserService接口:
public interface UserService {
// 用户登录
User userLoginService(String username,String pwd) throws IOException;
}
UserServiceImpl接口实现类:
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public User userLoginService(String username, String pwd){
if (userMapper!=null){
return userMapper.userLoginMapper(username,pwd);
}
return null;
}
}
UserMapper接口(映射文件没写用注解代替):
public interface UserMapper {
@Select("select * from t_user where userName=#{uname} and password=#{pwd}")
User userLoginMapper(@Param("uname") String username,@Param("pwd") String pwd);
}
User实体类:
public class User {
private String userid;
private String userName;
private String password;
private Double money;
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 创建数据源bean DriverManagerDataSource是DataSource在Spring的实现类-->
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
</bean>
<!-- 配置SqlSessionFactory的bean对象,同时,Spring整合了mybatis,需要导入mybatis-spring-1.3.1.jar包,到官网下载 -->
<bean name="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 获取UserMapper的接口bean -->
<bean name="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描Mapper路径 -->
<!--
Spring会将mapper扫描的结果(mapper层的对象),返回并存储在Spring容器中,为接口名的首字母小写
-->
<property name="basePackage" value="com.lyl.mapper"/>
<property name="sqlSessionFactory" ref="factory"/>
</bean>
<!-- 配置UserServiceImpl的bean -->
<bean name="us" class="com.lyl.service.impl.UserServiceImpl">
<!-- 依赖注入 -->
<property name="userMapper" ref="userMapper"/>
</bean>
</beans>
Test测试类:
public class Test {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = scanner.next();
System.out.println("请输入密码:");
String pwd = scanner.next();
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService us = (UserService) context.getBean("us");
User user1 = us.userLoginService(user, pwd);
System.out.println(user1);
}
}
查询结果:
别看把代码都呈现出来了,其实不需要全部一个一个代码的看,主要看两个地方,一个是Spring的配置文件,另一个是UserServiceImpl
代码的userLoginService
实现方法。
通过看Spring配置文件得知,大体分为4块
- 配置数据源bean
- 配置SqlSessionFactory的bean
- 获取UserMapper接口的bean
- 配置UserServiceImpl的bean(用了Setter注入实现逻辑解耦)
1.
很简单,就是准备数据库连接所需的参数(后面的可能有点杂,不感兴趣可以跳过!),刚开始难理解的可能就是DriverManagerDataSource
这个Spring提供的类了,我们顺着继承的关系一直找它的父类,我们们会发现一个接口——DataSource
,这个类有什么作用呢?
简要的说DataSource的作用还是得到Connection对象,用Connection对象对数据库进行操作。但是为什么DataSource这个类是关键?其实我们在单一的MyBatis时的配置文件也要进行数据库连接参数的相关配置,而核心是不是就是数据库连接参数的相关配置,说白了就是几个参数,那么参数会保存在哪?
那我们再来看看常规配置SqlSessionFactory的实现:
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
发现SqlSessionFactory最后调用了SqlSessionFactoryBuilder()的build()
方法,点进去看调用了这个重载方法
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException var13) {
}
}
return var5;
}
这个时候很郁闷,怎么又出现了一个新的类——XMLConfigBuilder
,查找资料发现:
这个类是对mybatis的配置文件进行解析的类,会对myabtis解析后的信息存放在Configuration对象中,Configuration对象会贯穿整个mybatis的执行流程,为mybatis的执行过程提供各种需要的配置信息。
得知这个类用来解析咱们的mybatis.xml配置文件,parse()
方法就是用来解析标签的并对内容进行存储,这个并不是最终的目的,接着往下看,发现最后调用的是下面这个方法
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
这个方法返回了DefaultSqlSessionFactory对象这个并不是重点,因为再点下去真就看不懂了,我们看参数Configuration
这个是不是我们配置MyBatis的跟标签一样?
查看资料:
Configuration就像是Mybatis的总管,Mybatis的所有配置信息都存放在这里,此外,它还提供了设置这些配置信息的方法。Configuration可以从配置文件里获取属性值。
这个Configuration就是存储MyBatis配置文件解析后的参数的对象。进去看看代码,会眩晕的,别急哈!在里面我们会看到一个Environment
类型的变量,也不用查找资料,看看mybatis.xml
文件的数据库连接参数配置标签就知道这个类的核心用处了——保存数据库的连接详细信息
里面有三个变量:
- id:当前环境变量的id,例如dev、prod等等
- transactionFactory:当前环境中的事务管理器
- dataSource:当前环境中的数据源
终于在MyBatis中找到了DataSource
数据源,通过层层查看源码,梳理逻辑关系,我们发现想要得到SqlSessionFactory的最后我们需要得到数据库的连接参数,毕竟我们只需要得到Connection就可以了,而MyBatis中的DataSource
就是保存连接参数的,至于怎么去实现,我们统统交给框架,关注业务代码即可。有没有发现实质上我们在MyBatis还是Spring的配置文件关心的都是配置参数,所以并不需要太纠结底层的所有源码的关系,抓住本质,本质就是两个不同框架需要相同的参数信息,我们做好参数配置即可。觉得乱也可以跳过,去查阅其他资料(毕竟也是初学的时候写的)。
2.
SqlSessionFactory是MyBatis操作数据库的核心Java类,我们必须从中得到SqlSession才能去进行具体的SQL操作,所以在Spring中用Setter实现数据源Bean的注入,使用的是mybatis-spring.jar
包,由Spring整合的mybatis包,这步操作就是得到SqlSessionFactory的bean
3.
获取UserMapper的接口bean,basePackage
这一属性是指定扫描的Mapper映射文件的包路径,sqlSessionFactory
将上面SqlSessionFactory的bean注入。我们打印一下此时的Spring容器中所有bean的名称:
发现我们只配置了4个Bean却出现了5个bean对象,多出一个userMapper
发现跟我们Mapper接口的名字好像,就首字母小写,其间肯定有什么关联。实际上在扫描Mapper包路径下的映射文件时,Spring会自动的将扫描出来的Mapper接口实例化成bean存在Spring容器中。这样我们在调用Mapper接口bean时,不用手动的去再配置Bean了。
4.
这一步就是简单的Setter依赖注入。
再看看UserServiceImpl
代码的userLoginService
实现方法,多了一个UserMapper的参数,如果不使用DI,那么我们常规需要使用一个接口或类的方法,需要创建这个接口或类的实例化才能调用,这样没有实现代码的解耦,如果使用DI,我们不需要去主动创建被调用方,只需要在Spring容器中设置bean,业务代码中我们只管拿最终的bean即可,实现了代码的解耦,A与B的关系不再直接,而是通过Spring容器,但是代码运行时,依然是一步一步,但是实现了解耦,方便维护。
小结
以上就是学习Spring整合MyBatis的简单案例的小结,其中也会有很多问题以及不足。要多结合实际和源码总结。
注意:Web项目中使用MyBatis是如果用了监听器ContextLoaderListener报错!
<context-param>
<!-- 必须写contextConfigLocation -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
param-name
标签中的变量名
必须写contextConfigLocation!
必须写contextConfigLocation!
必须写contextConfigLocation!
。。。
Spring整合MyBatis小结的更多相关文章
- Spring学习总结(五)——Spring整合MyBatis(Maven+MySQL)二
接着上一篇博客<Spring整合MyBatis(Maven+MySQL)一>继续. Spring的开放性和扩张性在J2EE应用领域得到了充分的证明,与其他优秀框架无缝的集成是Spring最 ...
- spring基础:什么是框架,框架优势,spring优势,耦合内聚,什么是Ioc,IOC配置,set注入,第三方资源配置,综合案例spring整合mybatis实现
知识点梳理 课堂讲义 1)Spring简介 1.1)什么是框架 源自于建筑学,隶属土木工程,后发展到软件工程领域 软件工程中框架的特点: 经过验证 具有一定功能 半成品 1.2)框架的优势 提高开发效 ...
- Spring学习总结(六)——Spring整合MyBatis完整示例
为了梳理前面学习的内容<Spring整合MyBatis(Maven+MySQL)一>与<Spring整合MyBatis(Maven+MySQL)二>,做一个完整的示例完成一个简 ...
- 分析下为什么spring 整合mybatis后为啥用不上session缓存
因为一直用spring整合了mybatis,所以很少用到mybatis的session缓存. 习惯是本地缓存自己用map写或者引入第三方的本地缓存框架ehcache,Guava 所以提出来纠结下 实验 ...
- 2017年2月16日 分析下为什么spring 整合mybatis后为啥用不上session缓存
因为一直用spring整合了mybatis,所以很少用到mybatis的session缓存. 习惯是本地缓存自己用map写或者引入第三方的本地缓存框架ehcache,Guava 所以提出来纠结下 实验 ...
- spring整合mybatis错误:class path resource [config/spring/springmvc.xml] cannot be opened because it does not exist
spring 整合Mybatis 运行环境:jdk1.7.0_17+tomcat 7 + spring:3.2.0 +mybatis:3.2.7+ eclipse 错误:class path reso ...
- spring 整合Mybatis 《报错集合,总结更新》
错误:java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldExcepti ...
- spring整合mybatis(hibernate)配置
一.Spring整合配置Mybatis spring整合mybatis可以不需要mybatis-config.xml配置文件,直接通过spring配置文件一步到位.一般需要具备如下几个基本配置. 1. ...
- spring 整合 mybatis 中数据源的几种配置方式
因为spring 整合mybatis的过程中, 有好几种整合方式,尤其是数据源那块,经常看到不一样的配置方式,总感觉有点乱,所以今天有空总结下. 一.采用org.mybatis.spring.mapp ...
随机推荐
- DC-9 靶机渗透测试
DC-9 渗透测试 冲冲冲,好好学习 DC系列的9个靶机做完了,对渗透流程基本掌握,但是实战中出现的情况千千万万,需要用到的知识面太广了,学不可以已. 靶机IP: 172.66.66.139 kali ...
- 预训练语言模型的前世今生 - 从Word Embedding到BERT
预训练语言模型的前世今生 - 从Word Embedding到BERT 本篇文章共 24619 个词,一个字一个字手码的不容易,转载请标明出处:预训练语言模型的前世今生 - 从Word Embeddi ...
- AT4828 [ABC152D] Handstand 2 TJ
前言 洛谷题解,懂?( 题目链接 来一点不一样的方法. 正解:动态规划 / 打表数据暴力分析 考试半小时想出方法,最后输在了两个细节上. 写一篇题解以此纪念. 打表暴力程序 最开始打的暴力对拍,没想到 ...
- [数据结构-平衡树]普通 FHQ_Treap从入门到精通(注释比代码多系列)
普通 FHQ_Treap从入门到精通(注释比代码多系列) 前提说明,作者写注释太累了,文章里的部分讲解来源于Oi-wiki,并根据代码,有部分增改.本文仅仅发布于博客园,其他地方出现本文,均是未经许可 ...
- MySQL学习05(MySQL函数)
MySQL函数 常用函数 官方文档 : https://dev.mysql.com/doc/refman/5.7/en/func-op-summary-ref.html 数据函数 SELECT ABS ...
- CTF-flask模板注入学习
今天又看到了一道这样的题,之前一直都学不明白的东西 反反复复给你看的时候,就想搞明白了. 我们做题的,需要知道flask是怎么运行的就行了. 这个就是一个最简单的flask应用,当我们访问的时候,就会 ...
- Linux通过命令增加IPV6地址
第一步:输入nmcli connection modify "eth0" ipv6.method manual ipv6.address ipv6地址/64 ifname et ...
- NOIP 模拟 $38\; \rm b$
题解 \(by\;zj\varphi\) 考虑转化问题,将计算最大公约数换为枚举最大公约数. 设 \(sum_i\) 为最大公约数为 \(i\) 的方案数,可以容斥求解,\(sum_i=f_i-\su ...
- ASP.NET Core教程:在ASP.NET Core中使用HttPClient调用WebService
一.前言 在以前的一篇文章中,曾经讲述过如何在ASP.NET Core中调用WebService.但是那种方式是通过静态引用的方式去调用的,如果是在生产环境中,肯定不能使用这种方式去调用,幸运的是微软 ...
- linux中 ~ 表示的是什么目录?
~ 表示代码主目录,也就是当前登录用户的用户目录.比如:我登录用户是chencd ~~ 代表的就是 /home/chen/当然前提是有用户目录,如果没有/home/chen目录的话情况就比较多了.总之 ...