Mybatis面试题(二)

发布时间:2024年01月18日

MyBatis 面试题

image-20240118215243855

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

第一种是使用标签,逐一定义数据库列名和对象属性名之间的映射关系。

第二种是使用 sql 列的别名功能,将列的别名书写为对象属性名。

有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

12、如何执行批量插入?

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

<insert id="insertname">

insert into names (name) values (#{value})

</insert>

然后在 java 代码中像下面这样执行批处理插入:

list < string > names = new arraylist();

names.add(“fred”);

names.add(“barney”);

names.add(“betty”);

names.add(“wilma”);

// 注意这里 executortype.batch

sqlsession sqlsession =

sqlsessionfactory.opensession(executortype.batch);

try {

namemapper mapper = sqlsession.getmapper(namemapper.class);

for (string name: names) {

mapper.insertname(name);

}

sqlsession.commit();

} catch (Exception e) {

e.printStackTrace();

sqlSession.rollback();

throw e;

}

finally {

sqlsession.close();

}
13、如何获取自动生成的(主)键值?

insert 方法总是返回一个 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());
14、在 mapper 中如何传递多个参数?

1、第一种:

DAO 层的函数

public UserselectUser(String name,String area);

对应的 xml,#{0}代表接收的是 dao 层中的第一个参数,#{1}代表 dao 层中第二参数,更多参数一致往后加即可。

<select id="selectUser"resultMap="BaseResultMap">

select * fromuser_user_t 

whereuser_name = #{0}

anduser_area=#{1}

</select>

2、第二种: 使用 @param 注解:

public interface usermapper {

user selectuser(@param(“username”) string

username,@param(“hashedpassword”) string hashedpassword);

}


然后,就可以在 xml 像下面这样使用(推荐封装为一个 map,作为单个参数传递给mapper):

<select id="selectuser" resulttype="user">

select id, username, hashedpassword

from some_table

where username = #{username}

and hashedpassword = #{hashedpassword}

</select>

3、第三种:多个参数封装成 map

try {

//映射文件的命名空间.SQL 片段的 ID,就可以调用对应的映射文件中的

SQL

//由于我们的参数超过了两个,而方法中只有一个 Object 参数收集,因此

我们使用 Map 集合来装载我们的参数

Map < String, Object > map = new HashMap();

map.put("start", start);

map.put("end", end);

return sqlSession.selectList("StudentID.pagination", map);

} catch (Exception e) {

e.printStackTrace();

sqlSession.rollback();

throw e;

} finally {

MybatisUtil.closeSqlSession();

}
15、Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql?

Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql,执行原理是根据表达式的值 完成逻辑判断并动态拼接 sql 的功能。

Mybatis 提供了 9 种动态 sql 标签:trim | where | set | foreach | if | choose| when | otherwise | bind。

16、Xml 映射文件中,除了常见的 select|insert|updae|delete标签之外,还有哪些标签?

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

17、Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?

不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配置 namespace,那么 id 不能重复;

原因就是 namespace+id 是作为 Map<String, MapperStatement>的 key使用的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。

有了 namespace,自然 id 就可以重复,namespace 不同,namespace+id 自然也就不同。

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

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

19、 一对一、一对多的关联查询 ?
<mapper namespace="com.lcb.mapping.userMapper">

<!--association 一对一关联查询 -->

<select id="getClass" parameterType="int"

  resultMap="ClassesResultMap">

  select * from class c,teacher t where c.teacher_id=t.t_id and

  c.c_id=#{id}

</select>

<resultMap type="com.lcb.user.Classes" id="ClassesResultMap">

  <!-- 实体类的字段名和数据表的字段名映射 -->

  <id property="id" column="c_id"/>

  <result property="name" column="c_name"/>

  <association property="teacher" javaType="com.lcb.user.Teacher">

    <id property="id" column="t_id"/>

    <result property="name" column="t_name"/>

  </association>

</resultMap>

<!--collection 一对多关联查询 -->

<select id="getClass2" parameterType="int" resultMap="ClassesResultMap2">

  select * from class c,teacher t,student s where c.teacher_id=t.t_id

  and c.c_id=s.class_id and c.c_id=#{id}

</select>

<resultMap type="com.lcb.user.Classes" id="ClassesResultMap2">

  <id property="id" column="c_id"/>

  <result property="name" column="c_name"/>

  <association property="teacher"  javaType="com.lcb.user.Teacher">

    <id property="id" column="t_id"/>

    <result property="name" column="t_name"/>

  </association>

  <collection property="student"  ofType="com.lcb.user.Student">

    <id property="id" column="s_id"/>

    <result property="name" column="s_name"/>

  </collection>

</resultMap>

</mapper>
20、MyBatis 实现一对一有几种方式?具体怎么操作的?

有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap 里面配置 association 节点配置一对一的类就可以完成;

嵌套查询是先查一个表,根据这个表里面的结果的 外键 id,去再另外一个表里面查询数据,也是通过 association 配置,但另外一个表的查询通过 select 属性配置。

文章来源:https://blog.csdn.net/qq_24428851/article/details/135685326
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。