MyBatis面试题(2020年持续更新)

 2024-02-02 04:03:40  阅读 0

1. 它是什么?

1.它是一个半ORM(对象关系映射)框架,内部封装了JDBC。 开发时

您只需要关注SQL语句本身,不需要花费精力加载驱动、创建连接、创建

等待复杂的过程。程序员直接编写原始SQL并可以严格控制SQL执行

有能力且高度灵活。

2. 可以使用XML或者注解来配置和映射原生信息,将POJO映射成数字。

数据库中的记录避免了几乎所有的 JDBC 代码以及手动设置参数和检索结果集。

3、通过xml文件或者注解配置要执行的各种功能,并通过

Java对象和SQL中的动态参数进行映射,生成最终执行的SQL语句。

然后框架执行sql并将结果映射到java对象中并返回它。 (从执行sql到返回

退货流程)。

2、优点:

1.基于SQL语句的编程相当灵活,不会对应用程序或数据库现有的设计产生任何影响。 SQL采用XML编写,将SQL与程序代码解耦,便于统一管理; 提供了 XML

标签支持编写动态SQL语句并且可以重复使用。

2、与JDBC相比,代码量减少50%以上,消除了JDBC中大量冗余代码。

需要手动开关连接;

3、对各种数据库的兼容性非常好(因为连接数据库都是使用JDBC,所以只要

支持 JDBC 支持的所有数据库)。

4、能够很好的融入;

5.提供映射标签,支持对象与数据库之间的ORM字段关系映射; 提供对象关系映射

标签支持对象关系组件维护。

3.框架的缺点:

1、编写SQL语句的工作量比较大,尤其是字段较多、关联表较多的情况下,开发人员编写起来非常困难。

对SQL语句的基础知识有一定要求。

2、SQL语句依赖于数据库,导致数据库可移植性差,无法随意更换数据库。

4、框架适用场合:

1、关注SQL本身,是一个足够灵活的DAO层解决方案。

2、对性能要求较高或者需求经常变化的项目,比如互联网项目,会

不错的选择。

5. 有什么区别?

1. 不一样

程序员自己写Sql语句。

2.直接编写原始SQL,可以严格控制SQL执行性能,灵活性高,非常

适合对关系数据模型要求不高的软件开发,因为这类软件的需求变化频繁。

寻求改变需要快速输出结果。 但灵活性的前提是不能实现数据库独立性。

如果需要实现支持多种数据库的软件,就需要定制多套SQL映射文件,工作量很大。

3、对象/关系映射能力强,数据库独立性好,对关系模型要求高

软件如果开发出来,可以节省大量代码,提高效率。

6.#{}和${}有什么区别?

#{}是预编译处理,

KaTeX 解析错误:'EOF',在 3: {}is̲ 字符串替换处得到 'is'。 ...{},将 ${} 替换为变量的值。

使用#{}可以有效防止SQL注入,提高系统安全性。

7、实体类中的属性名称与表中的字段名称不同怎么办?

类型一:通过在查询sql语句中定义字段名的别名,让字段名和实体类的别名

属性名称一致。

sql模糊查询like怎么用_模糊查询like的用法_sql模糊查询like变量

<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>  

类型2:用于映射字段名和实体类属性名的一一对应关系。

<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>  

8. 如何编写模糊查询like语句?

类型1:在Java代码中添加sql通配符。

string wildcardname =%smi%;  
list<name> names = mapper.selectlike(wildcardname);  
  
<select id=”selectlike”>  
select * from foo where bar like #{value}  
</select>  

类型2:在SQL语句中拼接通配符会导致SQL注入。

string wildcardname = “smi”;  
list<name> names = mapper.selectlike(wildcardname);  
<select id=”selectlike”>  
select * from foo where bar like "%"#{value}"%"  
</select>  

通常一个Xml映射文件都会有一个与之对应的Dao接口。 这个Dao接口是如何工作的呢? 如果Dao接口中的方法有不同的参数,该方法可以重载吗?

Dao接口是一个接口。 接口的完全限定名称是映射文件中的值;

接口的方法名就是映射文件中的id值; 这

参数是传递给sql的参数。

该接口没有实现类。 调用接口方法时,接口的全限定名+方法名用字符连接。

使用字符串作为键值来唯一定位one.in,每个

,,,标签都会被解析成

目的。

例如:com....,则只能

一旦找到,就com...以下id是

的。

接口中的方法不能重载,因为它们是使用完全限定名称+方法名称来保存和检索的。

寻找策略。 接口的工作原理是JDK动态代理,在运行时会使用JDK。

动态代理为接口生成一个代理对象proxy。 代理对象拦截接口方法并改为

执行代表的sql,然后返回sql执行结果。

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

使用对象进行分页,分页是在结果集上执行的

存储页,不是物理页。可以直接在sql中写入带有物理分页的参数来完成物理分页。

寻呼功能,还可以使用寻呼插件完成物理寻呼。

分页插件的基本原理是利用提供的插件接口来实现自定义插件。

在拦截方法中拦截要执行的sql,然后重写sql,根据方言添加对应的对象

管理寻呼语句和物理寻呼参数。

11、如何将SQL执行结果封装成目标对象并返回?

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

拍摄关系。

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

有了列名和属性名的映射关系后,通过反射创建对象,并利用反射来

对象的属性一一赋值并返回。 对于那些找不到映射关系的属性,无法完成赋值。

12、如何批量插入?

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

<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、如何获取自动生成的(主)键值?

该方法始终返回一个 int 值,该值表示插入的行数。

如果采用自增策略,则该方法执行后可以将自动生成的键值设置为传入的键值。

在参数对象中。

<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.如何传入多个参数?

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  
```java  
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.动态sql有什么用? 执行原理? 动态sql有哪些?

动态sql可以以标签的形式写在Xml映射文件中。 执行原理

它是根据表达式的值完成逻辑判断并动态拼接SQL的函数。

提供9个动态sql标签:trim | 哪里 | 集| | 如果|

| 当 | | 绑定。

16.除了常见的||updae| tag,Xml映射文件中还有哪些其他标签?

,,,,

,加上动态sql的9个标签,其中有sql片段标签,通过

标签引入sql片段,为不支持自增的主键生成策略标签。

符号。

Xml映射文件中,ID可以在不同的Xml映射文件中重复吗?

不同的Xml映射文件,如果配置的话,id可以重复; 如果没有配置

set,则id不能重复;

原因是+id是Map的key

用过,如果没有,就只剩下id了。 那么,重复的 id 就会导致数据互相覆盖。

同,自然id可以重复,不同,+id是自然

这不一样。

18.为什么叫半自动ORM映射工具? 它和全自动有什么区别?

它是一个全自动的 ORM 映射工具,使用查询相关对象或关联

收集对象时,可以根据对象关系模型直接获取,因此是全自动的。

查询相关对象或者相关集合对象时,需要手动编写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. 实现一对一的方式有多少种? 具体是如何运作的呢?

有联合查询和嵌套查询。 联合查询是多个表的联合查询。 仅查询一次。 经过

里面的配置节点配置可以通过配置一对一的类来完成;

嵌套查询是先查一张表,然后根据这张表中结果的外键id去往另一张表。

查询数据也是通过配置,但是查询另一个表是通过属性配置。

21. 实现一对多有几种方法,它们是如何操作的?

有联合查询和嵌套查询。联合查询是几个表的联合查询。 仅查询一次。 经过

可以通过为里面的节点配置一对多的类来完成; 嵌套查询是先检查

一个表,根据这个表结果的外键id,去查询另一个表的数据也是通过

配置,但是另一个表的查询是通过节点配置的。

sql模糊查询like变量_sql模糊查询like怎么用_模糊查询like的用法

22.支持延迟加载吗? 如果支持,其实现原理是什么?

答:仅支持延迟添加关联对象和关联集合对象。

set指的是一对一查询,set指的是一对多查询。存在

在配置文件中可以配置是否启用延迟加载=true|false。

它的原理是利用CGLIB创建目标对象的代理对象。 当调用目标方法时,就会进入该块。

拦截器方法,比如调用a.getB().(),()方法发现a.getB()是

null 值,则将单独发送与 B 对象关联的预先保存的 SQL 查询,并上传 B 查询。

然后调用a.setB(b),这样a的对象b属性就有值了,然后完成a.getB().()

方法调用。 这就是延迟加载的基本原理。

当然不仅如此,几乎所有支持延迟加载的原理都包括

一样的。

23、一级、二级缓存:

1)一级缓存:基于本地缓存,其存储范围为

,在flush或者close之后,所有的缓存在

会被清除,并且默认开启一级缓存。

2)二级缓存与一级缓存机制相同,默认采用。

存储,不同的是它的存储范围是(),并且存储源可以自定义,

比如,二级缓存默认是不开启的。 要启用二级缓存,需要使用二级缓存属性类。

实现序列化接口(可用于保存对象的状态),可以在其映射文件中进行配置

;

3)对于缓存数据更新机制,当一定范围(一级缓存/二级缓存)

),默认情况下该范围内的所有缓存都会

被清除。

24.什么是接口绑定? 实施方法有哪些?

接口绑定就是在接口中任意定义一个接口,然后将接口中的方法绑定到SQL语句上。

确定我们可以直接调用接口方法了。 这样,与原来提供的方法相比,我们可以

拥有更灵活的选择和设置。

有两种方法可以实现接口绑定。 一种是通过注解绑定,也就是添加

@、@等注解包含用于绑定的Sql语句; 另一种是通过xml

在里面写SQL进行绑定。 此时,您需要在xml映射文件中指定所需的内容。

是接口的全路径名。当SQL语句比较简单时,使用注解绑定。 当SQL语句比较复杂时,使用注解绑定。

有时,xml用于绑定。 一般情况下,使用xml进行绑定的情况比较多。

25、调用所使用的接口有什么要求?

1、接口方法名与.xml中定义的每个sql的id相同;

2、.xml中定义的接口方法的入参类型和各sql

同一类型;

3、接口方法的输出参数类型以及.xml中定义的各个sql

同一类型;

4. .xml文件中的是接口的类路径。

27、简述插件的工作原理以及如何编写插件。

你只能写给,,

,这四个接口的插件使用JDK的动态代码

处理,为需要拦截的接口生成代理对象,实现接口方法拦截功能,每当执行这4种类型时

接口对象的方法,就会进入拦截方法,具体是()

当然,方法只会拦截您指定拦截的那些方法。

标签: 映射 接口 语句

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码