coding……
但行好事 莫问前程

使用Mybatis Generator自动生成代码

看过前几篇关于Mybatis的文章可以发现,在DAO层做数据库交互时,存在两中方式。一种为使用注解手写mapper.xml,这种方式比较复杂,手写xml文件相当麻烦。另一种较手写mapper.xml文件简单一些,就是使用注解(@Select、@Update、@Insert、@Delete)的方式,但是手写sql也经常会带来一些隐式错误,并切也要手写sql,而Mybatis Generator的出现很好解决了这个痛点,Mybatis Generator可以自动生成dao层接口、pojo以及mapper.xml。DAO层可以使用Mybatis Generator自动生成的接口的现有功能,来完成具体业务需求。本篇文章将讲述一下Mybatis Generator插件的配置,及具体使用方法。

1. 项目结构

|   pom.xml
|   springboot-07-mybatis-generator.iml
|
+---src
|   +---main
|   |   +---java
|   |   |   \---com
|   |   |       \---zhuoli
|   |   |           \---service
|   |   |               \---springboot
|   |   |                   \---mybatis
|   |   |                       \---generator
|   |   |                           |   SpringBootMybatisGeneratorApplicationContext.java
|   |   |                           |
|   |   |                           +---controller
|   |   |                           |       UserController.java
|   |   |                           |
|   |   |                           +---repository
|   |   |                           |   +---conf
|   |   |                           |   |       DataSourceConfig.java
|   |   |                           |   |
|   |   |                           |   +---mapper
|   |   |                           |   |       UserMapper.java
|   |   |                           |   |
|   |   |                           |   +---model
|   |   |                           |   |       User.java
|   |   |                           |   |       UserExample.java
|   |   |                           |   |
|   |   |                           |   \---service
|   |   |                           |       |   UserRepository.java
|   |   |                           |       |
|   |   |                           |       \---impl
|   |   |                           |               UserRepositoryImpl.java
|   |   |                           |
|   |   |                           \---service
|   |   |                               |   UserControllerService.java
|   |   |                               |
|   |   |                               \---impl
|   |   |                                       UserControllerServiceImpl.java
|   |   |
|   |   \---resources
|   |       |   application.properties
|   |       |
|   |       +---autogen
|   |       |       generatorConfig_zhuoli.xml
|   |       |
|   |       \---base
|   |           \---com
|   |               \---zhuoli
|   |                   \---service
|   |                       \---springboot
|   |                           \---mybatis
|   |                               \---generator
|   |                                   \---repository
|   |                                       \---mapper
|   |                                               UserMapper.xml
|   |
|   \---test
|       \---java

其中generatorConfig_zhuoli.xml文件就是Mybatis Generator的配置文件。

2. 新建user表

CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `user_name` varchar(25) DEFAULT NULL COMMENT '用户名称',
  `description` varchar(25) DEFAULT NULL COMMENT '描述',
  `is_deleted` tinyint(3) DEFAULT NULL COMMENT '是否删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

3. pom.xml添加Mybatis-Generator插件依赖

<?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.zhuoli.service</groupId>
    <artifactId>springboot-07-mybatis-generator</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- Spring Boot 启动父依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
    </parent>

    <build>
        <plugins>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.5</version>
                <!--如果不配置configuration节点,Mybatis Generator配置文件名字必须为generatorConfig.xml-->
                <configuration>
                    <!--可以自定义generatorConfig文件名-->
                    <configurationFile>src/main/resources/autogen/generatorConfig_zhuoli.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- Exclude Spring Boot's Default Logging -->
        <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.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.2</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

</project>

4. application.properties配置

本文示例,数据源采用上篇文章介绍的Java Config配置数据源,application.properties文件中定义数据库信息,用于在Java Config中使用,如下:

##数据源配置
test.datasource.url=jdbc:mysql://115.47.149.48:3306/zhuoli_test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
test.datasource.username=zhuoli
test.datasource.password=zhuoli
test.datasource.driverClassName=com.mysql.jdbc.Driver

5. 数据源配置

@Configuration
@MapperScan(basePackages = "com.zhuoli.service.springboot.mybatis.generator.repository.mapper", sqlSessionFactoryRef = "sqlSessionFactory")
public class DataSourceConfig {
    @Value("${test.datasource.url}")
    private String url;

    @Value("${test.datasource.username}")
    private String user;

    @Value("${test.datasource.password}")
    private String password;

    @Value("${test.datasource.driverClassName}")
    private String driverClass;

    @Bean(name = "dataSource")
    public DataSource dataSource() {
        PooledDataSource dataSource = new PooledDataSource();
        dataSource.setDriver(driverClass);
        dataSource.setUrl(url);
        dataSource.setUsername(user);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean(name = "transactionManager")
    public DataSourceTransactionManager dataSourceTransactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);

        /*设置mapper文件位置*/
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:base/com/zhuoli/service/springboot/mybatis/generator/repository/mapper/*.xml"));
        return sessionFactory.getObject();
    }
}

注意一定要添加@MapperScan注解,否则因为Mybatis Generator生成的Mapper类并没有@Mapper注解,在Repository层无法Autowired。

6. Mybatis Generator插件配置文件

<?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>

    <!--注意:本地需要有mysql-connector-java-5.1.45-bin.jar-->
    <classPathEntry location="D:\\mysql-connector-java-5.1.45-bin.jar"/>
    <context id="DB2Tables" targetRuntime="MyBatis3">

        <property name="javaFileEncoding" value="UTF-8"/>
        <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
        <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>

        <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"/>
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>

        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--数据源-->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://115.47.149.48:3306/zhuoli_test?zeroDateTimeBehavior=convertToNull&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"
                        userId="zhuoli"
                        password="zhuoli">
        </jdbcConnection>

        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!--Model & Example文件-->
        <javaModelGenerator targetPackage="com.zhuoli.service.springboot.mybatis.generator.repository.model"
                            targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!--Mapper.xml文件-->
        <sqlMapGenerator targetPackage="com.zhuoli.service.springboot.mybatis.generator.repository.mapper"
                         targetProject="src/main/resources/base">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!--Mapper文件-->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.zhuoli.service.springboot.mybatis.generator.repository.mapper"
                             targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!--表映射-->
        <table tableName="user" domainObjectName="User">
            <generatedKey column="id" sqlStatement="JDBC" identity="true"/>
            <columnOverride column="id" javaType="Long"/>
            <columnOverride column="is_deleted" javaType="Integer"/>
        </table>

    </context>
</generatorConfiguration>

7. Mybatis Generator插件使用

对于Idea用户,可以使用Ide集成的Maven插件运行Mybatis Generator,操作方法为:Maven Projects -> Plugins->mybatis-generator->mybatis-generator:generate->右键 Run Maven Build

看到console提示SUCCESS的时候,就表明Mybatis Generator已经运行成功,代码已经自动生成了。如果本地装了maven,还可以使用命令行方式运行,在Terminal运行命令”mvn mybatis-generator:generate”。

不知道是Mybatis Generator的bug还是其他原因,如果之前运行过Mybatis Generator插件并且已经生成POJO、Mapper、Mapper.xml文件,如果再次执行时,第二次生成的Mapper.xml文件并不会替换之前生成的文件,而是会去追加,POJO和Mapper类都是替换的。所以重新运行Mybatis Generator时,要先删除之前生成的Mapper.xml文件

8. Mybatis Generator自动生成的代码介绍

对于一张表,Mybatis Generator生成的文件有四个,以本文的user表为例,我再配置文件中generatorConfig_zhuoli.xml中配置了user表的映射,所以生成的文件有以下四个:

8.1 POJO实体类

public class User implements Serializable {
    private Long id;

    private String userName;

    private String description;

    private Integer isDeleted;

    private static final long serialVersionUID = 1L;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName == null ? null : userName.trim();
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description == null ? null : description.trim();
    }

    public Integer getIsDeleted() {
        return isDeleted;
    }

    public void setIsDeleted(Integer isDeleted) {
        this.isDeleted = isDeleted;
    }
}

8.2 Example类

Example类主要用做查询、更新、删除时的条件定义,通俗的讲就是用来定义where后面的条件,底层通过一个Criteria静态内部类实现条件定义的,对于这个自动生成的类不用太多研究,结合使用场景,就能很好理解了,篇幅原因这里也不粘代码了,建议具体去操作一下。使用方法如下:

xxxExample example = new xxxExample(); 
UserExample.Criteria criteria = example.createCriteria();
方法 说明
example.setOrderByClause(“字段名 ASC”); 添加升序排列条件,DESC为降序
example.setDistinct(false) 去除重复,boolean型,true为选择不重复的记录。
criteria.andXxxIsNull 添加字段xxx为null的条件
criteria.andXxxIsNotNull 添加字段xxx不为null的条件
criteria.andXxxEqualTo(value) 添加xxx字段等于value条件
criteria.andXxxNotEqualTo(value) 添加xxx字段不等于value条件
criteria.andXxxGreaterThan(value) 添加xxx字段大于value条件
criteria.andXxxGreaterThanOrEqualTo(value) 添加xxx字段大于等于value条件
criteria.andXxxLessThan(value) 添加xxx字段小于value条件
criteria.andXxxLessThanOrEqualTo(value) 添加xxx字段小于等于value条件
criteria.andXxxIn(List<?>) 添加xxx字段值在List<?>条件
criteria.andXxxNotIn(List<?>) 添加xxx字段值不在List<?>条件
criteria.andXxxLike(“%”+value+”%”) 添加xxx字段值为value的模糊查询条件
criteria.andXxxNotLike(“%”+value+”%”) 添加xxx字段值不为value的模糊查询条件
criteria.andXxxBetween(value1,value2) 添加xxx字段值在value1和value2之间条件
criteria.andXxxNotBetween(value1,value2) 添加xxx字段值不在value1和value2之间条件

8.3 DAO接口Mapper

其实这个Mapper跟之前我手写的mapper类是一个概念,都是定义接口,底层依赖mapper.xml文件实现具体sql操作。Mybatis Generator对生成的Mapper做了抽象,即每一张表生成的mapper类方法名都是一样的,使用这些方法,可以满足绝大多数简单sql操作,省去了我们手写sql的麻烦。

public interface UserMapper {
    long countByExample(UserExample example);

    int deleteByExample(UserExample example);

    int deleteByPrimaryKey(Long id);

    int insert(User record);

    int insertSelective(User record);

    List<User> selectByExampleWithRowbounds(UserExample example, RowBounds rowBounds);

    List<User> selectByExample(UserExample example);

    User selectByPrimaryKey(Long id);

    int updateByExampleSelective(@Param("record") User record, @Param("example") UserExample example);

    int updateByExample(@Param("record") User record, @Param("example") UserExample example);

    int updateByPrimaryKeySelective(User record);

    int updateByPrimaryKey(User record);
}

方法说明:

方法 功能说明
int countByExample(UserExample example) thorws SQLException 按条件计数
int deleteByPrimaryKey(Integer id) thorws SQLException 按主键删除
int deleteByExample(UserExample example) thorws SQLException 按条件查询
String/Integer insert(User record) thorws SQLException 插入数据(返回值为ID)
User selectByPrimaryKey(Integer id) thorws SQLException 按主键查询
ListselectByExample(UserExample example) thorws SQLException 按条件查询
ListselectByExampleWithBLOGs(UserExample example) thorws SQLException 按条件查询(包括BLOB字段)。只有当数据表中的字段类型有为二进制的才会产生。
int updateByPrimaryKey(User record) thorws SQLException 按主键更新
int updateByPrimaryKeySelective(User record) thorws SQLException 按主键更新值不为null的字段
int updateByExample(User record, UserExample example) thorws SQLException 按条件更新
int updateByExampleSelective(User record, UserExample example) thorws SQLException 按条件更新值不为null的字段

8.4 Mapper.xml文件

与之前文章手写的mapper.xml文件一样,Mybatis Generator插件生成的mapper.xml文件同样用来定义sql语句(支持动态查询)。

9. 使用生成的DAO接口实特定功能

代码中我定义了一个UserRepository接口,用于给Service层调用。

public interface UserRepository {
    List<User> getAllUsers();

    List<User> getUserByCondition(String userName, String description);

    User getUserById(Long id);

    int delUserById(Long id);

    int createUser(User user);

    int updateUser(User user);
}

实现类如下:

@Repository
@AllArgsConstructor
public class UserRepositoryImpl implements UserRepository {

    private UserMapper userMapper;

    @Override
    public List<User> getAllUsers() {
        UserExample example = new UserExample();
        return userMapper.selectByExample(example);
    }

    @Override
    public List<User> getUserByCondition(String userName, String description) {
        UserExample example = new UserExample();
        /*动态sql,userName和description不为null,则作为查询条件查询*/
        UserExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isNullOrEmpty(userName)) {
            criteria.andUserNameEqualTo(userName);
        }
        if (!StringUtils.isNullOrEmpty(description)) {
            criteria.andDescriptionEqualTo(description);
        }
        return userMapper.selectByExample(example);
    }

    @Override
    public User getUserById(Long id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public int delUserById(Long id) {
        UserExample example = new UserExample();
        example.createCriteria().andIdEqualTo(id);
        return userMapper.deleteByExample(example);
        /*等价于
        return userMapper.deleteByPrimaryKey(id);
        */
    }

    @Override
    public int createUser(User user) {
        return userMapper.insertSelective(user);
    }

    @Override
    public int updateUser(User user) {
        return userMapper.updateByPrimaryKey(user);
    }
}

10. Service层定义

public interface UserControllerService {
    List<User> getAllUsers();

    List<User> getByCondition(String userName, String description);

    User getUserById(Long id);

    int delUserById(Long id);

    int createUser(User user);

    int updateUser(User user);
}

实现这里不粘了,就是调用UserRepository交互数据库。

11. Controller层定义

@RestController
@AllArgsConstructor
@RequestMapping(value = "/user")
@Slf4j
public class UserController {

    private UserControllerService userControllerService;

    @RequestMapping(value = "/get_all", method = RequestMethod.POST)
    public ResponseEntity getAllUser() {
        return ResponseEntity.status(HttpStatus.OK).body(userControllerService.getAllUsers());
    }

    @RequestMapping(value = "/get_by_condition", method = RequestMethod.POST)
    public ResponseEntity getUserByCondition(@RequestParam(value = "userName") String userName,
                                             @RequestParam(value = "description") String description) {
        return ResponseEntity.status(HttpStatus.OK).body(userControllerService.getByCondition(userName, description));
    }

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public ResponseEntity createUser(@RequestParam(value = "userName") String userName,
                                     @RequestParam(value = "description") String description) {
        User user = new User();
        user.setUserName(userName);
        user.setDescription(description);

        userControllerService.createUser(user);
        return ResponseEntity.status(HttpStatus.OK).body("create user success");
    }

    @RequestMapping(value = "/query_user", method = RequestMethod.POST)
    public ResponseEntity queryUserById(@RequestParam(value = "id") Long id) {
        return ResponseEntity.status(HttpStatus.OK).body(userControllerService.getUserById(id));
    }

    @RequestMapping(value = "/update_user", method = RequestMethod.POST)
    public ResponseEntity updateUserById(@RequestParam(value = "id") Long id,
                                         @RequestParam(value = "userName") String userName,
                                         @RequestParam(value = "description") String description) {
        User user = new User();
        user.setId(id);
        user.setUserName(userName);
        user.setDescription(description);
        userControllerService.updateUser(user);
        return ResponseEntity.status(HttpStatus.OK).body("update user success");
    }

    @RequestMapping(value = "/del_user", method = RequestMethod.POST)
    public ResponseEntity deleteUserById(@RequestParam(value = "id") Long id) {
        userControllerService.delUserById(id);
        return ResponseEntity.status(HttpStatus.OK).body("del user success");
    }
}

12. 测试

使用postman进行接口测试,由于controller方法参数使用的是@RequestParam接收的,所以测试时,请求头要设置为x-www-form-urlencoded,否则会报“HTTP Status 400 – Required String parameter ‘xx’ is not present”错,具体请查看

示例代码:码云 – 卓立 – Mybatis Generator使用示例

 

 

赞(0) 打赏
Zhuoli's Blog » 使用Mybatis Generator自动生成代码
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址