乱入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层调用.承接前 ...
随机推荐
- “\xef\xbb\xbf”爬坑记录
今天早上帮同事写了脚本,大致功能:从文本中读取域名,加密存储成按照自己定义的格式.但是一个简单的代码居然出现了错误.初始的代码如下: # coding:utf-8 import hashlib imp ...
- ansible 的file 模块
创建.修改.删除文件或者目录: file模块 file模块常用的几个参数:state.path.src.dest.mode.owner.group.name.recurse state后面跟的参数: ...
- Android 静态代码分析工具
简评: 作者在文中提到的三个静态代码分析工具不是互相替代的关系,各有各的侧重点,如果有需要完全可以同时使用. 静态代码分析是指无需运行被测代码,仅通过分析或检查源程序的语法.结构.过程.接口等来检查程 ...
- Spring AOP 在XML中声明切面
转载地址:http://www.jianshu.com/p/43a0bc21805f 在XML中将一个Java类配置成一个切面: AOP元素 用途 <aop:advisor> 定义AOP通 ...
- CSS基础-如何用border写三角形?
1.常用的border的单值属性(border指的是边框.) /*边框样式属性*/ border-style: solid; /*边框颜色*/ border-color: #06a43a; /*边框宽 ...
- mysql8.0.16操作记录
mysql8.0.16操作记录 2.1.登录 -uroot -p'AnvcTMagdLarwNV3CKaC' mysql: [Warning] Using a password on the comm ...
- jsp三种注释方法
HTML注释(输出注释):指在客户端查看源代码时能看见注释.例如, <!-- this is an html comment.it will show up int the response. ...
- electron监听系统托盘,electron是否最小化到系统托盘
在项目中需要判断窗口是否最小化在系统托盘上,任务栏那已经关闭,查了一晚上的api,始终找不到可以调用的方法,最后绞尽脑汁想到了一个办法,那就是在点右上角的关闭按钮时,加个全局变量,用来标识已经最小到系 ...
- 【leetcode】Heaters
Winter is coming! Your first job during the contest is to design a standard heater with fixed warm r ...
- vue-router的hash模式和history模式,
hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件: window.onhashchange = function(event){ console.log(ev ...