Mybatis


Mybatis

1. 什么是 Mybatis ?

(1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。

2. Mybatis 和 Hibernate 有哪些不同 ?

(1)Mybatis 和 Hibernate 不同,它不完全是一个 ORM 框架,因为 MyBatis 需要程序员自己编写 Sql 语句。Mybatis 可以通过 XML 或注解方式灵活配置要运行的sql语句,并将 Java 对象和 sql 语句映射生成最终执行的 sql,最后将 sql 执行的结果再映射生成 Java 对象。
(2)Mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。
(3)Hibernate对象/关系映射能力强,数据库无关性好。

3. #{} 和 ${} 有什么不同 ?

  • #{}
    (1)表示一个占位符号,通过#{}可以实现 preparedStatement 向占位符中设置值
    (2)自动进行java类型和jdbc类型转换
    (3)#{}可以有效防止sql注入
    (4)如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

  • $ {}
    (1)$ {}表示拼接sql串,通过 $ {}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换

    (2)$ {}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,$ {}括号中只能是value。

4. 当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

  1. 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
<select id = ”selectorder”  parametertype=int”  resultetype=”me.gacl.domain.order>
    select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};
 </select>
  1. 通过来映射字段名和实体类属性名的一一对应的关系。
<select id="getOrder" parameterType="int" resultMap="orderresultmap">
    select * from orders where order_id=#{id}
</select>

<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
    <!–用id属性来映射主键字段–>
    <id property=”id” column=”order_id”>

    <!–用result属性来映射非主键字段,property为实体类属性名,column为数据表中的属性–>
    <result property = “orderno” column =”order_no”/>
    <result property=”price” column=”order_price” />
</reslutMap>

5. 模糊查询like语句该怎么写 ?

  1. 在Java代码中添加sql通配符。
string wildcardname =%smi%;
list<name> names = mapper.selectlike(wildcardname);
 
<select id=”selectlike”>
     select * from foo where bar like #{value}
</select>
  1. 在sql语句中拼接通配符,会引起sql注入
string wildcardname = “smi”;
list<name> names = mapper.selectlike(wildcardname);
 
<select id=”selectlike”>
     select * from foo where bar like "%"${value}"%"
</select>

6. Mybatis是如何进行分页的?分页插件的原理是什么?

7. Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

第一种是使用 标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种是使用 sql 列的别名功能,将别名书写为对象属性名。
有了列明和属性名的映射关系之后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性是无法完成赋值的。

8. Mybatis 如何执行批量插入 ?

首先创建一个简单的 insert 语句:

<insert id = "insertname">
    insert into names (name) value (#{value})
</insert>

然后在 Java 代码中这样执行批量插入:

list<string> names = new arraylist();
names.add(“fred”);
names.add(“barney”);
names.add(“betty”);
names.add(“wilma”);

sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
namemapper mapper = sqlsession.getmapper(namemapper.class);
     for (string name : names) {
         mapper.insertname(name);

9. 如何获取自动生成的主键值 ?

insrt 方法总是返回一个 int 值,这个值代表的是插入的行数。
如果采用自增长策略,自动生成的键值在 insert 方法执行完后可以被设置到传入的参数对象中。

<insert id=”insertname” usegeneratedkeys=true” keyproperty=”id”>
     insert into names (name) values (#{name})
</insert>
    name name = new name();
    name.setname(“fred”);
 
    int rows = mapper.insertname(name);
    // 完成后,id已经被设置到对象中
    system.out.println(“rows inserted =+ rows);
    system.out.println(“generated key value =+ name.getid());

10. 在 mapper 中如何传递多个参数 ?

第一种:

//Dao 层的函数
public User selectUser(String name, String area);

//对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。
<select id = "selectUser" resultMap = "BaseResultMap">
    select *  fromuser_user_t   where user_name = #{0} and user_area=#{1}
</select>

11. Mapper 动态代理方式

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

  1. Mapper.xml文件中的namespace与mapper接口的类路径相同。
  2. Mapper 接口的方法名和 Mapper.xml 中定义的每个 statement 的 id 相同
  3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的 parameterType 的类型相同
  4. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的 resultType 的类型相同

12. Mybatis 动态 sql 有什么用 ? 执行原理 ? 有哪些动态 sql ?

Mybatis 动态 sql 可以在 xml 映射文件内,以标签的形式编写动态的 sql。执行原理是根据表达式的值完成逻辑判断并动态拼接 sql。
Mybatis提供了9种动态sql标签:trim | where | set | foreach | if | choose | when | otherwise | bind。

13. xml 映射文件中,除了常见的 select、insert、update 和 delete 标签之外,还有哪些标签 ?

、、、、,加上动态sql的9个标签,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。

14. 为什么说 Mybatis 是半自动的 ORM 映射工具?它与全自动的区别在哪里 ?

Hibernate 属于全自动的 ORM 映射工具, 使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。

15. 一对一、一对多关联查询 ?

一对一查询
  1. 比如,一个订单只能是一个人下的,所以从查询订单信心出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询。
  2. 方法一:使用resultType。使用resultType,改造订单pojo类,此pojo类中包括了订单信息和用户信息这样返回对象的时候,mybatis自动把用户信息也注入进来了。
  3. 方法二:使用resultMap。使用resultMap,定义专门的resultMap用于映射一对一查询结果。
一对多查询

16. Mybatis 是否支持延迟加载 ?如果支持,原理是什么 ?

Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association指的就是一对一collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。

它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

17. Mybatis 的一级二级缓存

Mybatis缓存
缓存的重要性是不言而喻的。 使用缓存, 我们可以避免频繁的与数据库进行交互, 尤其是在查询越多、缓存命中率越高的情况下, 使用缓存对性能的提高更明显。

mybatis 也提供了对缓存的支持, 分为一级缓存和二级缓存。 但是在默认的情况下, 只开启一级缓存(一级缓存是对同一个 SqlSession 而言的)。

同一个 SqlSession 对象, 在参数和 SQL 完全一样的情况先, 只执行一次 SQL 语句(如果缓存没有过期)。

在日志和输出中:

第一次查询发送了 SQL 语句, 后返回了结果;

第二次查询没有发送 SQL 语句, 直接从内存中获取了结果。

而且两次结果输入一致, 同时断言两个对象相同也通过。

总结:

  1. 在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map 中获取数据;
  2. 不同的 SqlSession 之间的缓存是相互隔离的;
  3. 用一个 SqlSession, 可以通过配置使得在查询前清空缓存;
  4. 任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值