一、半自动与全自动的区别
1.半自动
mybatis就属于半自动的ORM映射工具,它在查询关联队形或关联集合对象时,需要手动编写sql语句。
2.全自动
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
二、什么是ORM框架
对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。ORM框架是连接数据库的桥梁,只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。
ORM框架:为了解决面型对象与关系数据库存在的互不匹配的现象的框架。
ORM的优缺点:
优点:
1)提高开发效率,降低开发成本
2)使开发更加对象化
3)可移植
4)可以很方便地引入数据缓存之类的附加功能
缺点:
1)自动化进行关系数据库的映射需要消耗系统性能。其实这里的性能消耗还好啦,一般来说都可以忽略之。
2)在处理多表联查、where条件复杂之类的查询时,ORM的语法会变得复杂。
三、mybatis与Hibernate的区别
相同点
Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。
其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。Hibernate和MyBatis都支持JDBC和JTA事务处理。
不同点
- hibernate是全自动,而mybatis是半自动
- hibernate数据库移植性远大于mybatis.
hibernate通过它强大的映射结构和hql语言,大大降低了对象与数据库(Oracle、MySQL等)的耦合性,而mybatis由于需要手写sql,因此与数据库的耦合性直接取决于程序员写sql的方法,如果sql不具通用性而用了很多某数据库特性的sql语句的话,移植性也会随之降低很多,成本很高。 - hibernate拥有完整的日志系统,mybatis则欠缺一些
hibernate日志系统非常健全,涉及广泛,包括:sql记录、关系异常、优化警告、缓存提示、脏数据警告等;而mybatis则除了基本记录功能外,功能薄弱很多。 - sql直接优化上,mybatis要比hibernate方便很多
由于mybatis的sql都是写在xml里,因此优化sql比hibernate方便很多。而hibernate的sql很多都是自动生成的,无法直接维护sql;虽有hql,但功能还是不及sql强大,见到报表等变态需求时,hql也歇菜,也就是说hql是有局限的;hibernate虽然也支持原生sql,但开发模式上却与orm不同,需要转换思维,因此使用上不是非常方便。总之写sql的灵活度上hibernate不及mybatis。 - 缓存机制上,hibernate要比mybatis更好一些
MyBatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现。
而Hibernate对查询对象有着良好的管理机制,用户无需关心SQL。所以在使用二级缓存时如果出现脏数据,系统会报出错误并提示。
四、动态sql一对一、一对多、多对多的理解
一对一:一对一按照我自己的理解就是一个类型的对象只对应另外一个类型的对象,例如:每个人都只有一个名字。
一对多:一对多就是一个对象能够对应另外一个类型的多个对象,例如:一个老板名下可以有多个公司。
多对多:多对多就像 学生和学科 一个学生可以选修多门学科,一门学科也可以被多名学生选。
五、一级缓存、二级缓存
一级缓存
一级缓存作用域是sqlsession级别的, Mabits默认开启一级缓存,同一个sqlsession中执行相同的sql查询(相同的sql和参数),第一次会去查询数据库并写到缓存中,第二次从一级缓存中取。
当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。 每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。
二级缓存
它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的
六、分页查询插件
使用方法
- 使用Maven在pom.xml中引入:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>最新版本</version>
</dependency>
- 在核心配置文件下添加如下内容:
<!-- 配置分页助手插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
- 代码实现
@Test
public void test8() throws Exception {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = build.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//设置分页参数
PageHelper.startPage(1(当前页数),3(每页显示条数));
List<User> all = mapper.findAll();
for (User user : all) {
System.out.println(user);
}
PageInfo<User> pageInfo = new PageInfo<User>(all);
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示条数:"+pageInfo.getPageSize());
System.out.println("总记录数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("上一页:"+pageInfo.getPrePage());
System.out.println("下一页:"+pageInfo.getNextPage());
System.out.println("是否是第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否是最后一页:"+pageInfo.isIsLastPage());
}
七、延时加载
MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询。延迟加载可以有效的减少数据库压力。
延时加载类型及设定
通过对全局参数:lazyLoadingEnabled进行设置,默认就是false。 进行设置修改延时加载状态。
直接加载: 执行完对主加载对象的select语句,马上执行对关联对象的select查询。
<settings>
<!-- 延迟加载总开关 -->
<setting name="lazyLoadingEnabled" value="false"/>
</settings>
侵入式延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的某个属性(该属性不是关联对象的属性)时,就会马上执行关联对象的select查询。
<settings>
<!-- 延迟加载总开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延迟加载开关 -->
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
深度延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的select查询。
<settings>
<!-- 延迟加载总开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延迟加载开关 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
优缺点
- 深度延迟加载的使用会提升性能。
- 如果延迟加载的表数据太多,此时会产生N+1问题,主信息加载一次算1次,而从信息是会根据主信息传递过来的条件,去查询从表多次。
八、#与$符号的区别
这两个符号在mybatis中最直接的区别就是:#相当于对数据 加上 单引号,$相当于直接显示数据(只讨论字符串类型的)。
- #对传入的参数视为字符串,也就是它会预编译,select * from user where name = #{name},比如我传一个aaa,那么传过来就是 select * from user where name = ‘aaa’;
- $将不会将传入的值进行预编译,select * from user where name=${name},比如我传一个aaa,那么传过来就是 select * from user where name = aaa;
- #的优势就在于它能很大程度的防止sql注入,而$则不行。
接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查(通常我们应该对任何传来的参数都抱着不信任的做法来写程序,这样我们的程序才安全)。
总结
- #{变量名}可以进行预编译、类型匹配等操作。
- #{变量名}会转化为jdbc的类型。
- ${变量名}不进行数据类型匹配,直接替换。
- #方式能够很大程度防止sql注入。
- $方式无法防止sql注入。
- $方式一般用于传入数据库对象,例如传入表名。
- 尽量多用#方式,少用$方式。
- #会自动加双引号,$不会加双引号
本文对比了MyBatis与Hibernate这两种ORM框架的特点与应用场景,包括它们的一对一、一对多、多对多关联处理方式,一级缓存与二级缓存机制,并探讨了动态SQL、分页查询插件及延迟加载的实现。
1183

被折叠的 条评论
为什么被折叠?



