SpringSpringBoot@IT·互联网

SpringBoot+MyBatis通用Mapper3实践浅析

2017-05-16  本文已影响276人  阿里加多

阿里巴巴长期招聘Java研发工程师p6,p7,p8等上不封顶级别,有意向的可以发简历给我,注明想去的部门和工作地点:1064454834@qq.com

欢迎关注微信公众号:技术原始积累 获取更多技术干货

一、前言

MyBatis通用Mapper3是对mybaits的数据库操作的一层封装,之前使用时候是根据数据库表生成mapper.xml,mapper的接口类,这个mapper.xml和接口类被代理后生成能够操作数据对应表的基础功能,而Mapper3则是对其封装,基础功能不在需要mapper.xml,接口类只需要继承封装好的Mapper<T>接口就具有了操表的基础功能,如果你需要自己的操作则还是需要在mapper.xml中和接口类中写实现。Mapper3项目地址:http://git.oschina.net/free/Mapper

二、如何使用

2.1 引入maven配置

SpringBoot应用只需要引入:

<!--mybatis-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.1.1</version>
</dependency>
<!--mapper-->
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>1.1.0</version>
</dependency>
<!--pagehelper-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.1.0</version>
</dependency>

2.2 generator 生成基础文件

在src/main/resources下面
generator.xml文件

<generatorConfiguration>

//属性值,下面的config.properties文件
  <properties resource="config.properties"/>

  <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
    <property name="beginningDelimiter" value="`"/>
    <property name="endingDelimiter" value="`"/>
    //插件
    <plugin type="${mapper.plugin}">
      <property name="mappers" value="${mapper.Mapper}"/>
    </plugin>

  //数据源
    <jdbcConnection driverClass="${jdbc.driverClass}"
                    connectionURL="${jdbc.url}"
                    userId="${jdbc.user}"
                    password="${jdbc.password}">
    </jdbcConnection>

//Do生成
    <javaModelGenerator targetPackage="${targetModelPackage}" targetProject="${targetJavaProject}"/>
//mapper xml文件
    <sqlMapGenerator targetPackage="${targetXMLPackage}"  targetProject="${targetResourcesProject}"/>
//mapper接口文件
    <javaClientGenerator targetPackage="${targetMapperPackage}" targetProject="${targetJavaProject}" type="XMLMAPPER" />
<table tableName="lassen_swardman" >
  <generatedKey column="uid" sqlStatement="Mysql" identity="true"/>
</table>

</context>
</generatorConfiguration>

cofing.properties文件

jdbc.driverClass = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://1270.0.1:3308/db
jdbc.user = ****
jdbc.password =****

jdbc.maxPoolSize=50
jdbc.minPoolSize=10
jdbc.maxStatements=100
jdbc.testConnection=true

# 插件
mapper.plugin = tk.mybatis.mapper.generator.MapperPlugin
mapper.Mapper = tk.mybatis.mapper.common.Mapper

然后在pom.xml配置如下:

<properties>
        <!--  MyBatis Generator  -->
        <!--  Java接口和实体类  -->
        <targetJavaProject>${basedir}/src/main/java</targetJavaProject>
        <targetMapperPackage>com.zlx.demo.web.speech.mapper</targetMapperPackage>
        <targetModelPackage>com.zlx.alin.demo.speech.model</targetModelPackage>
        <!--  XML生成路径  -->
        <targetResourcesProject>${basedir}/src/main/resources</targetResourcesProject>
        <targetXMLPackage>mapper</targetXMLPackage>
        <mybatis.version>3.4.2</mybatis.version>
<!--         <mapper.version>3.3.9</mapper.version>
 -->        <mapper.version>3.4.1.snapshot</mapper.version>
        <mysql.version>5.1.30</mysql.version>
        <mybatis.spring.version>1.2.4</mybatis.spring.version>
    </properties>

<plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>${mysql.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>tk.mybatis</groupId>
                        <artifactId>mapper</artifactId>
                        <version>${mapper.version}</version>
                    </dependency>
                </dependencies>
            </plugin>

然后在pom所在目录执行:mvn mybatis-generator:generate 即可
生成的Mapper接口文件:

public interface SwardManMapper extends Mapper<SwardManDo>{


}

生成的Mapper.xml文件(里面没有任何操作):

<mapper namespace="com.zlx.demo.web.speech.mapper.SwardManMapper">

<resultMap id="BaseResultMap" type="com.zlx.demo.web.speech.model.SwardManDo" >
    <!--
      WARNING - @mbggenerated
    -->
    <id column="Id" property="id" jdbcType="INTEGER" />
    <result column="name" property="name" jdbcType="VARCHAR" />
    <result column="status" property="status" jdbcType="VARCHAR" />
  </resultMap>
</mapper>

生成的Do文件:

@Table(name="lassen_swardman")
public class SwardManDo {

    
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Integer    guild_id;
    private String creator;
    private String modifier;
    private String name;
    private String status;
    private Date   gmt_create;
    private Date   gmt_modified;
    private String is_deleted;
    private Integer     power;
    
    
    public String getCreator() {
        return creator;
    }
    public void setCreator(String creator) {
        this.creator = creator;
    }
    public String getModifier() {
        return modifier;
    }
    public void setModifier(String modifier) {
        this.modifier = modifier;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
    public Date getGmt_create() {
        return gmt_create;
    }
    public void setGmt_create(Date gmt_create) {
        this.gmt_create = gmt_create;
    }
    public Date getGmt_modified() {
        return gmt_modified;
    }
    public void setGmt_modified(Date gmt_modified) {
        this.gmt_modified = gmt_modified;
    }
    public String getIs_deleted() {
        return is_deleted;
    }
    public void setIs_deleted(String is_deleted) {
        this.is_deleted = is_deleted;
    }
    public Integer getPower() {
        return power;
    }
    public void setPower(Integer power) {
        this.power = power;
    }
    public Integer getGuild_id() {
        return guild_id;
    }
    public void setGuild_id(int guild_id) {
        this.guild_id = guild_id;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

}

2.3 测试

@RestController
@RequestMapping(value = "/speech/test")
public class TestRpc {
    
    @Autowired
    SwardManMapper swardManMapper;

    @RequestMapping(value = "selectAll", method = { RequestMethod.GET, RequestMethod.POST })
    public DecorateActionResult selectAll() {
        ActionResult result = new ActionResult();
        DecorateActionResult resultNew = new DecorateActionResult();
        resultNew.setContent(result);
        try {

            result.setRetValue(swardManMapper.selectAll());

        } catch (Exception ee) {
            result.setErrorMessage(ee.getLocalizedMessage());
            resultNew.setHasError(true);
        }

        return resultNew;
    }
}

三、原理分析

一切的不同在于mapper接口类继承了Mapper<T>,所以分析其原理自然是看看Mapper<T>干了啥:

public interface Mapper<T> extends
        BaseMapper<T>,
        ExampleMapper<T>,
        RowBoundsMapper<T>,
        Marker {
}

public interface BaseMapper<T> extends
        BaseSelectMapper<T>,
        BaseInsertMapper<T>,
        BaseUpdateMapper<T>,
        BaseDeleteMapper<T> {

}

public interface BaseSelectMapper<T> extends
        SelectOneMapper<T>,
        SelectMapper<T>,
        SelectAllMapper<T>,
        SelectCountMapper<T>,
        SelectByPrimaryKeyMapper<T>,
        ExistsWithPrimaryKeyMapper<T> {

}

public interface SelectAllMapper<T> {

    /**
     * 查询全部结果
     *
     * @return
     */
    @SelectProvider(type = BaseSelectProvider.class, method = "dynamicSQL")
    List<T> selectAll();
}

一层层继承后找到了上面调用的selectAll的定义,原来使用的是SelectProvider注解,再看下selectAll的实现类BaseSelectProvider

public class BaseSelectProvider extends MapperTemplate {

    public BaseSelectProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }

   ...........
    /**
     * 查询
     *
     * @param ms
     * @return
     */
    public String selectOne(MappedStatement ms) {
        Class<?> entityClass = getEntityClass(ms);
        //修改返回值类型为实体类型
        setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.selectAllColumns(entityClass));
        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
        sql.append(SqlHelper.whereAllIfColumns(entityClass, isNotEmpty()));
        return sql.toString();
    }


    /**
     * 查询全部结果
     *
     * @param ms
     * @return
     */
    public String selectAll(MappedStatement ms) {
        final Class<?> entityClass = getEntityClass(ms);
        //修改返回值类型为实体类型
        setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.selectAllColumns(entityClass));
        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
        sql.append(SqlHelper.orderByDefault(entityClass));
        return sql.toString();
    }
}

至此大概知道了是怎么玩的了,这些函数里面是拼接sql语句的。所以如果需要我们可以重写这些SelectProvider实现自己的逻辑,比如查找时候之筛选is_deleted='n'的等等。

欢迎关注微信公众号:技术原始积累 获取更多技术干货

image.png
上一篇下一篇

猜你喜欢

热点阅读