1、Mybatis中#和$的区别?
● #相当于对数据加上双引号,$相当于直接显示数据
● #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by#user_id#,如果传入的值是111,那么解析成sql时的值为order by"111",如果传入的值是id,则解析成的sql为order by “id”.
● 将传入的数据直接显示生成在 s q l 中。如: o r d e r b y 将传入的数据直接显示生成在sql中。如:order by 将传入的数据直接显示生成在sql中。如:orderbyuser_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,如果传入的值是id,则解析成的sql为order by id.
● #方式能够很大程度防止sql注入,$方式无法防止Sql注入。
● $方式一般用于传入数据库对象,例如传入表名.
2、Mybatis的编程步骤是什么样的?
● 创建SqlSessionFactory
● 通过SqlSessionFactory创建SqlSession
● 通过sqlsession执行数据库操作
● 调用session.commit()提交事务
● 调用session.close()关闭会话
3、JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
● 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,使用数据库链接池可解决此问题。解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
● Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
● 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。解决: Mybatis 自动将 java 对象映射至 sql 语句。
● 对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对象解析比较方便。解决:Mybatis 自动将 sql 执行结果映射至 java 对象。
4、使用MyBatis的mapper接口调用时有哪些要求?
● Mapper接口方法名和mapper.xml中定义的每个sql的id相同
● Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
● Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
● Mapper.xml文件中的namespace即是mapper接口的类路径。
5、Mybatis中一级缓存与二级缓存?
● 一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当flush或close之后,该Session中的所有Cache就将清空。
● 二级缓存与一级缓存其机制相同,默认也是采用PerpetualCache的HashMap存储,不同在于其存储作用域为Mapper(namespace),并且可自定义存储源,如Ehcache。作用域namespace是指对namespace所对应的配置文件中所有的select操作结果都缓存,这样不同线程之间就可以共用二级缓存。二级缓存可以设置返回的缓存对象策略:。当readOnly="true"时,表示二级缓存返回给所有调用者同一个缓存对象实例,调用者可以update获取的缓存实例,但是这样可能会造成其他调用者出现数据不一致的情况(因为所有调用者调用的是同一个实例)。当readOnly=“false”时,返回给调用者的是二级缓存总缓存对象的拷贝,即不同调用者获取的是缓存对象不同的实例,这样调用者对各自的缓存对象的修改不会影响到其他的调用者,即是安全的,所以默认是readOnly=“false”;
● 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)进行了C/U/D操作后,默认该作用域下所有select中的缓存将被clear。
6、MyBatis在insert插入操作时如何返回主键ID?
数据库为 MySql 时:
数据库为Oracle时:
SELECT SEQ_USER.NEXTVAL as userId from DUAL insert into user (user_id, user_name, modified, state) values (#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR}, #{modified,jdbcType=TIMESTAMP},#{state,jdbcType=INTEGER}) 由于Oracle没有自增长这一说法,只有序列这种自增的形式,所以不能再使用“useGeneratedKeys”属性。而是使用将ID获取并赋值到对象的属性中,insert插入操作时正常插入id。