MyBatis学习笔记2--创建逆向工程

逆向工程

mybatis的一个主要的特点就是需要程序员自己编写sql,那么如果表太多的话,难免会很麻烦,所以mybatis官方提供了一个逆向工程,可以针对单表自动生成mybatis执行所需要的代码(包括mapper.xml、mapper.java、po…)。一般在开发中,常用的逆向工程方式是通过数据库的表生成代码。

生成逆向工程需要用到 MyBatis Generator (MBG), MBG是MyBatis和iBATIS的代码生成器,它将为所有版本的MyBatis以及版本2.2.0之后的iBATIS版本生成代码。MBG对简单CRUD(增删改查)的大部分数据库操作产生重大影响。但是您仍然需要为连接查询或存储过程手动编写SQL和对象代码。

生成逆向工程

首先需要引入MyBatis-generator所需要的jar包。

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.41</version>
    </dependency>

下面通过官网的 quick start 教程生成一个简单的逆向工程。

在工程下创建 MyBatis Generator 的配置文件,其中包含如下配置:

  • <jdbcConnection> 数据库连接信息
  • <javaModelGenerator> java模型生成(指定java Bean 生成的位置)
  • <sqlMapGenerator> 指定sql映射文件生成的位置
  • <javaClientGenerator> 指定dao接口生成的位置,Mapper接口
  • <table> 指定每个表的生成策略

以上选项的具体的设定都可以在官网相关文档XML Configuration Reference 里面学习。

官网给我们举了一个简单的例子,可以参考它完成我们的配置。

<?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="/Program Files/IBM/SQLLIB/java/db2java.zip" />
  
  //配置数据库连接信息,这些需要自己配
  <context id="DB2Tables" targetRuntime="MyBatis3">
    <jdbcConnection driverClass="COM.ibm.db2.jdbc.app.DB2Driver"
        connectionURL="jdbc:db2:TEST"
        userId="db2admin"
        password="db2admin">
    </jdbcConnection>
    
   //java类型解析
    <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>
    
    //ava模型生成(指定java Bean 生成的位置)
    <javaModelGenerator targetPackage="test.model"    //指定生位置(文件夹)
      targetProject="\MBGTestProject\src">            //指定在那个工程下生成
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>
    
    //指定sql映射文件生成的位置
    <sqlMapGenerator targetPackage="test.xml"     //指定生位置(文件夹)
    	targetProject="\MBGTestProject\src">      //指定在那个工程下生成
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>
    
    //指定dao接口生成的位置,Mapper接口
    <javaClientGenerator type="XMLMAPPER" targetPackage="test.dao"
      targetProject="\MBGTestProject\src">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>
     
     //指定每个表的生成策略(具体生成策略在官网查看)
    <table tableName="book" domainObjectName="Books" ></table>
    <table tableName="papers" domainObjectName="Papers" ></table>
  </context>
</generatorConfiguration>

现在我们生成了配置文件,接下来通过逆向工程生成相应的javaBean 和配置文件 。在官网的 Running MyBatis Generator 下提供了以下几种方案,现在我们使用Java生成逆向工程

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;

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

public class MbjTest {
    public static void main(String[] args) throws IOException, XMLParserException, SQLException, InterruptedException, InvalidConfigurationException {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("mbj.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);

    }
}

假如我有三张表格分别为book, ticket, user,现在通过上面步骤生成一个简单的逆向工程。如下结构

在这里插入图片描述

MyBatis逆向工程类解析

我们表book为例,分析逆向工程生成的Book类, BookExample类,BookMapper以及生成的配置文件BookMapper.xml。

Book类就是根据数据库表应用ORM思想产生对应的属性以及get set方法,这里不再赘述,如下:

public class Book {
    private Integer id;

    private String name;

    private String author;

    private String price;

    private Integer status;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name == null ? null : name.trim();
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author == null ? null : author.trim();
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price == null ? null : price.trim();
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }


    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price='" + price + '\'' +
                ", status=" + status +
                '}';
    }
}

BookMapper类为逆向工程相对应的查询方法,与BookMapper.xml相对应:

public interface BookMapper {
    long countByExample(BookExample example);

    int deleteByExample(BookExample example);
	//按照主键删除
    int deleteByPrimaryKey(Integer id);
	//插入
    int insert(Book record);
	//选择性插入
    int insertSelective(Book record);
	//按照条件查询
    List<Book> selectByExample(BookExample example);
	//按照主键查询
    Book selectByPrimaryKey(Integer id);
	/*
	按照条件选择性更新
	第一个参数 是要修改的部分值组成的对象,其中有些属性为null则表示该项不修改。
 	第二个参数 是一个对应的查询条件的类, 通过这个类可以实现 order by 和一部分的where 条件
	*/
    int updateByExampleSelective(@Param("record") Book record, @Param("example") BookExample example);
	//按照条件更新
    int updateByExample(@Param("record") Book record, @Param("example") BookExample example);
	//按照主键选择性更新
    int updateByPrimaryKeySelective(Book record);
	//按照主键更新
    int updateByPrimaryKey(Book record);
}

下面查看 BookExample类,example类与实体类对应,是根据example根据Book类的属性设定相应的方法用作动态查询, 它可以使我们在查询的过程中添加各种复杂的筛选条件 如 whereorder by等:

package com.zhangbing.bean;

import java.util.ArrayList;
import java.util.List;

public class BookExample {

	//指定按照某个字段进行升序还是降序:字段+空格+asc(desc) 
    protected String orderByClause;
 	//去除重复:true是选择不重复记录,false,反之
    protected boolean distinct;
	//自定义查询条件
    protected List<Criteria> oredCriteria;

    public BookExample() {
        oredCriteria = new ArrayList<Criteria>();
    }

    public void setOrderByClause(String orderByClause) {
        this.orderByClause = orderByClause;
    }

    public String getOrderByClause() {
        return orderByClause;
    }

    public void setDistinct(boolean distinct) {
        this.distinct = distinct;
    }

    public boolean isDistinct() {
        return distinct;
    }

    public List<Criteria> getOredCriteria() {
        return oredCriteria;
    }

    public void or(Criteria criteria) {
        oredCriteria.add(criteria);
    }

    public Criteria or() {
        Criteria criteria = createCriteriaInternal();
        oredCriteria.add(criteria);
        return criteria;
    }

    public Criteria createCriteria() {
        Criteria criteria = createCriteriaInternal();
        if (oredCriteria.size() == 0) {
            oredCriteria.add(criteria);
        }
        return criteria;
    }
    //生成 Criteria 类的方法
    protected Criteria createCriteriaInternal() {
        Criteria criteria = new Criteria();
        return criteria;
    }
	
    public void clear() {
        oredCriteria.clear();
        orderByClause = null;
        distinct = false;
    }
	//定义
    protected abstract static class GeneratedCriteria {
        protected List<Criterion> criteria;

        protected GeneratedCriteria() {
            super();
            criteria = new ArrayList<Criterion>();
        }

        public boolean isValid() {
            return criteria.size() > 0;
        }

        public List<Criterion> getAllCriteria() {
            return criteria;
        }

        public List<Criterion> getCriteria() {
            return criteria;
        }

        protected void addCriterion(String condition) {
            if (condition == null) {
                throw new RuntimeException("Value for condition cannot be null");
            }
            criteria.add(new Criterion(condition));
        }

        protected void addCriterion(String condition, Object value, String property) {
            if (value == null) {
                throw new RuntimeException("Value for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value));
        }

        protected void addCriterion(String condition, Object value1, Object value2, String property) {
            if (value1 == null || value2 == null) {
                throw new RuntimeException("Between values for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value1, value2));
        }
		// 添加字段xxx为null的条件
        public Criteria andIdIsNull() {
            addCriterion("id is null");
            return (Criteria) this;
        }
		//添加字段xxx不为null的条件 
        public Criteria andIdIsNotNull() {
            addCriterion("id is not null");
            return (Criteria) this;
        }
		//添加xxx字段等于value条件  
        public Criteria andIdEqualTo(Integer value) {
            addCriterion("id =", value, "id");
            return (Criteria) this;
        }
		//添加xxx字段不等于value条件  
        public Criteria andIdNotEqualTo(Integer value) {
            addCriterion("id <>", value, "id");
            return (Criteria) this;
        }
		//添加xxx字段大于value条件  
        public Criteria andIdGreaterThan(Integer value) {
            addCriterion("id >", value, "id");
            return (Criteria) this;
        }
		//添加xxx字段大于等于value条件  
        public Criteria andIdGreaterThanOrEqualTo(Integer value) {
            addCriterion("id >=", value, "id");
            return (Criteria) this;
        }
		//添加xxx字段小于value条件 
        public Criteria andIdLessThan(Integer value) {
            addCriterion("id <", value, "id");
            return (Criteria) this;
        }
		//添加xxx字段小于等于value条件 
        public Criteria andIdLessThanOrEqualTo(Integer value) {
            addCriterion("id <=", value, "id");
            return (Criteria) this;
        }
		//添加xxx字段值在List  
        public Criteria andIdIn(List<Integer> values) {
            addCriterion("id in", values, "id");
            return (Criteria) this;
        }
		//不添加xxx字段值在List
        public Criteria andIdNotIn(List<Integer> values) {
            addCriterion("id not in", values, "id");
            return (Criteria) this;
        }
		//添加xxx字段值在之间
        public Criteria andIdBetween(Integer value1, Integer value2) {
            addCriterion("id between", value1, value2, "id");
            return (Criteria) this;
        }
		//添加xxx字段值不在之间 
        public Criteria andIdNotBetween(Integer value1, Integer value2) {
            addCriterion("id not between", value1, value2, "id");
            return (Criteria) this;
        }
		/*
		下面为name字段以及其他属性的设置与上面相类似,这里不再赘述

		*/
    }
    
	//内部Criteria类用来封装自定义查询条件
    public static class Criteria extends GeneratedCriteria {

        protected Criteria() {
            super();
        }
    }

    public static class Criterion {
        private String condition;

        private Object value;

        private Object secondValue;

        private boolean noValue;

        private boolean singleValue;

        private boolean betweenValue;

        private boolean listValue;

        private String typeHandler;

        public String getCondition() {
            return condition;
        }

        public Object getValue() {
            return value;
        }

        public Object getSecondValue() {
            return secondValue;
        }

        public boolean isNoValue() {
            return noValue;
        }

        public boolean isSingleValue() {
            return singleValue;
        }

        public boolean isBetweenValue() {
            return betweenValue;
        }

        public boolean isListValue() {
            return listValue;
        }

        public String getTypeHandler() {
            return typeHandler;
        }

        protected Criterion(String condition) {
            super();
            this.condition = condition;
            this.typeHandler = null;
            this.noValue = true;
        }

        protected Criterion(String condition, Object value, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.typeHandler = typeHandler;
            if (value instanceof List<?>) {
                this.listValue = true;
            } else {
                this.singleValue = true;
            }
        }

        protected Criterion(String condition, Object value) {
            this(condition, value, null);
        }

        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.secondValue = secondValue;
            this.typeHandler = typeHandler;
            this.betweenValue = true;
        }

        protected Criterion(String condition, Object value, Object secondValue) {
            this(condition, value, secondValue, null);
        }
    }
}

测试生成的逆向工程

1、在resources下配置sqlmapconfig

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">    <!--约束-->
<!--mybatis的主配置文件-->
<configuration>
    <!--配置环境-->
    <properties resource="dbconfig.properties"></properties>

    <environments default="mysql">
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="jdbc"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的四个基本信息-->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.jdbcUrl}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>

        </environment>
    </environments>

    <!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
    <mappers>
        <mapper resource="Mapper/xml/BookMapper.xml"/>
        <mapper resource="Mapper/xml/TicketMapper.xml"/>
        <mapper resource="Mapper/xml/UserMapper.xml"/>
    </mappers>

</configuration>

2、 测试CRUD

public class MyBatisTest {

    SqlSession session;
    InputStream in;


    BookMapper bookMapper;

    Book book;
    @Before
    public void init() throws Exception{

        in = Resources.getResourceAsStream("SqlMapConfig.xml");

        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

        SqlSessionFactory factory = builder.build(in);
        session = factory.openSession();
        bookMapper = session.getMapper(BookMapper.class);
    }

    @After
    public void destory() throws Exception{
        session.close();
        in.close();
    }


    /*
    * 测试插入数据
    * */
    @Test
    public void testCreate(){
        Book book = new Book();
        book.setId(2);
        book.setAuthor("周志华");
        book.setName("机器学习");
        book.setPrice("88");
        book.setStatus(0);
        bookMapper.insert(book);
        session.commit();

    }

    /*
     * 测试读取数据
     * */
    @Test
    public void testRead(){

        BookExample bookExample = new BookExample();
        bookExample.setOrderByClause("id desc");
        bookExample.setDistinct(false);

        BookExample.Criteria criteria = bookExample.createCriteria();
        criteria.andIdEqualTo(1);
        List<Book> books = bookMapper.selectByExample(bookExample);
        for(Book b : books){
            System.out.println(b);
        }
    }
    /*
    * 测试更新数据 updateByExampleSelective updateByExample
    *             updateByPrimaryKeySelective updateByPrimaryKey 四个方法
    * */
    @Test
    public void testUpdateByExampleSelective(){
        Book newbook = new Book(1, "高性能MySql", "Baron Scbwart", "99", 1);
        BookExample bookExample = new BookExample();
        BookExample.Criteria criteria = bookExample.createCriteria();
        criteria.andIdEqualTo(1);
        criteria.andNameLike("%高%");
        bookMapper.updateByExampleSelective(newbook, bookExample);
        session.commit();
    }

}

这样就生成了一个简单的逆向工程。

发布了44 篇原创文章 · 获赞 27 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42784951/article/details/102653325