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


    软件简介

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

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

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

    maven开发环境搭建

    使用eclipseIDE,新建maven工程。

    在pom.xml文件中,添加如下内容,引入相关jar。

    spring版本是3.1.0,mybatis版本是3.4.0,mybatis-generator版本是1.3.5。

    <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>datacenter</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>datacenter</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <fasterxml.jackson.version>2.1.1</fasterxml.jackson.version>
            <spring.version>3.1.0.RELEASE</spring.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit-dep</artifactId>
                <version>4.9</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.google.protobuf</groupId>
                <artifactId>protobuf-java</artifactId>
                <version>2.5.0</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>${fasterxml.jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>${fasterxml.jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${fasterxml.jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.dataformat</groupId>
                <artifactId>jackson-dataformat-xml</artifactId>
                <version>${fasterxml.jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.15</version>
            </dependency>
            <dependency>
                <groupId>org.jdom</groupId>
                <artifactId>jdom</artifactId>
                <version>1.1.3</version>
            </dependency>
    
            <dependency>
                <groupId>org.dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>2.0.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.39</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.0</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>1.3.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator -->
            <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>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    View Code

    工程目录结构

    数据库建表

    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) DEFAULT NULL,
      `password` varchar(255) DEFAULT NULL,
      `lastLoginTime` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;

    生成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:Users.m2
    epositorymysqlmysql-connector-java5.1.39mysql-connector-java-5.1.39.jar" />
        <context
            id="MySQL2Tables"
            targetRuntime="MyBatis3"
            defaultModelType="flat">
            <plugin type="com.founder.datacenter.utils.mybatis.MySQLPaginationPlugin" />
            <commentGenerator>
                <property
                    name="suppressDate"
                    value="true" />
                <property
                    name="suppressAllComments"
                    value="true" />
            </commentGenerator>
            <!--数据库链接地址账号密码 -->
            <jdbcConnection
                driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/mybatis?useSSL=false"
                userId="root"
                password="123456">
            </jdbcConnection>
            <javaTypeResolver>
                <property
                    name="forceBigDecimals"
                    value="false" />
            </javaTypeResolver>
            <!--生成Model类存放位置 -->
            <javaModelGenerator
                targetPackage="com.founder.datacenter.model"
                targetProject="src/main/java">
                <property
                    name="enableSubPackages"
                    value="true" />
                <property
                    name="trimStrings"
                    value="true" />
            </javaModelGenerator>
            <!--生成映射文件存放位置 -->
            <sqlMapGenerator
                targetPackage="com.founder.datacenter.dao.mapper"
                targetProject="src/main/java">
                <property
                    name="enableSubPackages"
                    value="true" />
            </sqlMapGenerator>
            <!--生成Dao类存放位置 -->
            <javaClientGenerator
                type="XMLMAPPER"
                targetPackage="com.founder.datacenter.dao.mapper"
                targetProject="src/main/java">
                <property
                    name="enableSubPackages"
                    value="true" />
            </javaClientGenerator>
            <!--生成对应表及类名 -->
            <table
                tableName="%"
                enableCountByExample="true"
                enableUpdateByExample="true"
                enableDeleteByExample="true"
                enableSelectByExample="true"
                selectByExampleQueryId="false"></table>
        </context>
    </generatorConfiguration>
    View Code

    编写代码生成脚本

    package com.founder.datacenter.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

     脚本运行后,会在指定的目录生成代码文件。

    测试生成的代码

     首先在src/main/conf目录下添加配置文件,其中包括jsbc.properties的配置文件,mybatis-spring的配置文件,以及service bean的配置文件。

    spring相关的配置文件放置在src/main/conf/spring目录下。

    jdbc.properties

    jdbc.driverClassName:com.mysql.jdbc.Driver
    jdbc.url:jdbc:mysql://localhost:3306/mybatis?useSSL=false
    jdbc.username:root
    jdbc.password:123456

    spring-mybatis.xml

    <?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"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:jee="http://www.springframework.org/schema/jee"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
               http://www.springframework.org/schema/context  
               http://www.springframework.org/schema/context/spring-context-3.0.xsd  
               http://www.springframework.org/schema/aop  
               http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
               http://www.springframework.org/schema/jee
               http://www.springframework.org/schema/jee/spring-jee-3.0.xsd 
               http://www.springframework.org/schema/tx     
               http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
    
        <!-- 引入dbconfig.properties属性文件 -->
        <context:property-placeholder location="classpath:jdbc.properties" />
        <!-- ========================================配置数据源========================================= -->
        <!-- 配置数据源 -->
        <bean id="dataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName">
                <value>${jdbc.driverClassName}</value>
            </property>
            <property name="url">
                <value>${jdbc.url}</value>
            </property>
            <property name="username">
                <value>${jdbc.username}</value>
            </property>
            <property name="password">
                <value>${jdbc.password}</value>
            </property>
        </bean>
    
        <!-- 自动扫描目录下所有SQL映射的xml文件, -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="mapperLocations" value="classpath:com/founder/datacenter/dao/mapper/*.xml" />
        </bean>
        <!-- 扫描指定包以及子包下的所有映射接口类 -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
            <property name="basePackage" value="com.founder.datacenter.dao.mapper" />
        </bean>
    
        <!-- 配置Spring的事务管理器 -->
        <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
    
        <!-- 注解方式配置事物 -->
        <tx:annotation-driven transaction-manager="transactionManager" />
    
    </beans>

    spring-service.xml

    <?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"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:jee="http://www.springframework.org/schema/jee"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
               http://www.springframework.org/schema/context  
               http://www.springframework.org/schema/context/spring-context-3.0.xsd  
               http://www.springframework.org/schema/aop  
               http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
               http://www.springframework.org/schema/jee
               http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
               http://www.springframework.org/schema/mvc 
               http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
    <!--其实component-scan 就有了annotation-config的功能即把需要的类注册到了spring容器中 --> <context:component-scan base-package="com.founder.datacenter.service" /> <!-- 可以使用@Service注解,完成service的bean声明,不必在spring文件中添加bean --> </beans>

    ExampleService.java

    package com.founder.datacenter.service;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.founder.datacenter.dao.mapper.UserMapper;
    import com.founder.datacenter.model.User;
    import com.founder.datacenter.model.UserExample;
    
    @Service("ExampleService")
    public class ExampleService {
        @Autowired
        private UserMapper userMapper;
    
        public boolean existUser(String name) {
            UserExample userE = new UserExample();
            userE.createCriteria().andNameEqualTo(name);
            userE.setDistinct(true);
            List<User> user = userMapper.selectByExample(userE);
            if (user.size() > 0)
                return true;
            else
                return false;
        }
    }

    测试代码

    package com.founder.datacenter;
    
    import static org.junit.Assert.assertEquals;
    
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.founder.datacenter.service.ExampleService;
    
    public class AppTest {
        BeanFactory factory;
    
        @Before
        public void before() {
            factory = new ClassPathXmlApplicationContext("spring/spring-*.xml");
            System.out.println("@Before");
        }
    
        @After
        public void after() {
            System.out.println("@After");
        }
    
        @Test
        public void exitTest() {
            ExampleService service = factory.getBean("ExampleService", ExampleService.class);
            assertEquals(service.existUser("mahuan2"), true);
        }
    }

    mysql表中插入了一条name为mahuan2的数据。

    测试结果通过。

    分页功能添加

    原始生成的代码是无法完成分页功能的,因为需要添加自定义插件,增加分页功能。

    插件代码

    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

    mysql的分页形式为limit startIndex,count的形式。

    在build-mybatis.xml中增加插件信息,在生成代码后,便可以使用分页功能了。

    生成代码中,UserExample增加了两个变量,UserMapper.xml相应的增加了limit的语句。

    使用分页的代码

    package com.founder.datacenter.service;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.founder.datacenter.dao.mapper.UserMapper;
    import com.founder.datacenter.model.User;
    import com.founder.datacenter.model.UserExample;
    
    @Service("ExampleService")
    public class ExampleService {
        @Autowired
        private UserMapper userMapper;
    
        public boolean existUser(String name) {
            UserExample userE = new UserExample();
            userE.createCriteria().andNameEqualTo(name);
            userE.setLimitStart(0);
            userE.setCount(1);
            userE.setDistinct(true);
            List<User> user = userMapper.selectByExample(userE);
            if (user.size() > 0)
                return true;
            else
                return false;
        }
    }

    表示在select的结果集中,从0索引开始,选择一行数据。

    测试代码通过。

  • 相关阅读:
    mysql的基础增删改查(一)
    用sql的avg(score)求完平均值后,保存两位小数的方法(用于查询或视图)
    异常java.lang.IllegalArgumentException:attempt to create delete event with null entity
    jsp传到java的control层的方法
    Java基础知识整理(一)
    DataTables warning (table id = 'DataTables_Table_0');错误解决办法!
    关于HTML学习整理(一)
    jQuery EasyUI 数据网格
    EasyUI DataGrid分页数据绑定
    SQL输出矩阵
  • 原文地址:https://www.cnblogs.com/mahuan2/p/5859921.html
Copyright © 2020-2023  润新知