介绍:
javax.persistence.Id 是由 JPA 定义的 annotation,记住 JPA 仅适用于关系数据的管理。
什么是JPA?
全称Java Persistence API,可以通过注解或者XML描述【对象-关系表】之间的映射关系,并将实体对象持久化到数据库中。
了解更多:SpringBoot集成jpa 一篇就够了 超详细_springboot集成jpa切面-CSDN博客
使用位置:
@Id 标注用于声明一个实体类的属性映射为数据库的主键列。该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上。
@Id标注也可置于属性的getter方法之前。
了解更多:JPA @Id 和 @GeneratedValue 注解详解-CSDN博客
配套使用高级注解
MyBatis 3.x 版本提供了以下4个CRUD的高级注解
@SelectProvider:用于构建动态查询SQL。
@InsertProvider:用于构建动态新增SQL。
@UpdateProvider:用于构建动态更新SQL。
@DeleteProvider:用于构建动态删除SQL。
动态SQL注解主要用于编写动态SQL。这里以@SelectProvider为例,它主要包含两个注解属性,其中,type表示工具类,method表示工具类的某个方法(用于返回具体的SQL语句)。
springbooot启动时加载BaseMapperSqlSourceBuilder的build方法
try {
List<MappedStatement> toAddMappedStatements = new LinkedList<>();
Object statements = configuration.getMappedStatements();
for (Object obj : (Collection) statements) {
if (!(obj instanceof MappedStatement)) {
continue;
}
MappedStatement mappedStatement = (MappedStatement) obj;
if (mappedStatement.getSqlSource() instanceof ProviderSqlSource) {
Class<?> providerClass = getProviderClass(mappedStatement);
if (providerClass != BaseMapperSqlSourceBuilder.class) {
continue;
}
Class<?> mapperClass = getMapperClass(mappedStatement);
Class<?>[] generics = getMapperGenerics(mapperClass);
Class<?> modelClass = generics[0];
Class<?> primaryFieldClass = generics[1];
ResultMap resultMap = getResultMap(mappedStatement, modelClass, mapperClass);
String sqlScript = getSqlScript(mappedStatement, mapperClass, modelClass, providerClass, primaryFieldClass, resultMap);
SqlSource sqlSource = createSqlSource(mappedStatement, sqlScript);
setSqlSource(mappedStatement, sqlSource);
if (resultMap != null) {
toAddMappedStatements.add(newMappedStatement(mappedStatement, resultMap));
}
}
}
for (MappedStatement mappedStatement : toAddMappedStatements) {
replaceStatement(configuration, mappedStatement);
}
} catch (Exception e) {
logger.error("初始化base mapper失败!", e);
}
return "sql";
}
第一步拿到所有的mapper和xml里面的各个方法(如果是MappedStatement才循环)
第二步如果providerClass不等于BaseMapperSqlSourceBuilder也跳过循环
第三步获取到对应的mapper以及对应的model和primaryField,其实应该也就是对应到接口里面的K和T
第四步获取到一个ResultMap对象
ps:我也不知道ResultMap是撒,反正挺出名的我知道
第五步获取到了对应sql语句,初始化完成
各个小方法解析
getProviderClass方法
通过反射拿到ProviderSqlSource里面的providerTypeField字段,通过setAccessible为ture关闭安全检查,通过java.lang.reflect.Field的get()获取到字段也就是BaseMapperSqlSourceBuilder
了解更多:setAccessible(true)用法及意义-CSDN博客
Java Field get()用法及代码示例 - 纯净天空 (vimsky.com)
getMapperClass方法
通过反射Class.forName拿到mapper对象
getMapperGenerics方法
将mapper对象传入,再通过getGenericInterfaces获取该对象继承或者实现了哪些接口,getActualTypeArguments()返回表示此类型实际类型参数
总而言之就是获取那几个泛型
了解更多:Java Class getGenericInterfaces()用法及代码示例 - 纯净天空 (vimsky.com) Java之泛型ParameterizedType、getGenericSuperclass、getActualTypeArguments-CSDN博客
getResultMap
1.获取方法
2.获取返回值
3.获取泛型