springboot和mybatis集成,自动生成model、mapper,增加mybatis分页功能

整体思路和http://www.cnblogs.com/mahuan2/p/5859921.html相同。

主要讲maven的pom.xml和一些配置变化,详细说明。

软件简介

Spring是一个流行的控制反转(IoC)和面向切面(AOP)的容器框架,在java webapp开发中使用广泛。http://projects.spring.io/spring-framework/

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。http://projects.spring.io/spring-boot/

MyBatis是一个基于Java的数据持久层框架,其原名是iBatis,在升级到3.0版本后,更名为MyBatis。https://github.com/mybatis/mybatis-3/

MyBatis Generator是一个MyBatis的代码生成器,通过配置,可自动生成数据操作接口、实体类以及mapper.xml文件。https://github.com/mybatis/generator

maven开发环境搭建

可以使用http://start.spring.io/初始化maven工程。

使用eclipseIDE,新建maven工程。

在pom.xml文件中,添加如下内容,引入相关jar。mybatis-generator版本是1.3.5。

<?xml version="1.0" encoding="UTF-8"?>
<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.founder</groupId>
    <artifactId>springboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>first</name>
    <description>Demo project for Spring Boot</description>

    <!-- lookup parent from repository -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
        <relativePath /> 
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator</artifactId>
            <version>1.3.5</version>
            <type>pom</type>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
</project>
View Code

工程目录结构

数据库建表,生成mybatis的代码

为了生成mybatis的代码,首先需要创建一个配置文件,告诉mybatis generator必须的变量。

配置文件保存在src/main/conf/build-mybatis.xml中。

具体配置信息参考官网http://www.mybatis.org/generator/index.html。

注意,配置文件中,添加了一个plugin,这是为生成分页操作添加的,具体内容,后面会讲解。

table中的tableName设置为%,意味着为mysql数据库中的所有表生成对应的代码文件。

mysql中表明使用“_”或者“-”分隔,自动生成的代码文件名中会去掉,并且其后面的字母会升级为大写。

指定好生成的代码文件的保存地址,共有三个。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--数据库驱动 -->
    <classPathEntry location="C:Usersmahuan.m2
epositorymysqlmysql-connector-java5.1.40mysql-connector-java-5.1.40.jar" />
    <context
        id="MySQL2Tables"
        targetRuntime="MyBatis3"
        defaultModelType="flat">
        <plugin type="com.founder.springboot.utils.mybatis.MySQLPaginationPlugin" />
        <commentGenerator>
            <property
                name="suppressDate"
                value="true" />
            <property
                name="suppressAllComments"
                value="true" />
        </commentGenerator>
        <!--数据库链接地址账号密码 -->
        <jdbcConnection
            driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://172.19.34.114:3306/founder_ali?useSSL=false"
            userId="root"
            password="123456">
        </jdbcConnection>
        <javaTypeResolver>
            <property
                name="forceBigDecimals"
                value="false" />
        </javaTypeResolver>
        <!--生成Model类存放位置 -->
        <javaModelGenerator
            targetPackage="com.founder.springboot.model.database"
            targetProject="src/main/java">
            <property
                name="enableSubPackages"
                value="true" />
            <property
                name="trimStrings"
                value="true" />
        </javaModelGenerator>
        <!--生成映射文件存放位置 -->
        <sqlMapGenerator
            targetPackage="com.founder.springboot.mapper.database"
            targetProject="src/main/java">
            <property
                name="enableSubPackages"
                value="true" />
        </sqlMapGenerator>
        <!--生成Dao类存放位置 -->
        <javaClientGenerator
            type="XMLMAPPER"
            targetPackage="com.founder.springboot.mapper.database"
            targetProject="src/main/java">
            <property
                name="enableSubPackages"
                value="true" />
        </javaClientGenerator>
        <!--生成对应表及类名 -->
        <table
            tableName="%"
            enableCountByExample="true"
            enableUpdateByExample="true"
            enableDeleteByExample="true"
            enableSelectByExample="true"
            selectByExampleQueryId="true">
            <property
                name="useActualColumnNames"
                value="true" />
            <!-- 需要插入时返回主键值,请将此属性打开,column值为主键的列明 
            <generatedKey column="taskId" sqlStatement="MySql" identity="true" />
             -->
        </table>
    </context>
</generatorConfiguration>
View Code

编写代码生成脚本

package com.founder.springboot.utils.mybatis;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;

public class MyBatisGeneratorTool {
    public static void main(String[] args) {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        String genCfg = "build-mybatis.xml";
        File configFile = new File(MyBatisGeneratorTool.class.getResource(genCfg).getFile());
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = null;
        try {
            config = cp.parseConfiguration(configFile);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XMLParserException e) {
            e.printStackTrace();
        }
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = null;
        try {
            myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        } catch (InvalidConfigurationException e) {
            e.printStackTrace();
        }
        try {
            myBatisGenerator.generate(null);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
View Code

分页插件代码

package com.founder.ebd.util.mybatis;

import java.util.List;

import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.Plugin;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

public class MySQLPaginationPlugin extends PluginAdapter {

    @Override
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        // add field, getter, setter for limit clause
        addLimit(topLevelClass, introspectedTable, "limitStart");
        addLimit(topLevelClass, introspectedTable, "count");
        // add the method that get the only Criteria
        addCriteriaGetter(topLevelClass, introspectedTable);
        return super.modelExampleClassGenerated(topLevelClass, introspectedTable);
    }

    @Override
    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        XmlElement isNotNullElement = new XmlElement("if"); //$NON-NLS-1$
        isNotNullElement.addAttribute(new Attribute("test", "limitStart != null and limitStart >= 0")); //$NON-NLS-1$ //$NON-NLS-2$
        isNotNullElement.addElement(new TextElement("limit ${limitStart} , ${count}"));
        element.addElement(isNotNullElement);
        return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
    }

    @Override
    public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        XmlElement isNotNullElement = new XmlElement("if"); //$NON-NLS-1$
        isNotNullElement.addAttribute(new Attribute("test", "limitStart != null and limitStart >= 0")); //$NON-NLS-1$ //$NON-NLS-2$
        isNotNullElement.addElement(new TextElement("limit ${limitStart} , ${count}"));
        element.addElement(isNotNullElement);
        return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
    }

    @Override
    public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
            IntrospectedTable introspectedTable, Plugin.ModelClassType modelClassType) {

        return super.modelGetterMethodGenerated(method, topLevelClass, introspectedColumn, introspectedTable, modelClassType);
    }

    private void addLimit(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String name) {
        CommentGenerator commentGenerator = context.getCommentGenerator();
        Field field = new Field();
        field.setVisibility(JavaVisibility.PROTECTED);
        field.setType(FullyQualifiedJavaType.getIntInstance());
        field.setName(name);
        field.setInitializationString("-1");
        commentGenerator.addFieldComment(field, introspectedTable);
        topLevelClass.addField(field);
        char c = name.charAt(0);
        String camel = Character.toUpperCase(c) + name.substring(1);
        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName("set" + camel);
        method.addParameter(new Parameter(FullyQualifiedJavaType.getIntInstance(), name));
        method.addBodyLine("this." + name + "=" + name + ";");
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);
        method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setReturnType(FullyQualifiedJavaType.getIntInstance());
        method.setName("get" + camel);
        method.addBodyLine("return " + name + ";");
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);
    }

    private void addCriteriaGetter(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        CommentGenerator commentGenerator = context.getCommentGenerator();
        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName("getCriteria");
        method.setReturnType(new FullyQualifiedJavaType("Criteria"));
        method.addBodyLine("if (oredCriteria.size() != 0) {return oredCriteria.get(0);}");
        method.addBodyLine("Criteria criteria = createCriteriaInternal();");
        method.addBodyLine("oredCriteria.add(criteria);");
        method.addBodyLine("return criteria;");
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);
    }

    @Override
    public boolean validate(List<String> arg0) {
        // TODO Auto-generated method stub
        return true;
    }
}
View Code

SpringBoot配置

在src/main/resources/application.properties中增加mybatis配置和jdbc配置。表示mybatis的配置文件未知,以及mapper的xml文件位置。

mybatis.config-locations=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:com/founder/springboot/mapper/database/*.xml

spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://172.19.34.114:3306/founder_ali?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = 123456

在application启动类中,增加注解,表示何处扫描mapper接口。

package com.founder.springboot;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.founder.springboot.mapper.database")
public class FirstApplication {

    public static void main(String[] args) {
        SpringApplication.run(FirstApplication.class, args);
    }
}

至此,mybatis配置完成。

springboot application.properties配置可参考官方文档

测试生成的代码

ExampleService

package com.founder.springboot.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.founder.springboot.mapper.database.SysUserMapper;
import com.founder.springboot.model.database.SysUser;
import com.founder.springboot.model.database.SysUserExample;

@Service
public class ExampleService {

    @Autowired
    SysUserMapper sysUser;

    public List<SysUser> get() {
        SysUserExample example = new SysUserExample();
        example.setLimitStart(0);
        example.setCount(10);
        return sysUser.selectByExample(example);
    }
}

ExampleController

package com.founder.springboot.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.founder.springboot.model.database.SysUser;
import com.founder.springboot.service.ExampleService;

@RestController
public class ExampleController {

    @Autowired
    private ExampleService service;

    @RequestMapping(value = "/get", produces = "application/json; charset=UTF-8")
    public List<SysUser> get() {
        return service.get();
    }
}

测试类

package com.founder.springboot.controller;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import com.founder.springboot.FirstApplication;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = FirstApplication.class)
@WebAppConfiguration
public class ExampleControllerTest {
    @Autowired
    private ExampleController controller;

    @Test
    public void get() throws Exception {
        System.out.println(controller.get());
    }
}

SpringBoot打包运行

使用maven命令

mvn clean package

可将springboot工程,打包为一个可运行的jar包。

注意:mapper的xml文件在src/main/java目录中,maven默认是不编译的,导致jar中缺少xml配置文件。需修改pom.xml配置,初始pom.xml已修改。

原文地址:https://www.cnblogs.com/mahuan2/p/6420577.html