一:mybatis基本工作流程
1.sqlMapConfig.xml:mybatis全局配置文件,配置了数据源,事务等mybatis的运行环境,与spring整合后由spring的配置文件接管。mapper.xml映射文件(配置sql语句等)
2.sqlSessionFactory(会话工厂):创建sqlSession(根据配置文件创建)。
3.sqlSession:操作数据库(crud):是一个面向用户的接口
4.Executor(执行器):SqlSession内部通过该执行器操做数据库(是一个接口:分为基本执行器和缓存执行器)
5.mapped Statement:(底层封装对象):对操作数据库存储封装:包括sql语句,输入参数,输出结果类型进行封装。
二:开发细节
1.mybatis中sql语句的占位符用#{}表示。
2.#{}中的值表示接收输入参数,如果输入参数类型为简单类型,其中的名称可以为任意值。
3.${}:表示拼接sql串,将接受到参数的内容不加任何修饰拼接在sql中。注意:使用${}拼接sql,会引起sql注入,${value}:接收输入参数内容为简单类型,必须为value.
4.主键返回策略:
主键id为自增类型:select Last_insert_ID().
配置中使用selectKey标签,标签属性KeyProperty:将查询的主键返回值设置到对象的哪个属性中。order:相对于insert执行语句的执行顺序。resultType:返回的结果类型。
三:mybatis与hibernate的区别
hibernate:是一个标准的ORM映射,不需要写sql语句,sql语句会全自动生成,同时对sql语句进行优化,修改比较困难。应用场景:适用于需求变化不多的中小型项目(ORM,OA...)
mybatis:专注于sql本身,需要自己编写sql,sql语句的修改优化比较方便,是一个不完全的ORM框架,虽然自己写sql,也可以实现映射。应用场景:适用于需求变化较多的项目(互联网项目)
企业进行技术选型,是以低成本,高回报作为技术选型的原则。
四:sqlSession应用场合
sqlSession是一个面向用户的接口,是线程不安全的,在SqlSession中的实现类中除了有方法,还有数据域属性,因此是多例的。
sqlSession最佳应用场合是在方法体内,定义局部变量。
五:原始dao问题总结
1.dao接口实现类方法中存在大量模板方法,重复代码较多
2.调用sqlsession方法statement的id硬编码 。
3.sqlsession传入的变量为object型,如果参数传递错误,编译阶段会报错
六:mapper代理方法(对原始dao的优化)
mapper代理方法能够省去实现类这一步骤
使用步骤:
1.程序员需要编写mapper.xml文件
2.编写mapper接口需要依据规范:
①:在mapper,xml中namespace等于mapper接口的地址。
②:mapper接口的方法名须和xml中statement的id一致
③:mapper接口的方法输入参数须和xml中parameterType类型一致。
④:mapper接口方法的返回值类型须和xml中的resultType类型一致。
3.获取自动生成的实现类对象
sqlSession.getMapper(接口名.class);
七:SqlMapConfig,xml解析
1.properties标签:
可以引用一些properties的资源文件。注意:不建议在properties标签里添加属性,可能会覆盖掉其他相同名称的属性值。
2.Setting标签:
配置全局参数:主要是跟Mybaties运行相关的一些参数,具体配置详见mybaties-setting.xlsx文件
3.typeAliases
别名定义。在mybatis中的resultType和parameterType的类型有可能是自定义的pojo类型,地址很长,不利于开发,可以使用别名定义。
批量别名定义:在其中使用package标签,name为保明,别名为类名,首字母不区分大小写。
4.类型处理器
jdbc类型与Java类型之间的相互转换,mybatis提供了许多转换类型,因此一般不需要我们手动配置。
5.mapper
class属性加载的是通过mapper接口加载映射文件,但需要遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称一致,且在同一个目录当中。
mapper批量加载:遵循上述规范,用package标签
八:输入映射
自定义包装类型,可以将很多pojo类以及扩展类定义在包装类型中,根据需求而定
九:输出映射
1.resultType
①:使用该属性映射,只有查询出来的列名与pojo属性名一致,才可以映射成功
②:如果查询出来的列名与pojo属性名全都不一致,则不会创建映射的pojo对象,但只要有一个列与pojo属性名称一致,就会创建pojo对象
2.resultMap
如果查询出来的列名与pojo属性名不一致却还要与pojo映射,可以使用resultMap
首先要定义resultMap与pojo属性的对应关系
十:动态sql
1.主要是where标签与if标签的综合使用,进行灵活的判断后动态拼接sql语句,where标签会自动将第一个and去掉。
2.定义sql片段:可以将相同的sql片段提取出来,这样其他的语句就可以引用该sql,在mapper.xml文件中单独使用sql标签定义。注意:相对于单表定义可重用性才高,不要在其中定义where标签。引用sql片段用include标签。
3.foreach标签可以遍历组装sql语句
collection属性为集合属性名
items为集合属性名称
open为拼接开始语句,close为拼接结束语句,separator为拼接集合属性的连接sql
十一:一对一查询,一对多查询
1.resultType:使用较为简单,如果pojo中没有查询出来的列名,只需要在pojo中增加对应的属性即可完成映射。如无特殊要求建议使用resultType:
2.resultMap:需要在映射文件中单独实现resultMap,如果对查询结果有特殊要求,使用resultMap可以完成将关联查询映射到pojo属性中,并且resultMap可以实现延迟加载,而resultType不能。
使用association标签将关联的信息映射到单个Java对象中,使用collection将关联信息映射到对象的集合当中。
在查询过程中,可以发现resultMap方式的实现相对于resultType相当复杂,因此建议使用resultType。
十二:延迟加载
定义resultMap中配置association,通过其select标签指定需要延迟加载的statement的id,column指定两表关联的外键列。使用延迟加载需要在主配置文件中打开延迟加载,其默认是关闭状态。
事实上完全可以定义两个查询方法实现延迟加载一样的功能。
十三:一级缓存
sqlSession级别的一级缓存,在执行sqlSession.commit操作之后会被清空一级缓存以防止脏读,一级缓存默认是开启的。
十四:二级缓存
mapper级别的二级缓存是可以让多个sqlsession公用的,区分不同的二级缓存用namespace区分,开启二级缓存除了在主配置文件中打开之外,还需要在相应的mapper.xml中开启,使用cache标签,开启二级缓存之后,如果sqlsession不进行关闭操作,数据是不会被写入二级缓存当中的,如果单个的某条语句不想使用二级缓存,可以userCache属性值来控制。