博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Boot MyBatis 通用Mapper插件集成
阅读量:5986 次
发布时间:2019-06-20

本文共 11102 字,大约阅读时间需要 37 分钟。

看本文之前,请确保你已经在SpringBoot中集成MyBatis,并能正常使用。

如果没有,那么请先移步 做了解后,再按本文步骤操作。

使用MyBatis在我们通过xml集中配置SQL,并通过创建接口Mapper文件来完成持久化DAO层(mybatis内部使用的是动态代理,所以我们不需要自己编写实现类)。

然而在实际开发中,单表操作非常多,如果你也想像JPA、JDBC那样做一个所谓的BaseDao。那么可以实现一个通用Mapper来达到目的。现在有现成的通用Mapper插件,我们无需重新创造轮子(代码是开源的,你也可以自己在其基础上修改)。

通用Mapper插件网址:


下面是使用方法(本文直接将分页插件PageHelper也集成了):

一、添加或修改pom依赖

org.mybatis
mybatis
3.3.0
org.mybatis
mybatis-spring
1.2.3
com.github.pagehelper
pagehelper
4.1.1
tk.mybatis
mapper
3.3.4

这里说一下,文章开始指定的那篇文章中直接依赖的mybatis的starter。因为本文在集成通用Mapper的时候直接使用出现了错误,所以将mybatis的starter中的Java类(它本身只有2个Java类,非常简单)拷贝到工程中,注释掉了头部的//@ConditionalOnBean(DataSource.class),你不用去找那2个类的源码了,下面会粘贴出来。

二、将下面4个Java类加入到工程中

将文件

MybatisAutoConfiguration.java
MyBatisMapperScannerConfig.java
MybatisProperties.java
MyMapper.java
添加到 org.springboot.sample.config.mybatis 中(包名根据自己工程修改)

最有一个MyMapper.java要特别注意,不要把MyMapper放到同其他Mapper一起,该类不能被当做普通Mapper一样被扫描,否则会出错。

package org.springboot.sample.config.mybatis;import java.util.Properties;import javax.annotation.PostConstruct;import javax.sql.DataSource;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.SqlSessionTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.autoconfigure.AutoConfigureAfter;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.DefaultResourceLoader;import org.springframework.core.io.Resource;import org.springframework.core.io.ResourceLoader;import org.springframework.util.Assert;import org.springframework.util.StringUtils;import com.github.pagehelper.PageHelper;/** * {@link EnableAutoConfiguration Auto-Configuration} for Mybatis. Contributes a * {@link SqlSessionFactory} and a {@link SqlSessionTemplate}. * * If {@link org.mybatis.spring.annotation.MapperScan} is used, or a configuration file is * specified as a property, those will be considered, otherwise this auto-configuration * will attempt to register mappers based on the interface definitions in or under the * root auto-configuration package. * * @author Eddú Meléndez * @author Josh Long */@Configuration@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })//@ConditionalOnBean(DataSource.class)@EnableConfigurationProperties(MybatisProperties.class)@AutoConfigureAfter(DataSourceAutoConfiguration.class)public class MybatisAutoConfiguration {    private static Log log = LogFactory.getLog(MybatisAutoConfiguration.class);    @Autowired    private MybatisProperties properties;    @Autowired(required = false)    private Interceptor[] interceptors;    @Autowired    private ResourceLoader resourceLoader = new DefaultResourceLoader();    @PostConstruct    public void checkConfigFileExists() {        if (this.properties.isCheckConfigLocation()) {            Resource resource = this.resourceLoader                    .getResource(this.properties.getConfig());            Assert.state(resource.exists(),                    "Cannot find config location: " + resource                            + " (please add config file or check your Mybatis "                            + "configuration)");        }    }    @Bean(name = "sqlSessionFactory")    @ConditionalOnMissingBean    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();        factory.setDataSource(dataSource);        if (StringUtils.hasText(this.properties.getConfig())) {            factory.setConfigLocation(                    this.resourceLoader.getResource(this.properties.getConfig()));        } else {            if (this.interceptors != null && this.interceptors.length > 0) {                factory.setPlugins(this.interceptors);            }            factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());            factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());            factory.setMapperLocations(this.properties.getMapperLocations());        }        return factory.getObject();    }    @Bean    @ConditionalOnMissingBean    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {        return new SqlSessionTemplate(sqlSessionFactory,                this.properties.getExecutorType());    }        /**     * 分页插件     *     * @param dataSource     * @return     * @author SHANHY     * @create  2016年2月18日     */    @Bean    public PageHelper pageHelper(DataSource dataSource) {        log.info("注册MyBatis分页插件PageHelper");        PageHelper pageHelper = new PageHelper();        Properties p = new Properties();        p.setProperty("offsetAsPageNum", "true");        p.setProperty("rowBoundsWithCount", "true");        p.setProperty("reasonable", "true");        pageHelper.setProperties(p);        return pageHelper;    }    }
package org.springboot.sample.config.mybatis;import java.util.Properties;import org.springframework.boot.autoconfigure.AutoConfigureAfter;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import tk.mybatis.spring.mapper.MapperScannerConfigurer;/** * MyBatis扫描接口,使用的tk.mybatis.spring.mapper.MapperScannerConfigurer 
* 如果你不使用通用Mapper,可以改为org.xxx... * */@Configuration//TODO 注意,由于MapperScannerConfigurer执行的比较早,所以必须有下面的注解@AutoConfigureAfter(MybatisAutoConfiguration.class)public class MyBatisMapperScannerConfig { @Bean public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory"); mapperScannerConfigurer.setBasePackage("org.springboot.sample.mapper"); Properties properties = new Properties(); // 这里要特别注意,不要把MyMapper放到 basePackage 中,也就是不能同其他Mapper一样被扫描到。 properties.setProperty("mappers", MyMapper.class.getName()); properties.setProperty("notEmpty", "false"); properties.setProperty("IDENTITY", "MYSQL"); mapperScannerConfigurer.setProperties(properties); return mapperScannerConfigurer; }}
package org.springboot.sample.config.mybatis;import org.apache.ibatis.session.ExecutorType;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.core.io.Resource;/** * Configuration properties for Mybatis. * * @author Eddú Meléndez */@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)public class MybatisProperties {    public static final String MYBATIS_PREFIX = "mybatis";    /**     * Config file path.     */    private String config;    /**     * Location of mybatis mapper files.     */    private Resource[] mapperLocations;    /**     * Package to scan domain objects.     */    private String typeAliasesPackage;    /**     * Package to scan handlers.     */    private String typeHandlersPackage;    /**     * Check the config file exists.     */    private boolean checkConfigLocation = false;    /**     * Execution mode.     */    private ExecutorType executorType = ExecutorType.SIMPLE;    public String getConfig() {        return this.config;    }    public void setConfig(String config) {        this.config = config;    }    public Resource[] getMapperLocations() {        return this.mapperLocations;    }    public void setMapperLocations(Resource[] mapperLocations) {        this.mapperLocations = mapperLocations;    }    public String getTypeHandlersPackage() {        return this.typeHandlersPackage;    }    public void setTypeHandlersPackage(String typeHandlersPackage) {        this.typeHandlersPackage = typeHandlersPackage;    }    public String getTypeAliasesPackage() {        return this.typeAliasesPackage;    }    public void setTypeAliasesPackage(String typeAliasesPackage) {        this.typeAliasesPackage = typeAliasesPackage;    }    public boolean isCheckConfigLocation() {        return this.checkConfigLocation;    }    public void setCheckConfigLocation(boolean checkConfigLocation) {        this.checkConfigLocation = checkConfigLocation;    }    public ExecutorType getExecutorType() {        return this.executorType;    }    public void setExecutorType(ExecutorType executorType) {        this.executorType = executorType;    }}
package org.springboot.sample.config.mybatis;import tk.mybatis.mapper.common.Mapper;import tk.mybatis.mapper.common.MySqlMapper;/** * 被继承的Mapper,一般业务Mapper继承它 * */public interface MyMapper
extends Mapper
, MySqlMapper
{ //TODO //FIXME 特别注意,该接口不能被扫描到,否则会出错}

三、属性配置文件

属性配置文件中和文章开头指定的文章一样配置,没有什么修改,下面粘贴出来:

mybatis.mapper-locations=classpath*:org/springboot/sample/mapper/sql/mysql/*Mapper.xmlmybatis.type-aliases-package=org.springboot.sample.entity

四、在业务Mapper中继承基础MyMapper接口

public interface StudentMapper extends MyMapper
{ List
likeName(String name); Student getById(int id); int add(Student stu); String getNameById(int id);}

然后在Service中使用即可,后面就没什么说的了。

@Servicepublic class StudentService {    @Autowired    private JdbcTemplate jdbcTemplate;        @Autowired    private StudentMapper studentMapper;        @TargetDataSource(name="ds2")    public List
likeName(String name){ return studentMapper.likeName(name); } public int testSave(){ Student stu = new Student(); stu.setAge(33); stu.setName("测试新增"); stu.setSumScore("66"); stu.setAvgScore("22"); return studentMapper.insert(stu);//这里调用的是基础Mapper中的insert方法 }}

最后还有一点要说明,使用公共Mapper“可能”需要对实体类进行修改。如果你的实体字段和数据库字段不一致(或者实体名称和数据库表名不一致),这样才需要修改,例如:

/** * 学生实体 * * @author   单红宇(365384722) * @myblog  http://blog.csdn.net/catoop/ * @create    2016年1月12日 */public class Student implements Serializable{            @Id    private int id;    private String name;    @Column(name="SCORE_SUM")    private String sumScore;    @Column(name="SCORE_AVG")    private String avgScore;    private int age;    // getter setter     }

其他没有什么可说的了,请至少要到 把插件的其他说明再看一遍。

你可能感兴趣的文章
Linux 进程管理
查看>>
Linux 线程相关函数理解
查看>>
我的友情链接
查看>>
2.3.1.shell awk 入门
查看>>
snmp在网络中的应用
查看>>
git 使用过程中问题记录
查看>>
SDN in Action: Deploy VXLAN with MP-BGP EV_P_N
查看>>
Maven学习总结(八)——使用Maven构建多模块项目
查看>>
Docker镜像与容器命令
查看>>
Java培训-日期类
查看>>
项目范围管理论文提纲
查看>>
python给qq发邮件
查看>>
关于mysql的 qps tps
查看>>
bootstrap datetimepicker 添加清空按钮
查看>>
Json学习总结(1)——Java和JavaScript中使用Json方法大全
查看>>
Myeclipse优化配置
查看>>
四大Java EE容器之简单比较
查看>>
我的友情链接
查看>>
oracle 11gR2 RAC存储迁移
查看>>
<org manual>翻译--2.8 抽屉
查看>>