User-Profile-Image
hankin
  • 5
  • Java
  • Kotlin
  • Spring
  • Web
  • SQL
  • MegaData
  • More
  • Experience
  • Enamiĝu al vi
  • 分类
    • Zuul
    • Zookeeper
    • XML
    • WebSocket
    • Web Notes
    • Web
    • Vue
    • Thymeleaf
    • SQL Server
    • SQL Notes
    • SQL
    • SpringSecurity
    • SpringMVC
    • SpringJPA
    • SpringCloud
    • SpringBoot
    • Spring Notes
    • Spring
    • Servlet
    • Ribbon
    • Redis
    • RabbitMQ
    • Python
    • PostgreSQL
    • OAuth2
    • NOSQL
    • Netty
    • MySQL
    • MyBatis
    • More
    • MinIO
    • MegaData
    • Maven
    • LoadBalancer
    • Kotlin Notes
    • Kotlin
    • Kafka
    • jQuery
    • JavaScript
    • Java Notes
    • Java
    • Hystrix
    • Git
    • Gateway
    • Freemarker
    • Feign
    • Eureka
    • ElasticSearch
    • Docker
    • Consul
    • Ajax
    • ActiveMQ
  • 页面
    • 归档
    • 摘要
    • 杂图
    • 问题随笔
  • 友链
    • Spring Cloud Alibaba
    • Spring Cloud Alibaba - 指南
    • Spring Cloud
    • Nacos
    • Docker
    • ElasticSearch
    • Kotlin中文版
    • Kotlin易百
    • KotlinWeb3
    • KotlinNhooo
    • 前端开源搜索
    • Ktorm ORM
    • Ktorm-KSP
    • Ebean ORM
    • Maven
    • 江南一点雨
    • 江南国际站
    • 设计模式
    • 熊猫大佬
    • java学习
    • kotlin函数查询
    • Istio 服务网格
    • istio
    • Ktor 异步 Web 框架
    • PostGis
    • kuangstudy
    • 源码地图
    • it教程吧
    • Arthas-JVM调优
    • Electron
    • bugstack虫洞栈
    • github大佬宝典
    • Sa-Token
    • 前端技术胖
    • bennyhuo-Kt大佬
    • Rickiyang博客
    • 李大辉大佬博客
    • KOIN
    • SQLDelight
    • Exposed-Kt-ORM
    • Javalin—Web 框架
    • http4k—HTTP包
    • 爱威尔大佬
    • 小土豆
    • 小胖哥安全框架
    • 负雪明烛刷题
    • Kotlin-FP-Arrow
    • Lua参考手册
    • 美团文章
    • Java 全栈知识体系
    • 尼恩架构师学习
    • 现代 JavaScript 教程
    • GO相关文档
    • Go学习导航
    • GoCN社区
    • GO极客兔兔-案例
    • 讯飞星火GPT
    • Hollis博客
    • PostgreSQL德哥
    • 优质博客推荐
    • 半兽人大佬
    • 系列教程
    • PostgreSQL文章
    • 云原生资料库
    • 并发博客大佬
Help?

Please contact us on our email for need any support

Support
    首页   ›   SQL   ›   MyBatis   ›   正文
MyBatis

MyBatis笔记16—逆向工程

2020-03-20 02:20:43
1019  0 0
参考目录 隐藏
1) 逆向工程的代码使用:
2) 总结:
3) 官方插件
4) Example实例函数使用及详解
5) mapper接口中的函数及方法
6) Example实例解析
7) 应用举例
8) 查询
9) 插入数据
10) 更新数据
11) 删除数据
12) 查询数据数量
13) 处理and、or关系的方法
14) ( xx and xx) or ( xx and xx)
15) xx and ( xx or xx)
16) 封装包使用

阅读完需:约 11 分钟

由于使用数据表时,我们需要给每一个表都创建对应的实体类,每个实体类都有对应的 Mapper 接口和 Mapper.xml 文件,这些其实都是一些重复的工作,我们可以通过第三方工具来完成。

MyBatis 逆向工程非常多,我们 IDEA 里边,也有对应的插件可以使用。

这里以 mybatis-generator-core-1.3.1 工具为例,拿到工具后,首先解压目录:

注意,这里的数据库驱动以 MySQL5.7 为例,如果自己的 MySQL 不是 5.7,这个驱动要换成适合自己 MySQL 的版本。

然后,我们打开 generator.xml 文件,配置我们需要逆向处理的表。

配置完成后,双击 123.bat 运行项目,运行完成后,将 src 目录下生成的代码拷贝到我们的项目中。

逆向工程的生成脚本:

https://github.com/Els-s/mybatis-generator-core-1.3.1

逆向工程的代码使用:

总结:

  • Example和Primarykey用来指定要 删除 / 更新 / 查询 的行。
  • 不加后缀、Selective后缀、WithBLOBs后缀用来限制要 删除 / 更新 / 查询 的列。

官方插件

MyBatis Generator:简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器,可以快速的根据表生成对应的映射文件,接口,以及bean类。支持基本的增删改查,以及QBC风格的条件查询。但是表连接、 存储过程等这些复杂sql的定义需要我们手工编写。

https://github.com/mybatis/generator/releases

GeneratorSqlmap.java

package xin.luxinda.NXProject;
 
import java.io.File;
import java.util.*;
 
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
 
public class GeneratorSqlmap {
 
	public void generator() throws Exception {
		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		// 指定配置文件
		File configFile = new File("./config/NXProject/generatorConfig.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);
	}
 
	// 执行main方法以生成代码
	public static void main(String[] args) {
		try {
			GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
			generatorSqlmap.generator();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

generatorConfig.xml

<?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>
  <context id="DB2Tables" targetRuntime="MyBatis3">
    <commentGenerator>
    	<!-- 是否去除自动生成的注释 -->
    	<property name="suppressAllComments" value="true"/>
    </commentGenerator>
    <!-- Mysql数据库连接的信息:驱动类、连接地址、用户名、密码 -->
    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
        connectionURL="jdbc:mysql://localhost:3306/e3mall"
        userId="root"
        password="111">
    </jdbcConnection>
    <!-- Oracle数据库
	    <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
	        connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"
	        userId="yycg"
	        password="yycg">
	    </jdbcConnection> 
    -->
	
	<!-- 默认为false,把JDBC DECIMAL 和NUMERIC类型解析为Integer,为true时
	把JDBC DECIMAL 和NUMERIC类型解析为java.math.BigDecimal -->
    <javaTypeResolver >
		<property name="forceBigDecimals" value="false" />
    </javaTypeResolver>
	
	<!-- targetProject:生成POJO类的位置 -->
    <javaModelGenerator targetPackage="cn.e3mall.pojo" targetProject=".\src">
		<!-- enableSubPackages:是否让schema作为包的后缀 -->
		<property name="enableSubPackages" value="false" />
		<!-- 从数据库返回的值被清理前后的空格 -->
		<property name="trimStrings" value="true" />
    </javaModelGenerator>
    
	<!-- targetProject:mapper映射文件生成的位置 -->
    <sqlMapGenerator targetPackage="cn.e3mall.mapper"  targetProject=".\src">
		<!-- enableSubPackages:是否让schema作为包的后缀 -->
		<property name="enableSubPackages" value="false" />
    </sqlMapGenerator>
    
	<!-- targetProject:mapper接口生成的的位置 -->
	<javaClientGenerator type="XMLMAPPER" targetPackage="cn.e3mall.mapper"  targetProject=".\src">
		<!-- enableSubPackages:是否让schema作为包的后缀 -->
		<property name="enableSubPackages" value="false" />
    </javaClientGenerator>
    
	<!-- 指定数据表 -->
	<table schema="" tableName="tb_content"></table>
	<table schema="" tableName="tb_content_category"></table>
	<table schema="" tableName="tb_item"></table>
	<table schema="" tableName="tb_item_cat"></table>
	<table schema="" tableName="tb_item_desc"></table>
	<table schema="" tableName="tb_item_param"></table>
	<table schema="" tableName="tb_item_param_item"></table>
	<table schema="" tableName="tb_order"></table>
	<table schema="" tableName="tb_order_item"></table>
	<table schema="" tableName="tb_order_shipping"></table>
	<table schema="" tableName="tb_user"></table>
    
    <!-- 有些表的字段需要指定java类型 
    <table schema="DB2ADMIN" tableName="ALLTYPES" domainObjectName="Customer" >
      <property name="useActualColumnNames" value="true"/>
      <generatedKey column="ID" sqlStatement="DB2" identity="true" />
      <columnOverride column="DATE_FIELD" property="startDate" />
      <ignoreColumn column="FRED" />
      <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
    </table> -->
 
  </context>
</generatorConfiguration>

配置文件需要修改的内容:

  • 数据库驱动、地址、用户名、密码
  • POJO类、mapper接口、mapper映射文件生成的位置
  • 指定数据表

生成后的pojo类中,有一部分是名字为XxxExample的类出现。

注意:如果有N张表,就会生成2N个POJO,N个mapper.java以及N个mapper.xml,也许你会问,为什么会生成2N个POJO呢?那是因为除了常规的POJO之外还生成了用于设置条件的xxxExample,比如图中的TbItem.java和TbItemExample.java,Example的具体使用会在后面详细说。

打开一个Example类我们会看到该类的三个成员变量:

distinct字段用于指定DISTINCT查询。

  • orderByClause字段用于指定ORDER BY条件,这个条件没有构造方法,直接通过传递字符串值指定。
  • oredCriteria字段用于自定义查询条件。
  • 这个类是专门用来对这个单表来查询的类,对该单表的CURD操作是脱离sql性质的(已经通过逆向工程生成相应的sql),直接在service层就可以完成相应操作。
  • 逆向工程生成的文件XxxExample.java中包含一个static 的内部类 Criteria ,在Criteria中有很多方法,主要是定义SQL 语句where后的查询条件。


Example实例函数使用及详解

mapper接口中的函数及方法

方法 功能说明
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 按主键查询
List selectByExample(UserExample example) thorws SQLException 按条件查询
List selectByExampleWithBLOGs(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的字段

Example实例解析

mybatis的逆向工程中会生成实例及实例对应的example,example用于添加条件,相当where后面的部分

xxxExample example = new xxxExample(); 
Criteria criteria = new Example().createCriteria();
方法 说明
example.setOrderByClause(“字段名 ASC”); 添加升序排列条件,DESC为降序
example.setDistinct(false) 去除重复,boolean型,true为选择不重复的记录。
example.clear() 清除条件
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之间条件

应用举例

查询

selectByPrimaryKey()

User user = XxxMapper.selectByPrimaryKey(100); //相当于select * from user where id = 100

selectByExample() 和 selectByExampleWithBLOGs()

UserExample example = new UserExample();
Criteria criteria = example.createCriteria();
criteria.andUsernameEqualTo("wyw");
criteria.andUsernameIsNull();
example.setOrderByClause("username asc,email desc");
List<?>list = XxxMapper.selectByExample(example);
//相当于:
select * from user where username = 'wyw' and  username is null order by username asc,email desc

逆向工程生成的文件XxxExample.java中包含一个static的内部类Criteria,Criteria中的方法是定义SQL 语句where后的查询条件。

插入数据

insert()

User user = new User();
user.setId("dsfgsdfgdsfgds");
user.setUsername("admin");
user.setPassword("admin")
user.setEmail("wyw@163.com");
XxxMapper.insert(user);
//相当于:
insert into user(ID,username,password,email) values ('dsfgsdfgdsfgds','admin','admin','wyw@126.com');

更新数据

updateByPrimaryKey()

User user =new User();
user.setId("dsfgsdfgdsfgds");
user.setUsername("wyw");
user.setPassword("wyw");
user.setEmail("wyw@163.com");
XxxMapper.updateByPrimaryKey(user);
//相当于:
update user set username='wyw', password='wyw', email='wyw@163.com' where id='dsfgsdfgdsfgds'

updateByPrimaryKeySelective()

User user = new User();
user.setId("dsfgsdfgdsfgds");
user.setPassword("wyw");
XxxMapper.updateByPrimaryKey(user);
//相当于:
update user set password='wyw' where id='dsfgsdfgdsfgds'

updateByExample() 和 updateByExampleSelective()

UserExample example = new UserExample();
Criteria criteria = example.createCriteria();
criteria.andUsernameEqualTo("admin");
User user = new User();
user.setPassword("wyw");
XxxMapper.updateByPrimaryKeySelective(user,example);
//相当于:
update user set password='wyw' where username='admin'

updateByExample()更新所有的字段,包括字段为null的也更新,建议使用 updateByExampleSelective()更新想更新的字段

删除数据

deleteByPrimaryKey()

deleteByExample()

UserExample example = new UserExample();
Criteria criteria = example.createCriteria();
criteria.andUsernameEqualTo("admin");
XxxMapper.deleteByExample(example);
//相当于:delete from user where username='admin'

查询数据数量

countByExample()

UserExample example = new UserExample();
Criteria criteria = example.createCriteria();
criteria.andUsernameEqualTo("wyw");
int count = XxxMapper.countByExample(example);
//相当于:
select count(*) from user where username='wyw'

处理and、or关系的方法

( xx and xx) or ( xx and xx) 

BaUserExample baUserExample = new BaUserExample();
 
Criteria criteria1 = baUserExample.createCriteria();
 
criteria1.andOrgIdEqualTo("1");
 
criteria1.andDeptIdEqualTo("1");
 
Criteria criteria2 = baUserExample.createCriteria();
 
criteria2.andUserNameEqualTo("name");
 
criteria2.andEmailLike("%test@%");
 
baUserExample.or(criteria2);
 
userMapper.countByExample(baUserExample);
Preparing: select count(*) from ba_user WHERE ( org_id = ? and dept_id = ? ) 
or( user_name = ? and email like ? )

 
TestTableExample example = new TestTableExample();
 
  example.or().andField1EqualTo(5).andField2IsNull();
 
  example.or().andField3NotEqualTo(9).andField4IsNotNull();
 
  List<Integer> field5Values = new ArrayList<Integer>();
  field5Values.add(8);
  field5Values.add(11);
  field5Values.add(14);
  field5Values.add(22);
 
  example.or().andField5In(field5Values);
 
  example.or().andField6Between(3, 7);
select * from table where (field1 = 5 and field2 is null)
     or (field3 <> 9 and field4 is not null)
     or (field5 in (8, 11, 14, 22))
     or (field6 between 3 and 7)

xx and ( xx or xx)

根据逻辑表达式可以知道 a and ( b or c ) = ( a and b) or ( a and c )

所以就转变成第一种方法

举个例子,假如想要实现 select count(*) from ba_user WHERE userName like ? and ( dept_id is null or dept_id <>? )

可以转化为select count(*) from ba_user WHERE (userName like ? and  dept_id is null ) or ( userName like ? and  dept_id <>? )

BaUserExample baUserExample = new BaUserExample();
 
 
Criteria criteria1 = baUserExample.createCriteria();
 
criteria1.andUserNameLike("%name%");
 
criteria1.andDeptIdIsNull();
 
 
Criteria criteria2 = baUserExample.createCriteria();
 
criteria2.andUserNameLike("%name%");
 
criteria2.andDeptIdNotEqualTo("1");
 
 
baUserExample.or(criteria2);
 
userMapper.countByExample(baUserExample);
select count(*) from ba_user WHERE 
( user_name like ? and dept_id is null ) or( user_name like ? and dept_id <> ? ) 

封装包使用

Example example = new Example(AfwFlowDtl.class);
 
 
for(int i=0;i < 10;i++) {
 
example.createCriteria().andEqualTo("roleCode",bean.getRoleCode)
 
.andNotIn("status",Arrays.asList("0","1"))
 
.andCondition("(FLAG <> '0' OR FLAG IS NULL)")
 
.andCondition("(role_nodecode is null or role_nodecode ='"+fean.getNextRoleNodeCode+"')");
 
example.selectProperties("serialNo", "roleCode", "employeeCode", "roleNodeCode");
 
example.setDistinct(true); // 去除重复,boolean型,true为选择不重复的记录。
 
example.orderBy("serialNo"); // 对应实体类中属性名
 
example.setOrderByClause("SERIAL_NO desc"); // 对应表结构字段名称
 
 
 
// 排序另外写法
 
example.orderBy("serialNo").asc().orderBy("employeeCode").asc();
 
 
List<AfwFlowDtl> afwFlowDtlList = afwFlowDtlMapper.selectList(example);
 
 
example.clear();// 把条件清空,可以循环使用,嵌套在for循环里面使用
 
}

这部分就是对criteria里面的参数进行判断,进而根据条件查询。

<sql id="Example_Where_Clause">
    <where>
      <foreach collection="oredCriteria" item="criteria" separator="or">
        <if test="criteria.valid">
          <trim prefix="(" prefixOverrides="and" suffix=")">
            <foreach collection="criteria.criteria" item="criterion">
              <choose>
                <when test="criterion.noValue">//没有值
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue">//单个值
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue">//区间值,范围查询
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue">//一组值
                  and ${criterion.condition}
                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>

如本文“对您有用”,欢迎随意打赏作者,让我们坚持创作!

0 打赏
Enamiĝu al vi
不要为明天忧虑.因为明天自有明天的忧虑.一天的难处一天当就够了。
543文章 68评论 297点赞 612885浏览

随机文章
SpringMVC—MultipartResolver 解析(文件上传)
5年前
PostgreSQL—自定义函数
12个月前
Spring Data Redis 使用(SSM版)
5年前
SpringCloud—LoadBalanced负载均衡
2年前
Java—并发编程(六)JUC锁 – (3)公平锁
4年前
博客统计
  • 日志总数:543 篇
  • 评论数目:68 条
  • 建站日期:2020-03-06
  • 运行天数:1955 天
  • 标签总数:23 个
  • 最后更新:2024-12-20
Copyright © 2025 网站备案号: 浙ICP备20017730号 身体没有灵魂是死的,信心没有行为也是死的。
主页
页面
  • 归档
  • 摘要
  • 杂图
  • 问题随笔
博主
Enamiĝu al vi
Enamiĝu al vi 管理员
To be, or not to be
543 文章 68 评论 612885 浏览
测试
测试
看板娘
赞赏作者

请通过微信、支付宝 APP 扫一扫

感谢您对作者的支持!

 支付宝 微信支付