1. 代码生成器
- MP 提供了大量的自定义设置,生成的代码完全能够满足各类型的需求
- MP 的代码生成器都是基于 java 代码来生成。
- MBG 基于 xml 文件进行代码生成
MyBatis 的代码生成器可生成: 实体类、 Mapper 接口、 Mapper 映射文件
MP 的代码生成器可生成: 实体类(可以选择是否支持 AR)、 Mapper 接口、 Mapper 映射
文件、 Service 层、 Controller 层.
表结构:采用下滑线也是没问题的,只需要在生成代码时配置 dbColumnUnderline 属性就可以
引入依赖
MP 的代码生成器默认使用的是 Apache 的 Velocity 模板,当然也可以更换为别的模板技术,例如 freemarker。
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
步骤生成
@Test
public void testGenerator() {
//1. 全局配置
GlobalConfig config = new GlobalConfig();
config.setActiveRecord(true) // 是否支持AR模式
.setAuthor("weiyunhui") // 作者
.setOutputDir("D:\\workspace_mp\\mp03\\src\\main\\java") // 生成路径
.setFileOverride(true) // 文件覆盖
.setIdType(IdType.AUTO) // 主键策略
.setServiceName("%sService") // 设置生成的service接口的名字的首字母是否为I
// IEmployeeService
.setBaseResultMap(true)
.setBaseColumnList(true);
//2. 数据源配置
DataSourceConfig dsConfig = new DataSourceConfig();
dsConfig.setDbType(DbType.MYSQL) // 设置数据库类型
.setDriverName("com.mysql.jdbc.Driver")
.setUrl("jdbc:mysql://localhost:3306/mp")
.setUsername("root")
.setPassword("1234");
//3. 策略配置
StrategyConfig stConfig = new StrategyConfig();
stConfig.setCapitalMode(true) //全局大写命名
.setDbColumnUnderline(true) // 指定表名 字段名是否使用下划线
.setNaming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略
.setTablePrefix("tbl_")
.setInclude("tbl_employee"); // 生成的表
//4. 包名策略配置
PackageConfig pkConfig = new PackageConfig();
pkConfig.setParent("com.atguigu.mp")
.setMapper("mapper")
.setService("service")
.setController("controller")
.setEntity("beans")
.setXml("mapper");
//5. 整合配置
AutoGenerator ag = new AutoGenerator();
ag.setGlobalConfig(config)
.setDataSource(dsConfig)
.setStrategy(stConfig)
.setPackageInfo(pkConfig);
//6. 执行
ag.execute();
}
capital
n.
资本,资金;资本家,资方;首都,首府,省会;活动(或生产)中心;大写字母;柱顶,柱头
adj.
可处死刑的;大写的;首府的,省会的;<旧>顶好的,极好的
camel
n.
骆驼;驼绒织品;驼色,浅黄褐色;打捞浮筒
adj.
驼色的,暗棕色的
加入 webMvc
- 为了生成的 controller 不报错
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
beans
@TableName("tbl_employee")
public class Employee extends Model<Employee> {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
}
controller
@Controller
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
//employeeService.select
}
mapper
public interface EmployeeMapper extends BaseMapper<Employee> {
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mp.mapper.EmployeeMapper">
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/> //这里会报错,要注释
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.atguigu.mp.beans.Employee">
<id column="id" property="id" />
<result column="last_name" property="lastName" />
<result column="email" property="email" />
<result column="gender" property="gender" />
<result column="age" property="age" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, last_name, email, gender, age
</sql>
</mapper>
service
public interface EmployeeService extends IService<Employee> {
}
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
//不用再进行mapper的注入.
/**
* EmployeeServiceImpl 继承了ServiceImpl
* 1. 在ServiceImpl中已经完成baseMapper对象的注入
* 2. 在ServiceImpl中也帮我们提供了常用的CRUD方法
*/
}
2. 插件
- 插件机制: Mybatis 通过插件(Interceptor) 可以做到拦截四大对象相关方法的执行,根据需求, 完
成相关数据的动态改变。
Executor
StatementHandler:SQL语句,编译器对象。
ParameterHandler:SQL的参数对象
ResultSetHandler
- 插件原理 四大对象的每个对象在创建时,都会执行 interceptorChain.pluginAll(),
-
而不是 直接返回对象。
-
会经过每个插 件对象的 plugin()方法,
- 目的是为当前的四大对象创建代理。
- 代理对象就可以拦截到四大对象相关方法的执行,
- 因为要执行四大对象的方法需要经过代理
源码说明
- StatementHandler
- BaseStatementHandler
- Callable StatementHandler
- Prepared StatementHandler
- Simple StatementHandler
- BaseStatementHandler
public interface StatementHandler {
}
public abstract class BaseStatementHandler implements StatementHandler {
...
this.parameterHandler = this.configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
this.resultSetHandler = this.configuration.newResultSetHandler(executor, mappedStatement, rowBounds, this.parameterHandler, resultHandler, boundSql);
}
}
public class Configuration {
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
//拦截器 执行链 对象
parameterHandler = (ParameterHandler)this.interceptorChain.pluginAll(parameterHandler);
return parameterHandler;
}
}
public class InterceptorChain {
private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
public Object pluginAll(Object target) {
//拿到所有的插件,迭代
for (Interceptor interceptor : interceptors) {
//执行
target = interceptor.plugin(target);
}
//返回 代理对象
return target;
}
public void addInterceptor(Interceptor interceptor) {
interceptors.add(interceptor);
}
public List<Interceptor> getInterceptors() {
return Collections.unmodifiableList(interceptors);
}
}
public interface Interceptor {
//最终执行此方法,插件 的逻辑 也在此方法
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
}
分页插件
com.baomidou.mybatisplus.plugins
//对其签名,拦截 哪个对象
@Intercepts({@Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class}
)})
public class PaginationInterceptor extends SqlParserHandler implements Interceptor {
public Object plugin(Object target) {
//四大对象传进来,返回代理对象。
return target instanceof StatementHandler ?
Plugin.wrap(target, this) : target;
}
}
public class Plugin implements InvocationHandler {
public static Object wrap(Object target, Interceptor interceptor) {
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
Class<?> type = target.getClass();
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
if (interfaces.length > 0) {
return Proxy.newProxyInstance(
type.getClassLoader(),
interfaces,
new Plugin(target, interceptor, signatureMap)); //当前类,继承了Handler,刚好
}
return target;
}
}
使用
方法1:mybatis-config.xml
<configuration>
<!-- <plugins>
<plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></plugin>
</plugins> -->
</configuration>
插件新增
方法2:applicationContext.xml
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 插件注册 -->
<property name="plugins">
<list>
<!-- 注册分页插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
<!-- 注册执行分析插件 -->
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
<property name="stopProceed" value="true"></property>
</bean>
<!-- 注册性能分析插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
<property name="format" value="true"></property>
<!-- <property name="maxTime" value="5"></property> --> 毫秒
</bean>
<!-- 注册乐观锁插件 -->
<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor">
</bean>
</list>
</property>
</bean>
Perform
v.
演出,表演;执行,履行(尤指复杂的任务或行动);运行,表现;起…...作用,有…...功能
performance
n.
表演,演出;工作情况,表现;(投资的)业绩;执行,履行;麻烦,苦差事(a performance);艺术上的表现,演技;(汽车的)性能;(语言学)语言表现,言语行为
adj.
性能卓越的,高性能的
测试
Page<Employee> page = new Page<>(1,1);
List<Employee > emps =
employeeMapper.selectPage(page, null);
System.out.println(emps);
System.out.println("=====获取分页相关的一些信息=====");
System.out.println("总条数:" +page.getTotal());
System.out.println("当前页码: "+ page.getCurrent());
System.out.println("总页码:" + page.getPages());
System.out.println("每页显示的条数:" + page.getSize());
System.out.println("是否有上一页: " + page.hasPrevious());
System.out.println("是否有下一页: " + page.hasNext());
//将查询的结果封装到page对象中
page.setRecords(emps);
ELECT id AS id,last_name AS lastName,email,gender,age FROM tbl_employee LIMIT 0,1
执行分析
-
SqlExplainInterceptor
-
如果为 全表操作,则停止,如上配置
employeeMapper.delete(null); // 全表删除
explain delete from tbl_employee;
//得到 Extra列为:Deleting all rows,如果查询不到,说明版本太低了
//如果使用了 条件为:Using where
PreparedStatement stmt = connection.prepareStatement(sqlExplain);
Throwable var13 = null;
handler.setParameters(stmt);
ResultSet rs = stmt.executeQuery();
Throwable var15 = null;
while(rs.next()) {
if (!"Using where".equals(rs.getString("Extra"))) {
if (this.isStopProceed()) {
throw new MybatisPlusException("Error: Full table operation is prohibited. SQL: " + boundSql.getSql());
}
break;
}
}
7.3 执行分析插件
-
com.baomidou.mybatisplus.plugins.SqlExplainInterceptor
-
SQL 执行分析拦截器,只支持 MySQL5.6.3 以上版本
-
该插件的作用是分析 DELETE UPDATE 语句,防止小白或者恶意进行 DELETE UPDATE 全表操作
-
只建议在开发环境中使用,不建议在生产环境使用
-
在插件的底层 通过 SQL 语句分析命令:Explain 分析当前的 SQL 语句,根据结果集中的 Extra 列来断定当前是否全表操作。
性能分析
-
com.baomidou.mybatisplus.plugins.PerformanceInterceptor
-
性能分析拦截器,用于输出每条 SQL 语句及其执行时间
-
SQL 性能执行分析,开发环境使用, 超过指定时间,停止运行。有助于发现问题
Employee employee = new Employee();
employee.setLastName("玛亚老师");
employee.setEmail("mly@sina.com");
employee.setGender("0");
employee.setAge(22);
employeeMapper.insert(employee);
Time:118 ms - ID:com.atguigu.mp.mapper.EmployeeMapper.insert
Execute SQL:
INSERT
INTO
tbl_employee
( last_name, email, gender, age )
VALUES
( '玛亚老师', 'mly@sina.com', '0', 22 )]
乐观锁插件
-
com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor
-
如果想实现如下需求: 当要更新一条记录的时候,希望这条记录没有被别人更新
-
乐观锁的实现原理:
- 取出记录时,获取当前 version 2
- 更新时,带上这个 version 2
- 执行更新时, set version = yourVersion+1 where version = yourVersion
- 如果 version 不对,就更新失败
- @Version 用于注解实体字段,必须要有。
@Version
private Integer version ;
//更新操作
Employee employee = new Employee();
employee.setId(1);
employee.setLastName("TomAA");
employee.setEmail("tomAA@sina.com");
employee.setGender("1");
employee.setAge(22);
employee.setVersion(1);//当前库里的 必须为1,才更新,更新后为2
employeeMapper.updateById(employee);
Time:87 ms - ID:com.atguigu.mp.mapper.EmployeeMapper.updateById
Execute SQL:
UPDATE
tbl_employee
SET
last_name='TomAA',
email='tomAA@sina.com',
gender='1',
age=22,
version=2 //结果更新为2
WHERE
id=1
and version=1] //条件增加上1
3. 自定义全局操作
根据 MybatisPlus 的 AutoSqlInjector 可以自定义各种你想要的 sql ,注入到全局中,相当于自
定义 Mybatisplus 自动注入的方法。
之前需要在 xml 中进行配置的 SQL 语句,现在通过扩展 AutoSqlInjector 在加载 mybatis 环境
时就注入。
不写xml实现删除
AutoSqlInjector
-
在 Mapper 接口中定义相关的 CRUD 方法
-
扩展 AutoSqlInjector inject 方法,实现 Mapper 接口中方法要注入的 SQL
-
在 MP 全局策略中,配置 自定义注入器
Mapper 和 类配置
public interface EmployeeMapper extends BaseMapper<Employee> {
int deleteAll();
}
<!-- 定义MybatisPlus的全局策略配置-->
<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
注入自定义全局操作
<property name="sqlInjector" ref="mySqlInjector"></property>
</bean>
<!-- 定义自定义注入器 -->
<bean id="mySqlInjector" class="com.atguigu.mp.injector.MySqlInjector"></bean>
注入器
/**
* 自定义全局操作
*/
public class MySqlInjector extends AutoSqlInjector{
/**
* 扩展inject 方法,完成自定义全局操作
*/
@Override
public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass,
Class<?> modelClass, TableInfo table) {
//将EmployeeMapper中定义的deleteAll, 处理成对应的MappedStatement对象,加入到configuration对象中。
//注入的SQL语句
String sql = "delete from " +table.getTableName();
//注入的方法名 一定要与EmployeeMapper接口中的方法名一致
String method = "deleteAll" ;
//构造SqlSource对象
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
//构造一个删除的MappedStatement
this.addDeleteMappedStatement(mapperClass, method, sqlSource);
}
}
逻辑删除
假删除、逻辑删除: 并不会真正的从数据库中将数据删除掉,而是将当前被删除的这条数据中的一个逻辑删除字段置为删除状态.
tbl_user logic_flag = 1 → -1
-
com.baomidou.mybatisplus.mapper.LogicSqlInjector
-
logicDeleteValue 逻辑删除全局值
-
logicNotDeleteValue 逻辑未删除全局值
-
在 POJO 的逻辑删除字段 添加 @TableLogic 注解
-
会在 mp 自带查询和更新方法的 sql 后面,追加『逻辑删除字段』 =『LogicNotDeleteValue
默认值』 删除方法: deleteById()和其他 delete 方法, 底层 SQL 调用的是 update tbl_xxx
set 『逻辑删除字段』 =『logicDeleteValue 默认值』
配置
CREATE TABLE `tbl_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`logic_flag` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;
globalConfiguration
<!-- 注入逻辑删除 --> //上面自定义的删除
<property name="sqlInjector" ref="logicSqlInjector"></property>
<!-- 注入逻辑删除全局值 -->
<property name="logicDeleteValue" value = "-1"></property>
<property name="logicNotDeleteValue" value="1"></property>
<!-- 逻辑删除 -->
<bean id="logicSqlInjector" class="com.baomidou.mybatisplus.mapper.LogicSqlInjector"></bean>
代码
//@KeySequence(value="seq_user",clazz=Integer.class)
public class User extends Parent {
//@TableId(type=IdType.INPUT)
private Integer id ;
@TableField(fill=FieldFill.INSERT_UPDATE)
private String name ;
@TableLogic // 逻辑删除属性
private Integer logicFlag ;
}
public interface UserMapper extends BaseMapper<User>{
}
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = ctx.getBean("userMapper",UserMapper.class);
Integer result = userMapper.deleteById(1);
System.out.println("result:" +result );
//查询的时候,查询不到
User user = userMapper.selectById(1);
System.out.println(user);
Time:91 ms - ID:com.atguigu.mp.mapper.UserMapper.deleteById
Execute SQL:
UPDATE
tbl_user
SET
logic_flag=-1
WHERE
id=1]
Time:150 ms - ID:com.atguigu.mp.mapper.UserMapper.selectById
Execute SQL:
SELECT
id,
`name`,
logic_flag AS logicFlag
FROM
tbl_user
WHERE
id=1
AND logic_flag=1]
源码
public class LogicSqlInjector extends AutoSqlInjector {
public LogicSqlInjector() {
}
protected void injectDeleteByIdSql(boolean batch, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
if (table.isLogicDelete()) {
SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE_BY_ID;
String idStr = table.getKeyProperty();
if (batch) {
sqlMethod = SqlMethod.LOGIC_DELETE_BATCH_BY_IDS;
StringBuilder ids = new StringBuilder();
ids.append("\n<foreach item=\"item\" index=\"index\" collection=\"coll\" separator=\",\">");
ids.append("#{item}");
ids.append("\n</foreach>");
idStr = ids.toString();
}
String sql = String.format(sqlMethod.getSql(), table.getTableName(), this.sqlLogicSet(table), table.getKeyColumn(), idStr);
SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
} else {
super.injectDeleteByIdSql(batch, mapperClass, modelClass, table);
}
}
}
/**
* 逻辑删除
*/
LOGIC_DELETE_BY_ID("deleteById", "根据ID 逻辑删除一条数据", "<script>UPDATE %s %s WHERE %s=#{%s}</script>"),
公共字段自动填充
元数据处理器接口
com.baomidou.mybatisplus.mapper.MetaObjectHandler
- insertFill(MetaObject metaObject)
- updateFill(MetaObject metaObject)
metaobject: 元对象. 是 Mybatis 提供的一个用于更加方便,更加优雅的访问对象的属性,
给对象的属性设置值 的一个对象. 还会用于包装对象. 支持对 Object 、 Map、 Collection
等对象进行包装
本质上 metaObject 获取对象的属性值或者是给对象的属性设置值,最终是要
通过 Reflector 获取到属性的对应方法的 Invoker, 最终 invoke.
- 注解填充字段 @TableFile(fill = FieldFill.INSERT) 查看 FieldFill
- 自定义公共字段填充处理器
- MP 全局注入 自定义公共字段填充处理器
@TableField(fill=FieldFill.INSERT_UPDATE)
private String name ;
public enum FieldFill {
DEFAULT(0, "默认不处理"),
INSERT(1, "插入填充字段"),
UPDATE(2, "更新填充字段"),
INSERT_UPDATE(3, "插入和更新填充字段");
}
配置
<!-- globalConfiguration 注入公共字段填充处理器 -->
<property name="metaObjectHandler" ref="myMetaObjectHandler"></property>
<!-- 公共字段填充 处理器 -->
<bean id="myMetaObjectHandler" class="com.atguigu.mp.metaObjectHandler.MyMetaObjectHandler"> </bean>
处理器
/**
* 自定义公共字段填充处理器
*/
public class MyMetaObjectHandler extends MetaObjectHandler {
/**
* 插入操作 自动填充
*/
@Override
public void insertFill(MetaObject metaObject) {
//获取到需要被填充的字段的值
Object fieldValue = getFieldValByName("name", metaObject);
if(fieldValue == null) {
System.out.println("*******插入操作 满足填充条件*********");
setFieldValByName("name", "weiyunhui", metaObject);
}
}
/**
* 修改操作 自动填充
*/
@Override
public void updateFill(MetaObject metaObject) {
一样
}
}
测试
User user = new User();
user.setLogicFlag(1);
userMapper.insert(user);
User user = new User();
user.setId(1);
user.setLogicFlag(1);
userMapper.updateById(user);
Time:167 ms - ID:com.atguigu.mp.mapper.UserMapper.insert
Execute SQL:
INSERT
INTO
tbl_user
( `name`, logic_flag )
VALUES
( 'weiyunhui', 1 )]
Time:84 ms - ID:com.atguigu.mp.mapper.UserMapper.updateById
Execute SQL:
UPDATE
tbl_user
SET
`name`='weiyh',
logic_flag=1
WHERE
id=1]
4. 使用oracle
MySQL: 支持主键自增。 IdType.Auto
Oracle: 序列(Sequence)
- 实体类配置主键 Sequence @KeySequence(value=”序列名”, clazz=xxx.class 主键属性类
型) - 全局 MP 主键生成策略为 IdType.INPUT
- 全局 MP 中配置 Oracle 主键 Sequence
com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
配置文件
<!-- Oracle驱动: 因为Oracle授权的问题,不能从Maven的仓库中下载到Oracle驱动 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
</dependency>
orcl.driver=oracle.jdbc.OracleDriver
orcl.url=jdbc:oracle:thin:@localhost:1521:xe
orcl.username=system
orcl.password=1234
<!-- Oracle -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${orcl.driver}"></property>
<property name="jdbcUrl" value="${orcl.url}"></property>
<property name="user" value="${orcl.username}"></property>
<property name="password" value="${orcl.password}"></property>
</bean>
drop table tbl_user;
create table tbl_user(
id number(11) primary key,
name varchar2(50),
logic_flag number(11)
);
create sequence seq_user start with 100 increment by 2 ;
select seq_user.nextval from dual; //第一次查询为100,第二次查为102
select seq_user.currval from dual; //当前为102,每次查都是102
类改动
//@KeySequence(value="seq_user",clazz=Integer.class)
public class User extends Parent {
//@TableId(type=IdType.INPUT)
private Integer id ;
}
// 或者 IdType.INPUT,配置成 全局的
<!-- Oracle全局主键策略 -->
<property name="idType" value="1"></property>
<!-- 注入Oracle主键Sequence -->
<property name="keyGenerator" ref="oracleKeyGenerator"></property>
<!-- 配置Oracle主键Sequence -->
<bean id="oracleKeyGenerator" class="com.baomidou.mybatisplus.incrementer.OracleKeyGenerator"></bean>
User user = new User();
user.setLogicFlag(1);
userMapper.insert(user);
序列提取父类
- 可以将@keySequence 定义在父类中, 可实现多个子类对应的多个表公用一个 Sequence
@KeySequence(value="seq_user",clazz=Integer.class)
public abstract class Parent {
}
public class User extends Parent {
}
5. Idea 的 MybatisX
MybatisX 辅助 idea 快速开发插件,为效率而生.
可以实现 java 与 xml 跳转,根据 Mapper 接口中的方法自动生成 xml 结构.
官方安装: File -> Settings -> Plugins -> Browse Repositories… 输入 mybatisx 安装下载
Jar 安装: File -> Settings -> Plugins -> Install plugin from disk… 选中 mybatisx…jar 安