使用mybatis plus时分页
可以直接使用生成的mapper或者service封装好的分页方法
userService.selectPage(new Page<>(6,5),null).getRecords().stream().forEach(System.out::println);
但是这种方法只是物理上的分页,实际查询时会把所有记录全部查询出来,然后在内存中分页,效率不高。
一般我们使用mybatis plus 自带的分页插件实现分页功能。
首先,在spring配置文件中配置分页插件。
配置在sqlSessionFactory的bean标签下
<!-- 插件注册 -->
<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>
在plugins属性设置里,查看源码可以看到是使用数组设值。
public void setPlugins(org.apache.ibatis.plugin.Interceptor[] plugins) { /* compiled code */ }
因此我们用list标签配置各种插件。
配置完成后,我们这样就能实现分页:
UserService userService=ioc.getBean(UserService.class);
Page<User> page = new Page<>(3,5);
Page<User> emps =
userService.selectPage(page, null);
System.out.println(emps);
System.out.println("===============获取分页相关的一些信息======================");
System.out.println("总条数:" +page.getTotal());
System.out.println(page.getRecords());
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.getRecords());
我们可以通过page对象获得我们需要的各种值。
主要用来对数据库操作进行分析,若是全表删除或者更新操作,会导致操作失败。
和sql语句中的Explain关键字有关。
可以对数据库操作进行分析,例如指定限制时间,若是对数据库的操作超时等,返回操作失败的结果。
上面有配置,在表对应的javabean类里,新添字段,然后在字段上加上@Version注解。
表中也新增该字段,然后在每次对数据库进行操作的时候,会判断你操作中的version值是否和数据库中的一致,如果此时有其他人对表中你将操作的字段进行了更改,version会自增,你的version值和表中不一致会导致操作失败。
<!-- 定义MybatisPlus的全局策略配置-->
<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!-- 在2.3版本以后,dbColumnUnderline 默认值就是true -->
<property name="dbColumnUnderline" value="true"></property>
<!-- Mysql 全局的主键策略 -->
<!-- <property name="idType" value="0"></property> --> <!-- Oracle全局主键策略 -->
<property name="idType" value="1"></property>
<!-- 全局的表前缀策略配置 -->
<property name="tablePrefix" value="tbl_"></property>
<!--注入自定义全局操作
<property name="sqlInjector" ref="mySqlInjector"></property>
--> <!-- 注入逻辑删除 --> <property name="sqlInjector" ref="logicSqlInjector"></property>
<!-- 注入逻辑删除全局值 -->
<property name="logicDeleteValue" value = "-1"></property>
<property name="logicNotDeleteValue" value="1"></property>
<!-- 注入公共字段填充处理器 -->
<property name="metaObjectHandler" ref="myMetaObjectHandler"></property>
<!-- 注入Oracle主键Sequence -->
<property name="keyGenerator" ref="oracleKeyGenerator"></property>
</bean>
<!-- 定义自定义注入器 -->
<bean id="mySqlInjector" class="com.atguigu.mp.injector.MySqlInjector"></bean>
<!-- 逻辑删除 -->
<bean id="logicSqlInjector" class="com.baomidou.mybatisplus.mapper.LogicSqlInjector"></bean>
<!-- 公共字段填充 处理器 -->
<bean id="myMetaObjectHandler" class="com.atguigu.mp.metaObjectHandler.MyMetaObjectHandler"> </bean>
<!-- 配置Oracle主键Sequence -->
<bean id="oracleKeyGenerator" class="com.baomidou.mybatisplus.incrementer.OracleKeyGenerator"></bean>
同样,配置完后,给表和对应的javabean新增一个字段,然后用上注解
这样表中每个数据被删除时并不会真正从表中移除,而是将该数据的logicFlag字段更改为-1,然后其他操作不能对该行数据进行影响。
当想自定义一个新方法的时候又不想写对应的xml文件,可以通过该方法,配置完后,在Mapper内新建一个方法
public interface EmployeeMapper extends BaseMapper<Employee> {
int deleteAll();
}
然后新建类MySqlInjector
/**
* 自定义全局操作 */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);
}
}
如上配置之后
在需要自动填充的字段上添加注解
这样当插入和更新操作时,会进入已注册的填充类中的方法检查
MyMetaObjectHandler:
/**
* 自定义公共字段填充处理器 */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) {
Object fieldValue = getFieldValByName("name", metaObject);
if(fieldValue == null) {
System.out.println("*******修改操作 满足填充条件*********");
setFieldValByName("name", "weiyh", metaObject);
}
}
}
当满足if语句中的条件的时候,会自动为下面设置的字段填充上设置的值。
学习oracle后明白,oracle里没有mysql一样的Auto_increment字段。
一般我们使用序列Sequence来实现同样的功能
如上配置后(记得设置主键策略为IdType.INPUT)
在oracle里新建序列,然后在需要使用的javabean类上注解
value值为你的序列名。
另外,我们还可以使用多个类继承一个父类,然后在父类上添加该注解,实现多个类共用一个序列。
另外,mybatis plus还有很多功能,如AR(Active Record),让javabean类继承Model类,然后自身可以调用对应的数据库操作方法
如
User user=new User();
user.setId(1);
user.setName(“哈哈”);
user.updateById();
还有什么动态切换数据源之类的功能…
具体上官网