MyBatis 使用笔记
关于@Param() 注解
- 基本类型的参数或者String类型,需要加上
- 引用类型不需要加
- 如果只有一个基本类型的话,可以忽略,但是建议大家都加上!
- 我们在SQL中引用的就是我们这里的 @Param() 中设定的属性名!
#{} ${} 区别
注解中 #{} 传参 ${} 替换
多对一 (联合)association
<select id="getStudent" resultMap="StudentTeacher">
select * from student
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂的属性,我们需要单独处理 对象: association 集合: collection -->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{id}
</select>
一对多(集合)collection
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from mybatis.teacher where id = #{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from mybatis.student where tid = #{tid}
</select>
javaType & ofType
- JavaType 用来指定实体类中属性的类型
- ofType 用来指定映射到List或者集合中的 pojo类型,泛型中的约束类型!
一级缓存和二级缓存
-
MyBatis系统中默认定义了两级缓存:
-
一级缓存(SqlSession级别的缓存,也称为本地缓存,默认开启)
-
二级缓存 (需要手动开启和配置,他是基于namespace级别的缓存)
- 只要开启了二级缓存,在同一个Mapper下就有效
- 所有的数据都会先放在一级缓存中;
- 只有当会话提交,或者关闭的时候,才会提交到二级缓存中!
-
为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
三种缓存策略
- FIFO,first in first out,先进先出
- LFU, Less Frequently Used,一直以来最少被使用的
- LRU,Least Recently Used,最近最少使用的
-
MyBatis-plus学习笔记(MP)
主键策略
//以下3种类型、只有当插入对象ID 为空,才自动填充。
ID_WORKER(3),//全局唯一ID (idWorker)
UUID(4),//全局唯一ID (UUID)
ID_WORKER_STR(5);//字符串全局唯一ID (idWorker 的字符串表示)
//以下3种类型、只有当插入对象ID 为空,才自动填充。
ID_WORKER(3),//全局唯一ID (idWorker)
UUID(4),//全局唯一ID (UUID)
ID_WORKER_STR(5);//字符串全局唯一ID (idWorker 的字符串表示)
自动更新(时间gmt_create .gmt_modified)
1、实体添加自动更新字段添加注解 (数据库操作省略)
//记住用util包下的Date!!
//字段添加填充内容
@TableField(fill = FieldFill.INSERT) //插入时更新
private Data creatTime;
@TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新是时更新
private Data updateTime;
2、编写处理器处理注解
@Slf4j
@Component //把处理器加到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
//插入时的填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("Start insert fill.... ");
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
//更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("Start update fill.... ");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
逻辑删除
1、实体添加字段和注解(数据库操作省略)
//逻辑删除
@TableLogic
private Integer deleted;
2、*注册逻辑删除 (MP3.1.1开始不需要注册)
//注册逻辑删除
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}
3、配置逻辑删除value (注解中未添加属性则需要全局配置)
# 配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
乐观锁
1、实体添加version字段(数据库操作省略)
@Version //整数类型下会自动+1
@TableField(fill = FieldFill.INSERT) *//用于自动填充,可省略*
private Integer version;
2、元对象处理器接口添加version的insert默认值(用于自动填充,可省略)
@Override
public void insertFill(MetaObject metaObject) {
......
this.setFieldValByName("version", 1, metaObject);
}
3、注册Bean
@EnableTransactionManagement
@Configuration
@MapperScan("cn.jift.mybatis_plus.mapper")
public class MybatisPlusConfig {
// 乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
4、测试修改成功与失败
@Test
public void testOptimisticLocker() {
//查询
User user = userMapper.selectById(1L);
//修改数据
user.setName("Helen Yao");
user.setEmail("helen@qq.com");
//执行更新
userMapper.updateById(user);
}
@Test
public void testOptimisticLockerFail() {
//查询
User user = userMapper.selectById(1L);
//修改数据
user.setName("Helen Yao1");
user.setEmail("helen@qq.com1");
//模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了version
user.setVersion(user.getVersion() - 1);
//执行更新
userMapper.updateById(user);
}
性能分析插件
@Bean
@Profile({"dev","test"}) //设置dev 和 test环境开启
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(1); //查询时间查过会报错
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
代码生成器
import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
// 代码自动生成器
public class KuangCode {
public static void main(String[] args) {
// 需要构建一个 代码自动生成器 对象
AutoGenerator mpg = new AutoGenerator();
// 配置策略
// 1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath+"/src/main/java");
gc.setAuthor("狂神说"); gc.setOpen(false);
gc.setFileOverride(false);
// 是否覆盖
gc.setServiceName("%sService");
// 去Service的I前缀
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/kuang_community? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
dsc.setDbType(DbType.MYSQL); mpg.setDataSource(dsc);
//3、包的配置
PackageConfig pc = new PackageConfig();
//只需要改实体类名字 和包名 还有 数据库配置即可
pc.setModuleName("blog"); pc.setParent("com.kuang");
pc.setEntity("entity"); pc.setMapper("mapper");
pc.setService("service"); pc.setController("controller");
mpg.setPackageInfo(pc);
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("blog_tags","course","links","sys_settings","user_record"," user_say");// 设置要映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
// 自动lombok;
strategy.setLogicDeleteFieldName("deleted");
// 自动填充配置
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate); tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
// 乐观锁
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
// localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.execute(); //执行
}
}