问题:JDBC编程有哪些不足之处,Mybatis是如何解决这些问题的 ?
Ⅰ、数据库连接的创建、释放频繁造成系统资源浪费从而影响了性能,如果使用数据库连接池就可以解决这个问题。
当然JDBC同样能够使用数据源。
解决:在SQLMapConfig.xml中配置数据连接池,使用数据库管理数据库连接。
Ⅱ、 SQL语句在写代码中不容易维护,事件需求中SQL变化的可能性很大,SQL变动需要改变JAVA代码。
解决:将SQL语句配置在mapper.xml文件中与java代码分离。
Ⅲ、向SQL语句传递参数麻烦,因为SQL语句的where条件不一定,可能多,也可能少,占位符需要和参数一一对应。
解决:Mybatis自动将java对象映射到sql语句。
Ⅳ、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
解决:Mybatis自动将SQL执行结果映射到java对象。
问题:Mybatis编程步骤 ?
Step1:创建SQLSessionFactory
Step2:通过SQLSessionFactory创建SQLSession
Step3:通过SQLSession执行数据库操作
Step4:调用session.commit()提交事物
Step5:调用session.close()关闭会话
问题:Mybatis与Hibernate有哪些不同 ?
Ⅰ、MyBatis 是支持定制化 SQL、存储过程以及高级映射的一种持久层框架。
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
Mybatis它不完全是一个ORM(对象关系映射)框架;它需要程序员自己编写部分SQL语句。
mybatis可以通过xml或者注解的方式灵活的配置要运行的SQL语句,并将java对象和SQL语句映射生成最终的执行的SQL,最后将SQL执行的结果在映射生成java对象。
Mybatis程序员可以直接的编写原生态的SQL语句,可以控制SQL执行性能,灵活度高,适合软件需求变换频繁的企业。
缺点:
Mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套SQL映射文件,工作量大。
Ⅱ、Hibernate是支持定制化 SQL、存储过程以及高级映射的一种持久层框架。
Hibernate对象-关系映射能力强,数据库的无关性好,
Hibernate可以自动生成SQL语句,对于关系模型要求高的软件,如果用Hibernate开发可以节省很多时间。
问题:使用Mybatis的Mapper接口调用时候有哪些要求 ?
Ⅰ、Mapper接口方法名和Mapper.xml中定义的每个SQL的id相同;
Ⅱ、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType类型相同
Ⅲ、Mapper接口方法的输入输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
Ⅳ、Mapper.xml文件中的namespace,就是接口的类路径。
问题:SQLMapConfig.xml(mybatis.cfg.xml)中配置有哪些内容 ?
名称 含义 properties 属性 settings 配置 typeAliases 类型别名 typeHandlers 类型处理器 objectFactory 对象工厂 plugins 插件 environments 环境集合属性对象 environment 环境子属性对象 transactionManager 事务管理 dataSource 数据源 mappers 映射器
问题:Mybatis的一级缓存和二级缓存 ?
Ⅰ、一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession, Mybatis默认开启一级缓存。 在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。 当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。 每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。 Mybatis的内部缓存使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。 SqlSession执行insert、update、delete等操作commit后会清空该SQLSession缓存。
Ⅱ、二级缓存 二级缓存是mapper级别的,Mybatis默认是没有开启二级缓存的。
第一次调用mapper下的SQL去查询用户的信息,查询到的信息会存放代该mapper对应的二级缓存区域。
第二次调用namespace下的mapper映射文件中,相同的sql去查询用户信息,会去对应的二级缓存内取结果。
问题:Mapper编写有几种方式 ?
Ⅰ、接口实现类集成SQLSessionDaoSupport
此方法需要编写mapper接口,mapper接口的实现类,mapper.xml文件。
Ⅱ、使用org.mybatis.spring.mapper.MapperFactoryBean
此方法需要在SqlMapConfig.xml中配置mapper.xml的位置,还需定义mapper接口。
Ⅲ、使用mapper扫描器
需要编写mapper.xml文件,需要mapper接口,配置mapper扫描器,使用扫描器从spring容器中获取mapper的实现对象。
问题:Mybatis的映射文件 ?
Mybatis 真正强大的在于它的映射文件,它和JDBC代码进行比较,可以省掉95%的代码,Mybatis就是针对SQL进行构建。 SQL映射文件中几个顶级的元素:
名称 含义 cache 给定命名空间的缓存配置。 cache-ref 其他命名空间缓存配置的引用。 resultMap 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。 sql 可被其他语句引用的可重用语句块。 insert 映射插入语句 update 映射更新语句 delete 映射删除语句 select 映射查询语句
问题:Mybatis动态SQL ?
1) 传统的JDBC的方法,在组合SQL语句的时候需要去拼接,稍微不注意就会少少了一个空格,标点符号,都会导致系统错误。Mybatis的动态SQL就是为了解决这种问题而产生的;Mybatis的动态SQL语句值基于OGNL表达式的,方便在SQL语句中实现某些逻辑;可以使用标签组合成灵活的sql语句,提供开发的效率。
2) Mybatis的动态SQL标签主要由以下几类:
名称 解释 If语句 简单的条件判断 Choose(when/otherwise) 相当于java语言中的switch,与jstl中choose类似 Trim 对包含的内容加上prefix(前缀),或者suffix(后缀) Where 主要是用来简化SQL语句中where条件判断,
能智能的处理and/or 不用担心多余的语法导致的错误
Set 主要用于更新时候 Foreach 一般使用在mybatis in语句查询时特别有用
问题:Mybatis分页查询 ?
Mybatis本身有分页查询,但是并不是真正的分页查询,它是把数据查出来放在内存里面,你想要什么就给你什么。
我们使用Mybatis实现分页查询的时候,是要实现真分页查询,就是要用sql语句来实现分页查询。
MySQL和Oracle两种数据库的实现方法是不一样的。
Mysql:select * from table limit N , M;其中:N表示从第几页开始,M表示每页显示的条数。
比如:数据库中有30条数据,要求每页显示10条,显示第2页的所有数据。 SQL语句就可以写成:Limit 10 , 20;
Oracle实现分页查询:采用伪列ROWNUM
问题:Mybatis常用注解 ?
名称 含义 @Insert 插入sql , 和xml insert sql语法完全一样 @Select 查询sql, 和xml select sql语法完全一样 @Update 更新sql, 和xml update sql语法完全一样 @Delete 删除sql, 和xml delete sql语法完全一样 @Param 参数 @Results 结果集合 @Result 结果
问题:Mybatis的表关联的映射 ?
名称 含义 名称 含义 Property 对象属性名称 javaType 对象属性的类型 column 所对应的外键字段的名称 select 使用另一个查询封装的结果 ①、一对一关联
②、一对多(多对一)关联
③、多对多关联
问题:Mybatis与Spring的整合 ?
Ⅰ、Spring Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架;
AOP和IOC是Spring框架重要的两个模块;
控制反转就是改变对象的创建方式,将对象的创建和维护有开发人员创建改为由容器帮我们完成创建和维护。
Ⅱ、Mybatis是支持SQL查询,存储过程和高级映射的优秀持久层框架。
Mybatis几乎是消除了使用JDBC存在的重复创建和关闭连接,以及结果集查询的问题。
它使用简单的xml或者注解用于配置和映射,将java的POJOs映射成数据库中的记录。
问题:Mybatis中保存一条记录,返回主键有哪些要求?
保存一条记录,返回主键有两种方法:保存记录时获取主键、保存记录后获取主键
Ⅰ、在保存记录时能够返回主键的关键所在:SQL标签中添加三个属性。即,
①【useGeneratedKeys】的值————>必须设置为【true】,否则无法获得主键id,
可以在【mybatis-config.xml】中设置:
<settings> <setting name="useGeneratedKeys" value="true"/> </settings>
②【keyProperty】————>设置为POJO对象的主键id【属性名称】
③【keyColumn】————>设置为数据库记录的主键id的【字段名称】
Ⅱ、在保存记录之后获取主键,用到了【selectKey】标签
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER"> select LAST_INSERT_ID() 或者 select @@identity </selectKey>
要求:
①【keyProperty】————>设置为POJO对象的主键id【属性名称】
②【keyColumn】————>设置为数据库记录的主键id的【字段名称】
③【resultType】————>设置为获取主键的SQL语句的返回值的【数据类型】
④【order】——————>设置获取主键的SQL语句在保存记录之前【BEFORE】还是之后【AFTER】执行
SQL语句有两种:
# 查询最后一次添加的SQL语句中的主键的值 select LAST_INSERT_ID(); select @@identity
问题:请写出使用Mybatis的Mapper代理的步骤;dao有啥要求?映射文件有什么要求?
mapper:相当于Java里面的类
namespace:相当于Java里面的包名
使用Mapper代理的要求:
————> namespace:必须是Dao接口的包名+类名
————> sql标签中的id:必须和dao接口中的方法名一样,唯一标识,id不能重复
————> parameterType:必须和dao接口方法中的形参类型一样
————> resultType:必须和dao接口方法中的返回值类型一样
——————> 如果查询的是单条,那么返回值类型就是resultType;
——————> 如果查询的是多条,那么返回值的类型是List,List里面放的是resultType
Ⅰ、接口和Mapper文件必须在同一目录下
Ⅱ、mapper.xml中namespace指定为mapper接口的全限定名
Ⅲ、mapper.xml中statement的id就是mapper.java中方法名
Ⅳ、mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致
Ⅴ、mapper.xml中statement的resultType和mapper.java中方法返回值类型一致.
问题:请写出Mybatis中映射文件的动态SQL语句常用的SQL标签有哪些?分别代表什么含义?
where
if
when
otherwise
choose
set
sql
include
trim
foreach
test
问题:Mybatis中实现一对多的关联关系的步骤有哪些?
Ⅰ、数据库两表关联字段
A表的主键列是B表的外键列,即,A表——>B表为一对多的关系
Ⅱ、映射文件中需要为两表的关联字段重新赋值
<!-- A表是一的一方,B表是多的一方 --> <mapper namespace="A表"> <select id="findList" resultMap="resultMap" parameterType="A表对应的POJO类的类全限定名"> <!-- 为重复字段【两表中的关联字段】重新赋值 --> <id column="A表中主键ID字段名" property="A表POJO类主键ID对应的属性名"/> <property id="B表POJO类中的A表的自定义引用属性名" column="B表中关联字段的属性名" ofType="B表的类全限定名" select="B表.findList"> </select> </mapper> <mapper namespace="B表"> <select id="findList" resultType="B表对应的POJO类的类全限定名"> select * from B表 where B表关联字段ID = #{ID} </select> </mapper>
Ⅲ、Mapper文件需要在全局配置文件中配置,以便加载配置时知道Mapper文件的位置
问题:Mybatis的分页有三种,分别是什么?
Ⅰ、数组分页 ?
Ⅱ、SQL分页
mysql分页关键字 limit
postgresql分页关键字 offset
oracle 分页:三层rowNum 嵌套
分页必备的两个要素:总条数、每页多少条
<select id="page_Query" resultType="POJO类的全限定名"> select * from 表名 limit 3,2 </select>
Ⅲ、拦截器+插件配置分页
<!-- 配置插件 --> <plugins> <!-- 插件 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 参数 reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时, pageNum<=0 时会查询第一页, pageNum>pages(超过总数时), 会查询最后一页。默认false 时,直接根据参数进行查询。 --> <property name="reasonable" value="true"/> </plugin> </plugins>
插件:pageHelper:Page page = pageHelper.startPage(a,b);
总条数:page.getTotal();
总页数:page.getPageSize();
每页条数:page.getPages();
page.getPageNum();
Ⅳ、RowBounds分页
Mybatis中自带的RowBounds;RowBounds rowBounds = new RowBounds(a,b);