乱入Spring+Mybatis
新进入一个项目,写了一个功能,就是提供一个服务(service),该服务能够查询和插入。完成后,想要用junit测试一下;发现到了DAO底层注入的SqlSession字段为空;才意识到这是一个Spring注解的项目;之前经验主要是Spring MVC方式开发使用到Spring的注解和依赖注入。另外,这个字段被注解为@Autowired(required=true),在编译器都没有被报错实例化失败,也说明了以着这种测试的方式根本就没有走Spring的容器来管理对象。
看来是时候要好好研究一下Spring和Mybatis的一些功能本质。
想要在非Web工程使用Spring,那么需要通过于是添加了applicationContext.xml,定义了服务类bean,然后通过下面的方式获取容器获取对象:
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");// 读取bean.xml中的内容
SmallServiceImplsvr = ctx.getBean("service", SmallServiceImpl.class);// 创建bean的引用对象
Spring的思想就是容器管理bean,所以无论是他和谁组合,还是让他管理什么,都是向Spring的容器中放入对象。那么,这种放入就有了很多种方式,一种是通过向配置文件中添加配置的传统方式,比如,下面就是添加了service的引用。
<?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"
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-4.0.xsd">
<context:annotation-config />
<context:component-scan
base-package="com.a.b.component, com.a.b.service, com.a.b.dao" />
<bean id="service" class="com.a.b.service.impl.SmallServiceImpl"></bean>
</beans>
定义了bean就可以通过上面的代码来获取SmallServiceImpl了。但是对于这段xml有两点说明:
1. 其实是不需要对annotation-config进行声明,因为component-scan已经具有了annotation-config的职能;
2.component-scan可以一次性声明扫描多个包(Spring做的扫描是扫描class文件);我就是曾经有一次运行报错,就是因为有一个包没有添加到监视,导致了Spring容器创建bean失败;
扫描的本质是基于注解(@Service,@Component,@Repository)来发现bean(免于在xml文件进行配置),扫描之后,就是“装配”,类似于Autowired声明是为了Spring容器在实例化bean的过程中来装配字段,所以扫描和装配是两个阶段,后者是基于前者,也不完全依赖(还可以基于配置文件)。
你会发现一个现象:@Autowired声明的字段的类型都是接口,但是作为装配的类都是通过@Service/@Repository注解声明的实现类。
另外对于基于注解的说明,对于本例而言,可以不再配置文件中声明service,可以在定义的类头声明@Service(value="service")也可;如果不指定value值,默认的bean的名称为类名首字母小写(smallServiceImp)
@Service(value="service")
public class SmallServiceImpl {
通过getBean获取到了SmallService之后,在运行发现还是报错,因为执行到DAO的时候,发现那个SqlSession的字段(required=true)实例化失败,无法找到候选类;查找了很久原因;其实扫描的是指定的包,无法找到mybaits的类很正常,这个时候就是第三段那段话,和第三方组件配合的时候,第三方组件都是以bean形式定义到了Spring中;另外这个问题查了一段时间是因为我忘记了MyBatis的核心组件就是SqlSession以及SqlSessionFactory,早点想到就能知道需要将其以bean形式注入。
<bean id="dataSource" name="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 指定连接数据库的驱动 -->
<property name="driverClass" value="dm.jdbc.driver.DmDriver" />
<!-- 指定连接数据库的URL -->
<property name="jdbcUrl" value="jdbc:dm://localhost:5236" />
<!-- 指定连接数据库的用户名 -->
<property name="user" value="user" />
<!-- 指定连接数据库的密码 -->
<property name="password" value="password" />
<!-- 指定连接池中保留的最大连接数. Default:15 -->
<property name="maxPoolSize" value="10" />
<!-- 指定连接池中保留的最小连接数 -->
<property name="minPoolSize" value="3" />
<!-- 指定连接池的初始化连接数 取值应在minPoolSize 与 maxPoolSize 之间.Default:3 -->
<property name="initialPoolSize" value="3" />
<!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。 Default:0 -->
<property name="maxIdleTime" value="0" />
<!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数. Default:3 -->
<property name="acquireIncrement" value="2" />
<!-- JDBC的标准,用以控制数据源内加载的PreparedStatements数量。 但由于预缓存的statements属于单个connection而不是整个连接池所以设置这个参数需要考虑到多方面的因数.如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default:0 -->
<property name="maxStatements" value="20" />
<!-- 每60秒检查所有连接池中的空闲连接.Default:0 -->
<property name="idleConnectionTestPeriod" value="60" />
</bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:sqlmapConfig.xml"></property>
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"></property>
<property name="typeAliasesPackage" value="com.a.b.vo"></property>
</bean> <!-- 配置SQLSession模板 -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
增加了三个bean,定义数据源(dataSource),定义SqlSessionFactory以及SqlSession就不多说什么了。核心就是SqlSessionFactory,dataSource字段说明了数据源信息(此次项目使用的ComboPooledDataSource进行JDBC以及连接池管理);mapperLocation,就是告知mapper文件路径,注意这里路径指的是class路径,因为Spring容器的操作都是在部署之后的环境,所以一定是claas路径;configLocation,对于mybatis的配置(比如mapper参数对象,返回对象的别名,mybatis对于缓存的一些配置都是放置在这个配置文件中;至于typeAliasesPackage,不知。
<?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>
<setting name="cacheEnabled" value="true" />
<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="false" />
<setting name="multipleResultSetsEnabled" value="true" />
<setting name="useColumnLabel" value="true" />
<setting name="defaultExecutorType" value="REUSE" />
<setting name="defaultStatementTimeout" value="25000" />
</settings> <typeAliases>
<package name="com.zcm.mall.vo"/>
</typeAliases> </configuration>
上面这个就是mybatis的配置文件。
配置好了SqlSession/Factory信息之后,SqlSession字段可以被实例化,而且可以顺利的访问数据库了。
小记
1. 在mapper文件中,经常会有比较大小的情况">","<",对于这些特殊字符要么采用转义的方式,要么采用<![CDATA[ 这里写你的sql ]]> 这种方式;
2.在mapper的sql中,可以通过在sql语句中添加<include refid="whereClause" />来添加共通的sql,比如where的过来条件(根据查询bean字段进行拼sql),可能多个select语句会共用,这个时候可以考虑使用。比如分页是一个共同的sql,可以单独放置到一个文件中(比如CommonsqlMapper.xml),然后使用的地方通过include进行引用。
CommonSqlMapper.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="commonSql" >
<sql id="pageSql">
<if test="offset != null and limit != null">
limit #{offset}, #{limit}
</if>
</sql>
</mapper>
ASqlMapper.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.zcm.mall.vo.AuditLog">
<resultMap id="auditLog" type="com.a.b.vo.c">
<id column="id" property="id" jdbcType="BIGINT" />
<result column="log_type" property="logType" jdbcType="VARCHAR" />
<result column="log_msg" property="log" jdbcType="VARCHAR" />
<result column="oper_Id" property="userId" jdbcType="BIGINT" />
<result column="oper_name" property="userName" jdbcType="VARCHAR" />
<result column="create_date" property="createDate" jdbcType="VARCHAR" />
</resultMap>
<select id="select" parameterType="auditLog" resultMap="auditLog">
select * from AUDIT_LOG
<include refid="whereClause" />
<include refid="commonSql.pageSql" />
</select>
上面的xml中有一个地方定义了resultMap,这个定义用于将数据库中查询结果和实体类进行映射之用。如果你的数据库字段定义的和实体类名称不一致,需要通过这种方式进行映射。
乱入Spring+Mybatis的更多相关文章
- Idea SpringMVC+Spring+MyBatis+Maven调整【转】
Idea SpringMVC+Spring+MyBatis+Maven整合 创建项目 File-New Project 选中左侧的Maven,选中右侧上方的Create from archetyp ...
- SpringMVC+Spring+MyBatis+Maven调整【转】
Idea SpringMVC+Spring+MyBatis+Maven整合 创建项目 File-New Project 选中左侧的Maven,选中右侧上方的Create from archetyp ...
- Spring+MyBatis实践—工程配置
初次实践:Spring+MyBatis技术搭建框架,采用Bootstrap前端开源框架. 简介: MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除 了几乎所 ...
- Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)(转)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文实现了一个后台由Spring+Mybatis+SpringMVC组成,分页采用Pag ...
- 玩转SSH(四):Struts + Spring + MyBatis
一.创建 SSMDemo 项目 点击菜单,选择“File -> New Project” 创建新项目.选择使用 archetype 中的 maven-webapp 模版创建. 输入对应的项目坐标 ...
- Spring mybatis源码篇章-sql mapper配置文件绑定mapper class类
前言:通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-MybatisDAO文件解析(二) 背景知识 MappedStatement是mybatis操作sql ...
- Spring mybatis源码篇章-MybatisDAO文件解析(一)
前言:通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-SqlSessionFactory 加载指定的mybatis主文件 Mybatis模板文件,其中的属性 ...
- Spring mybatis源码篇章-NodeHandler实现类具体解析保存Dynamic sql节点信息
前言:通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-XMLLanguageDriver解析sql包装为SqlSource SqlNode接口类 publi ...
- Spring mybatis源码篇章-MapperScannerConfigurer关联dao接口
前言:Spring针对Mybatis的XML方式的加载MappedStatement,通过引入MapperScannerConfigurer扫描类来关联相应的dao接口以供Service层调用.承接前 ...
随机推荐
- python自动化测试—配置文件的使用
一.什么是配置文件? 配置文件示例 [mysql] default-character-set = utf8 [mysqld] port = 3306 basedir = c:\mysql-5.7.2 ...
- js 一些小技巧
Javascript 中的 绑定事件 on $(document).on("事件","元素","方法"): Js 定时方法 1.setTim ...
- imagecreatefromjpeg(): gd-jpeg: JPEG library reports unrecoverable
错误: imagecreatefromstring(): Empty string or invalid image 或者 imagesx() expects parameter 1 to be re ...
- gd_t结构 bd_t结构
gd_t在u-boot-2018.07-fmxx/include/asm-generic/global_data.h中定义 typedef struct global_data { bd_t * ...
- 稀疏数组SparseArray
1 实际需求 1.1 需求提出 编写五子棋程序,有存盘退出和续上盘的功能. 实现思路: 存盘退出: 定义一个二维数组,默认值是0,黑子表示1,蓝子表示2,然后将二维数组通过流存储到文件中. 换言之:五 ...
- SpringMVC的数据转换&&数据格式化&&数据校验
1 SpringMVC的数据绑定流程 SpringMVC将ServletRequest对象及目标方法的入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象. ...
- ZROI 19.07.29 线性代数入门/wq
1.高斯消元 在模意义下依然有效,对主元求逆即可. 甚至可以模合数,需要对两个方程辗转相除,复杂度\(O(n^3\log p)\). 辗转相除法只要能定义带余除法就有效. 逆矩阵:对于矩阵\(A\), ...
- POJ-3020-Antena Placement(最小路径覆盖)
链接: https://vjudge.net/problem/POJ-3020 题意: The Global Aerial Research Centre has been allotted the ...
- Struts 2 实现Action的几种方式_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 Action用于处理用户的请求,因此也被称为业务控制器.每个Action类就是一个工作单元,Struts 2框架负责将用 ...
- 【NOIP2017提高组模拟12.10】幻魔皇
题目 幻魔皇拉比艾尔很喜欢斐波那契树,他想找到神奇的节点对. 所谓斐波那契树,根是一个白色节点,每个白色节点都有一个黑色节点儿子,而每个黑色节点则有一个白色和一个黑色节点儿子.神奇的节点对则是指白色节 ...