* >>>>>> * hibernate: 【全自动化】 * (1) 全表映射 * (2) SQL 优化,自定义SQL * (3) 复杂SQL不容易实现 * (4) HQL 黑盒调优复杂 * (5) 性能相对mybatis 没有mybatis好 * 快速开发时可以考虑 * mybatis: 【半自动化】 * (1) 自定义SQL,灵活度高,几乎可以替换JDBC * (2) 底层SQL优化容易 * (3) 易于维护 * (4) 缺点: 工作量较大 * * mybtais : 面向接口编程 * (1) SQL语句 (2) POJO对象 (3) 映射关系 - 接口 * * >>>>>> * SqlSessionFactoryBuilder 读取配置信息创建SqlSessionFactory对象,建造者模式, * 方法级别的声明周期。将xml 的所有的mapper.xml扫描加入内存 * mybatis的核心配置。xml和 所有的xml文件加载 * * SqlSessionFactory 维护一个数据库的连接池, 程序的整个声明周期, 单例 * * SqlSession 工厂单例模式, 标识 一次数据库连接,方法级别 * * 动态代理生成一个Mapper的实现类。调用具体的方法 * * >>>>>> 动态代理加反射实现:{DDL 的 标签的 id必须和 方法名称相同,以及 mapper的java接口文件名称和xml名称定义成一样这样在反射的时候不需要作其他} * * (1)自动映射 resultType * (2)<ResultMap/> 属于手动映射,我们需要配置映射关系 * * 多参数: * (1) @Param 小于5的参数 * (2) 封装java bean parameterType = "xxxx.xx.Auto_clazz" 大于5个参数时使用 * (3) 放入map parameterType = "map" 可读性差,可维护性差 * * selectKey keyProperty="" order="before" * select Last_Insert_ID() * useGeneratedKeys * >>>>>>>>>>>> 批量插入时,在事务提交之后才能拿到 每条记录对应的主键id >>>>>>>>>>>> * * >>>>>> 注解定义 ResultMap * * @Select({ * select * from user where id = 1 limit 10 * }) * @Results(id = "Base_Result_Map", value = { * @Result(column = "", property = "", jdbcType = JdbcType.INTEGER), * @Result(column = "", property = "", jdbcType = JdbcType.VARCHAR), * @Result(column = "", property = "", jdbcType = JdbcType.VARCHAR) * }) * void selectByKey(); * * #{} 占位符 ? 拼接的时候会添加 单引号 \'\' * 例如:表名,order by , in 考虑使用 ${} 原样拼接 * * mybatis 执行器: * 分为三种: simple, reuse , batch 三种 reuse 预处理的执行器 batch 批处理执行器 * ExecutorType.SIMPLE:该执行器类型不做特殊的事情,为每个语句的执行创建一个新的预处理语句(PreparedStatement) * ExecutorType.REUSE:该执行器类型会复用预处理语句(PreparedStatement) * ExecutorType.BATCH:该执行器类型会批量执行所有的更新语句 * * configuration 包裹所有配置标签 整个配置文件的顶级标签 * properties 属性 该标签可以引入外部配置的属性,也可以自己配置。该配置标签所在的同一个配置文件的其他配置均可以引用此配置中的属性 * setting 全局配置参数 用来配置一些改变运行时行为的信息,例如是否使用缓存机制,是否使用延迟加载,是否使用错误处理机制等。 * typeAliases 类型别名 用来设置一些别名来代替 Java 的长类型声明(如 java.lang.int 变为 int),减少配置编码的冗余 * typeHandlers 类型处理器 将数据库获取的值以合适的方式转换为 Java 类型,或者将 Java类型的参数转换为数据库对应的类型 * objectFactory 对象工厂 实例化目标类的工厂类配置 * plugins 插件 可以通过插件修改 MyBatis 的核心行为,例如对语句执行的某一点进行拦截调用 * environments 环境集合属性对象 数据库环境信息的集合。在一个配置文件中,可以有多种数据库环境集合,这样可以使 MyBatis 将 SQL 同时映射至多个数据库 * environment 环境子属性对象 数据库环境配置的详细配置 * transactionManager 事务管理 指定 MyBatis 的事务管理器 * dataSource 数据源 使用其中的 type 指定数据源的连接类型,在标签对中可以使用 * property 属性指定数据库连接池的其他信息 * mappers 映射器 配置 SQL 映射文件的位置,告知 MyBatis 去哪里加载 SQL 映射文件 * * <<<<<<<<<<<<<<<<<<<< 批量操作时,在处理大数据量时需要注意,分批进行处理,数据量过大会导致栈溢出 >>>>>>>>>>>>>>>>>>> * update student set * sname = * case suid * when ? then ? * when ? then ? * when ? then ? end , * tel = * case tel * when ? then ? * when ? then ? * when ? then ? end * where suid in ( ? , ? , ? ) * * <<<<<<<<<<<<<<<<<<<< BatchExecutor 底层是对 JDBC ps.addBatch()的封装,原理是攒一批 SQL 以后再发送 <<<<<<<<<<<<<<<<<<<< * * 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false * <setting name="lazyLoadingEnabled" value="true"/> * * 当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过 select 标签的fetchType 来覆盖 * <setting name="aggressiveLazyLoading" value="false"/> * * Mybatis 创建具有延迟加载能力的对象所用到的代理工具,默认 JAVASSIST * <setting name="proxyFactory" value="CGLIB" /> * * >>>>>> MBG : 三种方式 * (1) java -jar mybatis-generator-core-1.3.5.jar -Dfile.encoding=UTF-8 -configfile generator.xml --override * (2) maven : mvn mybatis-generator:generate * <groupId>org.mybatis.generator</groupId> * <artifactId>mybatis-generator-maven-plugin</artifactId> * (3) java 类 * * >>>>>> 关联查询之 : * (1) 一对一 association * 1. 方式一: <association column="uid" javaType="com.UserInfo" > * <result column="name" property="name" jdbcType="VARCHAR" /> * </association> * 2. 方式二: <association property="job" javaType="com.JobInfo" fetchType="lazy" select="com.mapper.JobMapper.selectHisJob"/> * 会有 N+1 问题 user表一次 工作部门 N 次,解决方法就是 开启延迟加载 fetchType="lazy" eager: 及时加载 * lazy 按需加载,当使用的时候才会查询数据库查询数据 * (2) 一对多 collection 注意 ofType 属性指定具体 实体类 javaType 为 List * <collection property="departments" javaType="java.util.List" ofType="com.Department"> * <result column="name" property="name" jdbcType="VARCHAR" /> * </collection> * * 延迟加载 是通过代理的方式实现的 这里的 job 对象就是一个代理对象 * * discriminator 鉴别器 * * <resultMap id="Grade_Map" type="com.UserDeparts"> * <discriminator column="gradeId" javaType="int"> * <case value="10" resultMap="Grade10_Map"/> * <case value="11" resultMap="Grade11_Map"/> * </discriminator> * </resultMap> * * <resultMap id="Grade10_Map" extends="Grade_Map" type="com.UserDeparts"></resultMap> * <resultMap id="Grade11_Map" extends="Grade_Map" type="com.UserDeparts"></resultMap> * * 多对多: * 两个一对多,有中间表 * * >>>>>> 条件查询 * choose when 多条件查询 * if 但条件查询 * * >>>>>> Example criteria() 查询 仅适用于单表操作,而且与实体类是强耦合一旦字段发生变化需要重新生成实体类 * * >>>>>> typeHandler:自定义 类型转换器,实现 BaseTypeHandler<?> 重写期中的方法 * * >>>>>> 嵌套查询: * (1) 嵌套结果: 通过连表用一条SQL 将结果查出关联查询成为,嵌套结果 * (2) 嵌套查询: 多条SQL查询,N+1 ( 会用到 select 属性指定嵌套的 查询方法) * * >>>>>> mybatis 缓存Cache * 一级缓存 应用及缓存 * (1) 一级缓存 应用及缓存, 默认是开启的,想要关闭 在 select 标签的 flushCache="true" true不用一级缓存 * 属于SqlSession 会话一次请求级别,不能共享,mybatis 会根据方法 生成key 缓存到 Map 中 * mybatis的核心配置文件 中 <setting name="localCacheScope" value="statement|session"></setting> * * (2) <<<<<< 任何 Insert update delete 会清空一级缓存 >>>>>> * 二级缓存: 以命名空间 namespace 为声明周期的 * (1) xml 中 <cache><cache/> 开启 核心配置文件中;<setting name="cacheEnabled" value="true"></setting> * (2) setting 中配置 EnableCached 默认是 true 开启的 * (3) <<<<<< 不管什么缓存 任何的 Insert update delete 都会清空缓存 >>>>>> * (4) mybatis 会对 二级缓存进行命中率进行统计,只要 打印出 Cache Hit Ratio 就说明走的是 * (5) 二级缓存不建议使用,会造成脏读,可以使用 redis memcached * * >>>>>> * 逻辑翻页: RowBounds(start, size) 在内存中实现翻页,不适合数据量大的场景 * * >>>>> * * Executor 执行器 分为 三种 simple reuse batch * * >>>>>> 一级缓存 SqlSession * --------------------------------- * ---------- | | * | | -----请求----->> | -> ----------- -> ----- | * | 用户请求 | | | Executor | | DB | | * | | <<---响应------- | <- ----------- <- ----- | * ---------- | | * ---------------------------------- * 如果BaseExecutor 中cache 中可以查到则 直接返回不查 DB 一级缓存 会话级别, 当一个Mapper操作多个表时,不同Mapper之间相互无感知 * 所以有几率造成脏读 * * >>>>>> 二级缓存 namespace * ------------------------------------------------------ * ---------- | | * | | -----请求----->> | -> ---------------- -> ----------- -> ----- | * | 用户请求 | | |CachingExecutor | | Executor | | DB | | * | | <<---响应------- | <- ---------------- <- ----------- <- ----- | * ---------- | | * ------------------------------------------------------- * 二级命名空间级别,namespace 由于增删改 会造成缓存的清空,所以如果一个 命名空间 增删改方法较多 缓存就显得很鸡肋 * * 所以我们一般都会采用第三方的缓存方案,而不使用mybatis自带的缓存 * * ++++++++++++++++++++++ 源码解析 ++++++++++++++++++++++ * * >>>>>> * mybatis 中的设计模式: * (1) 缓存 Cache 使用装饰器模式,持有被装饰类的对象通过构造函数传入 * (2) 建造者模式 * ResultMap.Builder * MappedStatement.Builder * >>>>>> * -> SqlSessionFactoryBuilder.build() -> XMLConfigBuilder -> 解析 核心配置文件, 设置 Configuration 的属性 * * -> cache-ref/cache/sql等标签 * * -> XMLMapperBuilder 解析 Mapper 的xml文件 * resultMap -> 存入Configuration的 resultMaps * select|insert|update|delete 标签 封装 MappedStatement 对象存入mappedStatements 的Map集合中
mybatis提升基础若干问
最新推荐文章于 2023-10-31 18:51:32 发布