【201806版本MyBatis-Plus尚—02】2.3版本,代码生成器。插件:分页,执行分析,性能分析,乐观锁。自定义全局操作:逻辑删除 ,公共字段填充,使用Oracle,MybatisX

1. 代码生成器

  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. 插件

  1. 插件机制: Mybatis 通过插件(Interceptor) 可以做到拦截四大对象相关方法的执行,根据需求, 完

成相关数据的动态改变。
Executor
StatementHandler:SQL语句,编译器对象。
ParameterHandler:SQL的参数对象
ResultSetHandler

  1. 插件原理 四大对象的每个对象在创建时,都会执行 interceptorChain.pluginAll(),
  • 而不是 直接返回对象。

  • 会经过每个插 件对象的 plugin()方法

    • 目的是为当前的四大对象创建代理。
    • 代理对象就可以拦截到四大对象相关方法的执行,
    • 因为要执行四大对象的方法需要经过代理

源码说明

  • StatementHandler
    • BaseStatementHandler
      • Callable StatementHandler
      • Prepared StatementHandler
      • Simple StatementHandler
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 执行分析插件

  1. com.baomidou.mybatisplus.plugins.SqlExplainInterceptor

  2. SQL 执行分析拦截器,只支持 MySQL5.6.3 以上版本

  3. 该插件的作用是分析 DELETE UPDATE 语句,防止小白或者恶意进行 DELETE UPDATE 全表操作

  4. 只建议在开发环境中使用,不建议在生产环境使用

  5. 在插件的底层 通过 SQL 语句分析命令:Explain 分析当前的 SQL 语句,根据结果集中的 Extra 列来断定当前是否全表操作。

性能分析

  1. com.baomidou.mybatisplus.plugins.PerformanceInterceptor

  2. 性能分析拦截器,用于输出每条 SQL 语句及其执行时间

  3. SQL 性能执行分析,开发环境使用, 超过指定时间,停止运行。有助于发现问题

		Employee employee = new Employee();
		employee.setLastName("玛亚老师");
		employee.setEmail("mly@sina.com");
		employee.setGender("0");
		employee.setAge(22);
		
		employeeMapper.insert(employee);
 Time118 ms - ID:com.atguigu.mp.mapper.EmployeeMapper.insert
 Execute SQLINSERT 
    INTO
        tbl_employee
        ( last_name, email, gender, age ) 
    VALUES
        ( '玛亚老师', 'mly@sina.com', '0', 22 )]

乐观锁插件

  1. com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor

  2. 如果想实现如下需求: 当要更新一条记录的时候,希望这条记录没有被别人更新

  3. 乐观锁的实现原理:

  • 取出记录时,获取当前 version 2
  • 更新时,带上这个 version 2
  • 执行更新时, set version = yourVersion+1 where version = yourVersion
  • 如果 version 不对,就更新失败
  1. @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);
 Time87 ms - ID:com.atguigu.mp.mapper.EmployeeMapper.updateById
 Execute SQLUPDATE
        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

  1. 在 Mapper 接口中定义相关的 CRUD 方法

  2. 扩展 AutoSqlInjector inject 方法,实现 Mapper 接口中方法要注入的 SQL

  3. 在 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

  1. com.baomidou.mybatisplus.mapper.LogicSqlInjector

  2. logicDeleteValue 逻辑删除全局值

  3. logicNotDeleteValue 逻辑未删除全局值

  4. 在 POJO 的逻辑删除字段 添加 @TableLogic 注解

  5. 会在 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);
 Time91 ms - ID:com.atguigu.mp.mapper.UserMapper.deleteById
 Execute SQLUPDATE
        tbl_user 
    SET
        logic_flag=-1 
    WHERE
        id=1]
        
 Time150 ms - ID:com.atguigu.mp.mapper.UserMapper.selectById
 Execute SQLSELECT
        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.

  1. 注解填充字段 @TableFile(fill = FieldFill.INSERT) 查看 FieldFill
  2. 自定义公共字段填充处理器
  3. 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);
 Time167 ms - ID:com.atguigu.mp.mapper.UserMapper.insert
 Execute SQLINSERT 
    INTO
        tbl_user
        ( `name`, logic_flag ) 
    VALUES
        ( 'weiyunhui', 1 )]
        
 Time84 ms - ID:com.atguigu.mp.mapper.UserMapper.updateById
 Execute SQLUPDATE
        tbl_user 
    SET
        `name`='weiyh',
        logic_flag=1 
    WHERE
        id=1]

4. 使用oracle

MySQL: 支持主键自增。 IdType.Auto
Oracle: 序列(Sequence)

  1. 实体类配置主键 Sequence @KeySequence(value=”序列名”, clazz=xxx.class 主键属性类
    型)
  2. 全局 MP 主键生成策略为 IdType.INPUT
  3. 全局 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);

序列提取父类

  1. 可以将@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 安

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis-plusMyBatis增强工具包,用于简化CRUD操作。该工具包为MyBatis提供了一些高效,有用,即用的功能,使用它可以有效地节省您的开发时间。Mybatis-plus特征与MyBatis完全兼容 启动时自动配置 开箱即用的用于操作数据库的界面 强大而灵活的条件包装器 生成主键的多种策略 Lambda样式的API 全能和高度可定制的代码生成器 自动分页操作 SQL注入防御 支持活动记录 支持可插拔的自定义界面 内置许多有用的扩展Mybatis-plus功能1、单表CURD(简单 + 批量)操作,自动完成(支持 like 比较等查询)。 2、分页插件,Count查询自动或自定义SQL查询。 3、Spring根据不同环境加载不同配置支持(支持typeAliasesPackage通配符扫描)。 【自动生成Entity Mapper Service文件】Mybatis-plusMybatis增强工具包) v3.3.2更新日志分页参数提取,单元测试用例修复 达梦数据库代码生成器表过滤支持 微软数据库代码生成器表过滤支持 修复代码生成器属性字段规则错误 SelectById 支持自定义方法名 修复分页插件获取数据库类型问题 Json转换器空值处理 bugfix(mybatis-plus-generator):SQL类型返回错误问题 调整未知方言异常,自动识别url转换小写匹配. fix: 初始化TableInfo中遇到多个字段有@TableId注解时未能抛出异常的问题 SuperController有Class参数的set方法 增加方法StrategyConfig.setSuperServiceImplClass(java.lang.Class<?>). 代码生成器命名策略调整. 扩展分页缓存key值计算. 去除方法推测,直接访问属性字段. 修正枚举处理器类型不匹配比较. 修改表前缀匹配方式 修改在Mybatis全局配置文件中设置分页插件参数不生效问题 修改在Mybatis全局配置文件中设置分页插件参数不生效问 修复PR未指定解析器的时候引发空指针 增加分页插件limit参数配置 修复指定superEntityClass重复生成父类字段问题 无主键的情况无需导入IdType与TableId包 调整生成BaseResultMap格式 支持lombok模式下选择是否进行链式set生成 修复解析器for update错误 过滤PG约束列(只留下主键约束) 增加生成器禁用模板生成 fix(kotlin): 修复动态表名BUG,最大努力替换表名 修复PG约束生成重复属性字段问题 fix(kotlin): 将LambdaUtils中缓存的key改为String 代码生成器增加数据库关键字处理接口 fix github/issues/2454 支持注解可继承 新增 AES 加密数据库用户名密码 优化方法入参泛型,支持更多类型 修复代码生成器开启移除is前缀生成实体缺少包导入 fixed github issues/2470Mybatis-plus截图

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值