Mybatis集成Spring,pom.xml文件内容
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<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>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
</dependency>
Mybatis Plus的配置–applicationContext.xml
<context:property-placeholder location=“classpath:db.properties”/>
<!-- 事务管理器 -->
<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 基于注解的事务管理 -->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
<!-- 配置SqlSessionFactoryBean
Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
-->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 别名处理 -->
<property name="typeAliasesPackage" value="com.atguigu.mp.beans"></property>
<!-- 注入全局MP策略配置 -->
<property name="globalConfig" ref="globalConfiguration"></property>
<!-- 插件注册 -->
<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>
<!-- 定义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>
<!--
配置mybatis 扫描mapper接口的路径
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.atguigu.mp.mapper"></property>
</bean>
<!--
配置mybatis 扫描mapper接口的路径
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.atguigu.mp.mapper"></property>
</bean>
@TableName 全局的配置
@TableField 全局的配置
@TableId
selectById(Serializable id)方法-通过ID查询
selectOne(entity) 通过多个列进行查询,将entity中设置有值的字段,当作条件进行查询
selectBatchIds(List<? extends Serializable> idList)方法
selectByMap(Map<Stirng,Object> columnMap);封装查询条件,注意封装到columnMap中的key为列名非属性名。
selectPage(RowBounds rowBouds,@Param(“ew”) Wrapper wrapper) 因为Page类集成Paginat,pagenite继承RowBounds对象,所以直接传Page对象给该方法即可,比如xxMapper.selectPage(new Page<>(2.2),null)表示第二行,查询两条数据,但是打印出的sql语句没有limit 语句,也就是mybatis plus 的这个方法还是用的是mybatis的Rowbounds的方法,实质上是内存分页不是真正的物理分页(在mybatis.cfg.xml中或者applicationContext.xml 中配置好PaginationInterceptor这个插件拦截器),mybatis有类似pageHelper插件,mybatis plus也有类似的
insert(entity)方法,会根据实体的每个属性进行非空判断,只有非空的才会出现在SQL语句中
insertAllColumn(entity)方法,不管属性是否有值,所对应的字段都会出现在SQL语句中
updateById(entity) 修改一个实体,这个方法entity中的某个属性如果没有set值的话,sql中不会打印出来
updateAllColumnById(entity)方法,不管entity中的属性有没有set值,都会在sql语句中打印出来,注意如果不想修改某些属性的值,则不用用该方法,因为该方法会将表中原有的值设置为NULL。
deleteById(Serilizable id)
deleteBymap(@Param(“cm”) Map<String,Object> columMap);
deleteBatchIds(List<? extends Serializable > idList)
原理分析: 根据xxMapper可以得到看到xxMapperProxy代理对象–>其中有sqlSession–>其中有sqlSessionFactory–>其中有Configuration–> MappedStatement
每一个mappedStatement都表示Mapper接口中的一个方法与Mapper映射文件中的一个SQL。mybatis plus在启动时候就会挨个分析xxMapper中的方法,并且将对应的sql语句处理好保存到configuration中
条件构造器 EntityWrapper***加粗样式***
En’ti’t’y’Wrapper和Condition类似来让程序员自动的构建查询条件
例如: employeeMapper.selectPage(new Page(1,2), new EntityWrapper().between(“age”,18,50).eq(“gender”,1),eq(“last_name”,“tom”));
带条件的查询
List selectlist(@Param(“ew”) Wrapper wrapper);
例如:employeeMapper.selectList(new EntityWrapper().eq(“gender”,0).orderBy(“age”).last(“desc”));
employeeMapper。selectPage(
new Page(1,2),Condition.create().between(“age”,18,50).eq(“gender”,“1”).eq(“last_name”,“Tom”));
带条件的修改
In’te’ge’r update(@Param(“et”) T entity,@param(“ew”) Wrapper wapper);
例如: employee’Mapper.update(employee,new EntityWrapper().eq(“last_name”,“Tom”).eq(“age”,44));
带条件的删除
Integer delete(@Param(“ew”) Wrapper wapper);
ActiveRecord(活动记录)
让实体类集成Model 这个类
例如 AR插入: Employee em = new Employee();
em.setLastName(“sls”);
em.setEmail("@atguigu");
em.setGender(1);
boolean result = employee.insert(); //自己插入自己
System.out.println(result) //
AR修改:Employee em = new Employee();
em.setLastName(“sls”);
em.setEmail("@atguigu");
em.setGender(1);
boolean result = employee.upateById();
System.out.println(“result:”+result); //返回true
代码生成器依赖
org.apache.velocity
velocity-engine-core
2.0
@Test
public void testGenerator() {
//1. 全局配置
GlobalConfig config = new GlobalConfig();
config.setActiveRecord(true) //是否支持AR模式
.setAuthor(“weiyunhui”) //作者
.setOutputDir(“D:\workspace_my\mp03\src\main\java”)
//生成路径
.setFileOverride(true)//文件覆盖
.setServiceName("%sService") //设置生成的service接口名
首字母是否为I
.setIdType(IdType.AUTO) //主键策略
.setBaseResultMap(true)
.setBaseColumnList(true);
;
//2. 数据源配置
DataSourceConfig dsConfig = new DataSourceConfig();
dsConfig.setDbType(DbType.MYSQL)
.setUrl(“jdbc:mysql://localhost:3306/javaEE_0228”)
.setDriverName(“com.mysql.jdbc.Driver”)
.setUsername(“root”)
.setPassword(“1234”);
//策略配置
StrategyConfig stConfig = new StrategyConfig();
stConfig.setCapitalMode(true) // 全局大写命名
.setDbColumnUnderline(true) //表名 字段名 是否使用下滑
线命名
.setNaming(NamingStrategy.underline_to_camel) // 数据
库表映射到实体的命名策略
.setInclude(“tbl_employee”) //生成的表
.setTablePrefix(“tbl_”); // 表前缀
//4.包名策略
PackageConfig pkConfig = new PackageConfig();
pkConfig.setParent(“com.atguigu.mp”)
.setController(“controller”)
.setEntity(“beans”)
.setService(“service”);
//5. 整合配置
AutoGenerator ag = new
AutoGenerator().setGlobalConfig(config)
.setDataSource(dsConfig)
.setStrategy(stConfig)
.setPackageInfo(pkConfig);
ag.execute();
}
分页插件: PaginationInterceptor
Page page = new Page<>(1,1);
List emps = employeeMapper.selectPage(page,null);
page.setRecords(emps); //将查询出来的employee放到page对象中
执行分析插件
SqlExplainInterceptor使用详情applicationContext.xml中的 SqlExplainInterceptor
该插件的作用是分析delete update语句放智小白或者而已进行delete update全表操作底层原理同事sql语句分析命令:eXplain分析当前的SQL语句,分局结果集中的Extra列来判定当前是否全表操作
性能分析插件 PerformanceInterceptor
性能分析拦截器,用于输出每条 SQL 语句及其执行时间,SQL 性能执行分析,开发环境使用, 超过指定时间,停止运行
乐观锁插件 OptimisticLockerInterceptor
@Version 用于注解实体字段,必须要有。
乐观锁的实现原理:
(比如更新一个实体,该实体中有setVersion(2))这个字段,如果在执行更新前,有个其他的进程将他更新了,此时它将会更新失败。因为version的值不同。
取出记录时,获取当前 version 2
更新时,带上这个 version 2
执行更新时, set version = yourVersion+1 where version = yourVersion
如果 version 不对,就更新失败
自定义全局插件
public class mySqlInjector extends AutoSqlInjector
{
@Override
public void inject(Configuration configuration,MapperBuilderAssistant builderAssistant ,Class<?> method,Class<?> modelClass,TableInfo table)
{
String sql = "delete from "+ table.getTableName();
String method = “deleteAll”;
SqlSource sqlSource = languageDriver.createSqlSource(configuration,sql,modelClass);
this.addDeleteMappedStatement(mapperClass,method,sqlSource);
}
}
全局SQL注入器
-
逻辑删除 @TableLogic 注解标注在需要逻辑删除的实体类的某个属性上
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);
}
} -
**公共字段自动填充 **
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 全局注入 自定义公共字段填充处理器
/**
-
自定义公共字段填充处理器
*/
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);
}
}
- 插入操作 自动填充
}