MyBatis从入门到精通(第9章):Spring集成MyBatis(中)
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法。
应该将应用自身的设计和具体的实现技术解耦。技术实现是应用的底层支撑,它不应该直接对应用产生影响。框架一般处在低层应用平台(如 J2EE)和高层业务逻辑之间的中间层。
- mybatis-spring 可以帮助我们将MyBatis代码无缝整合到Spring中。使用这个类库中的类,Spring将会加载必要的MyBatis工厂类和Session类。
- MyBatis Spring Adapter项目地址为: https://github.com/mybatis/spring
9.3 集成 MyBatis
需要注意的是,在 9.1 节创建基本项目的时候就己经添加了 MyBatis 的依赖,这一节主要是介绍与 mybatis-spring 相关的内容。
1. 在 pom.xml 中添加 mybatis-spring 依赖
mybatis-spring就是Mybatis和spring集成中必须的依赖。
此处使用版本为2.0.2版本。mybatis 3.5.2 spring 5.0.15.RELEASE
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency>
2. 配置 SqlSessionFactoryBean
在mybatis-spring中,SqlSessionFactoryBean 是用于创建SqlSessionFactory 的。在Spring的.xml配置文件 applicationContext.xml中配置这个工厂类,代码如下。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations"> <array> <value>classpath:cn/bjut/mybatis/**/mapper/*.xml</value> </array> </property> <property name="typeAliasesPackage" value="cn.bjut.mybatis.web.model"/> </bean>
typeAliasesPackage :配置包中类的别名 ,这个配置不支持 *通配符的路径,当需要配置多个包路径时,可以使用分号或逗号进行分隔。
上面配置的 mybatis-config.xml 位于 src/main/resources 目录下 , 配置文件内容如下 。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> <setting name="logImpl" value="LOG4J"/> <setting name="cacheEnabled" value="true"/> <setting name="mapUnderscoreToCamelCase" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings> </configuration>
3. 配置 MapperScannerConfigurer
这里要介绍的用法是最简单且推荐使用的一种,通过 MapperScannerConfigurer 类: 自动扫描所有的 Mapper 接口,使用时可以直接注入接口 。
在spring配置文件 applicationContext.xml 中配置扫描类,代码如下。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="addToConfig" value="true"/> <property name="basePackage" value="cn.bjut.mybatis.**.mapper"/> </bean>
MapperScannerConfigurer 中常配置以下两个属性 。
- basePackage : 用于配置基本的包路径。可以使用分号或逗号作为分隔符设置多于一个的包路径 。
- annotationClass : 用于过滤被扫描的接口,如果设置了该属性,那么 MyBatis 的接口只有包含该注解才会被扫描进去。
9.4 几个简单实例
在resources目录下添加日志的配置文件:log4j.properties
log4j.rootLogger=DEBUG, stdout log4j.logger.cn.bjut.mybatis=DEBUG log4j.logger.cn.bjut.mybatis.web.mapper=TRACE ### Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
这一小节会通过一整套的代码来演示MyBatis在项目开发中的基本用法,按照自下而上的顺序进行开发。
从Mapper开始,依次开发Service层、Controller层、JSP前端页面。
9.4.1 基本准备
在开始之前需要先准备数据库,表和数据。这一节会新增一个 表(table),然后针对这个表进行增、删、改、查4类操作。
字典表的建表语句和基础数据的SQL如下。
-- ---------------------------- -- Table structure for sys_dict -- ---------------------------- DROP TABLE IF EXISTS `sys_dict`; CREATE TABLE `sys_dict` ( `id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '主键', `code` varchar(64) NOT NULL COMMENT '类别', `name` varchar(64) NOT NULL COMMENT '字典名', `value` varchar(64) NOT NULL COMMENT '字典值', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_dict -- ---------------------------- INSERT INTO `sys_dict` VALUES ('1', '性别', '男', '男'); INSERT INTO `sys_dict` VALUES ('2', '性别', '女', '女'); INSERT INTO `sys_dict` VALUES ('3', '季度', '第一季度', '1'); INSERT INTO `sys_dict` VALUES ('4', '季度', '第二季度', '2'); INSERT INTO `sys_dict` VALUES ('5', '季度', '第三季度', '3'); INSERT INTO `sys_dict` VALUES ('6', '季度', '第四季度', '4');
在src/main/java 中新建 cn.bjut.mybatis.web.model 包,然后新建 SysDict 实体类。
package cn.bjut.mybatis.web.model; import java.io.Serializable; public class SysDict implements Serializable { private static final long serialVersionUID = 1L; private Long id; private String code; private String name; private String value; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
9.4.2 开发(DAO层)Mapper层
数据访问层(DAO层) 也就是常说的Mapper层。使用Mapper接口和XML映射文件结合的方式进行开发,在9.3节集成MyBatis的配置中,自动扫描接口的包名为 cn.bjut.mybatis.**.mapper ,因此在创建Mapper接口所在的包时也要参照这个命名规则。
在 src/main/java 中新建 cn.bjut.mybatis.web.mapper 包,然后新建 DictMapper接口。
package cn.bjut.mybatis.web.mapper; import cn.bjut.mybatis.web.model.SysDict; import org.apache.ibatis.session.RowBounds; import cn.bjut.mybatis.web.model.SysDict; import java.util.List; /** * @author kangmainfeng */ public interface DictMapper { /** * 根据主键查询 * * @param id * @return */ SysDict selectByPrimaryKey(Long id); /** * 条件查询 * * @param sysDict * @return */ List<SysDict> selectBySysDict(SysDict sysDict, RowBounds rowBounds); /** * 新增 * * @param sysDict * @return */ int insert(SysDict sysDict); /** * 根据主键更新 * * @param sysDict * @return */ int updateById(SysDict sysDict); /** * 根据主键删除 * * @param id * @return */ int deleteById(Long id); }
同时,9.3节的 SqlSessionFactoryBean 中也配置了扫描XML映射文件的目录
classpath:cn/bjut/mybatis/**/mapper/*.xml
在 src/main/resources 中新建 cn/bjut/mybatis/web/mapper/ 目录,然后新建 DictMapper.xml文件。
此处直接将接口和对应的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="cn.bjut.mybatis.web.mapper.DictMapper"> <select id="selectByPrimaryKey" resultType="SysDict"> select id, code, name, `value` from sys_dict where id = #{id} </select> <select id="selectBySysDict" resultType="tk.mybatis.web.model.SysDict"> select * from sys_dict <where> <if test="id != null"> and id = #{id} </if> <if test="code != null and code != ''"> and code = #{code} </if> </where> order by code, `value` </select> <insert id="insert" useGeneratedKeys="true" keyProperty="id"> insert into sys_dict(code, name, value) values (#{code}, #{name}, #{value}) </insert> <update id="updateById"> update sys_dict set code = #{code}, name = #{name}, value = #{value} where id = #{id} </update> <delete id="deleteById"> delete from sys_dict where id = #{id} </delete> </mapper>
这5个方法都是很基础的方法,下面(的博客文章)将在这5个接口的method 基础上,继续编写Service层的代码。
================
end