框架
- 是一系列jar包,其本质是对JDK功能的拓展。
- 框架是一组程序的集合,包含了一系列的最佳实践,作用是解决某一领域的问题。
Web开发中的最佳实践(根据职责的纵向划分:控制层,业务层,持久层)
控制层:web/mvc 负责处理与界面交互的相关操作(Structs2/Sping MVC)
业务层:service 负责负责的业务逻辑计算和判断(Spring)
持久层:dao 负责将业务逻辑数据进行持久化存储(MyBatis/Hibernate)
ORM思想
- 对象关系映射(Object Relational Mapping,简称ORM)
- 是一种为了解决面向对象与关系型数据库存在的互不匹配的问题的技术。也就是说,ORM是通过使用描述对象和数据库之间映射的元数据,将Java程序中的对象自动持久化到关系数据库中。
- 常见的ORM框架
1)JPA:本身是一种ORM规范,不是ORM框架,有各大ORM框架提供实现
2)Hibernate:目前最流行的ORM框架,设计灵巧,性能优秀,文档丰富。
3)MyBatis:目前最受欢迎的持久层解决方案。
MyBatis
4. MyBatis是支持普通SQL查询,存储过程和高级映射的持久层框架,严格上说应该是一个SQL映射框架。其前身是iBatis(淘宝使用的持久层框架)
5. 几乎所有的JDBC代码和参数的手工设置以及结果集的处理都可以交给MyBatis完成。只需要通过使用XML或注解配置就可以完成。
MyBatis核心组件
6. SqlSessionFactoryBuilder(构建器):根据配置信息或Java代码来构建SqlSessionFactory对象。
作用:创建SqlSessionFactory对象。
作用域:方法作用域
7. SqlSessionFactory(会话工厂):好比是DataSource,线程安全的,在应用运行期间不要重复创建多次,建议使用单例模式。
作用:创建SqlSession对象
作用域:应用作用域
8. SqlSession(会话):好比是Connection,线程不安全的,底层封装了JDBC。每次使用开启新的SqlSession对象,使用完毕正常关闭,默认使用DefaultSqlSession。提供操作数据库的增删改查方法,可以调用操作方法,也可以操作Mapper组件。
作用域:请求或方法作用域
9. Executor(执行器):SqlSession本身不能直接操作数据库,需要Executor来完成,该接口有两个实现:缓存执行器(缺省)、基本执行器。
10. MappedStatement:映射语句封装执行语句时的信息如SQL、输入参数、输出结果。
MyBatis工作原理
- MyBatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件中构建出SqlSessionFactory。
- SqlSessionFactory的实例直接开启一个SqlSession,再通过SqlSession实例获得Mapper对象并运行Mapper映射的SQL语句,完成对数据库的CRUD和事务提交。
- 关闭SqlSession。
MyBatis配置文件
- MyBatis的配置文件有两种
1)主配置文件(只有一份):主要包括数据库的信息,如连接池、事务等和全局的配置,如关联映射日志、插件等。
2)映射文件(有多份):包含对象的CRUD操作的配置和SQL。
MyBatis缓存机制
- MyBatis的缓存,包括一级缓存和二级缓存
1)一级缓存(本地缓存),默认一级开启
2)二级缓存(查询缓存),需要手动开启和配置,基于其他的缓存框架技术。 - 一级缓存:(是SqlSession级别的)在SqlSession中存在一个Map用于缓存查询出来的对象,可以提升性能。(MyBatis把执行的方法和参数通过算法生成缓存的key,将key和查询的结果value存入一个Map对象中)
注意:一级缓存提升性能有限,因为SqlSession生命周期太短(和SqlSession相同),真正需要提升性能我们得使用二级缓存。 - 二级缓存:是mapper级别的。二级缓存是多个SqlSession共享的,作用域是mapper的同一个namespace。即在同一个namespace中查询sql可以从缓存中获取数据。
Mapper组件
- Mapper组件:MyBatis中的组件有Java接口和XML映射文件组成。
- 使用Mapper组件
1)创建一个Mapper接口的要求:
① 接口的全限名,就是映射文件中的namespace的值
② 接口的方法名,就是映射文件中MappedStatement的id值
③ 接口方法内的参数,就是传递给sql的参数。
Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement。
Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。
2)创建SqlSession
3)通过SqlSession.getMapper(XxxMapper.class)方法得到一个Mapper对象
4)调用Mapper对象上的方法完成对象的CRUD。 - Mapper接口的原理是JDK动态代理。
MyBatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。
#{}和${}
- #和$都可以获取对象中的属性。
- 区别:
1)使用#传递的参数会先转换为String,无论传递是什么类型数据都会带一个单引号。
2)使用$传递的参数,直接把值作为SQL语句的一部分。 - 注意:
1)#{}方式能够很大程度防止sql注入。
2)如果需要设置占位符参数,全部使用#,也就是SQL中可以使用?的地方。
3)如果需要拼接成SQL的一部分使用$,比如排序。
Mybatis查询结果映射
- 使用别名
如果表中的列名和对象属性名不匹配,我们可以设置查询结果集中列的别名,把列的别名设置和对象中属性同名。 - 使用resultMap
resultMap元素定义了一个ORM的具体映射规则
1)type属性:最终返回的对象类型
2)id属性:该结果映射名称,这个名称就是在get或listAll中使用的resultMap对应的id。
3)子元素result:把结果集中的哪一个列设置到对象中的哪一个属性上,处理普通列
4)子元素id:和result功能相同,处理主键时使用id元素提升性能,处理主键列。