MyBatis-面试题

1、什么是MyBatis?

半orm框架,内部封装了jdbc,开发时不需要关注数据库的加载驱动,创建连接,等等其他复杂过程,
只需要关注sql语句本身,编写原生态sql,执行即可。
可以使用xml文件,把实体的变量映射成数据库的记录。
通过xml文件,java对象和sql语句的参数及进行映射生成最终要执行的sql语句,
由mybatis执行sql,将结果映射成java对象返回。

2、MyBatis的优点:

​ 1、sql写在xml里,解除sql与程序代码的耦合,方便管理。

​ 2、比jdbc减少了代码量,不需要手动开关连接。

​ 3、兼容各种数据库。

​ 4、提供映射标签,支持对象与数据库字典关系映射。

3、MyBatis的缺点

​ 1、sql语句编写工作量较大,字段多,关联表多的时候,比较复杂。

​ 2、sql语句依赖于数据库,移植性差,不能随意更换数据库。

4、MyBatis框架适用场合

​ MyBatis 专注于 SQL 本身,是一个足够灵活的 DAO 层解决方案。

对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis 将是不错的选择。

5、MyBatis和Hibernate有什么不同

​ Mybatis允许开发人员直接编写sql语句, 可以在xml文件中配置。更加灵活,但是开发人员要有较强的sql技能,mybatis同时提供了两级缓存,可以在同一个sqlSession中缓存数据,。

​ Hibernate更注重于面向对象的操作,提供了多种映射方式,包括注解和xml配置,可以在运行时动态生成sql。Hibernate支持懒加载,有助于提高性能。

​ MyBatis适用于对sql语句要求较高的项目,Hibernate适用于需要面向对象操作的项目。

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

​ #{} 是预编译处理,可以自动进行参数类型转换和安全性校验,防止sql注入。

​ ${} 是一个字符串替换的占位符,将占位符替换成对应的属性值,但是没有预编译和安全性校验。

尽量使用#{}占位符,除非需要进行动态sql语句拼接或者字符串替换的情况下使用${}占位符。

7.实体类中属性名和表中字段名不一致,怎么处理?

​ 1、使用ResultMap进行映射.

select user_name, user_age from user where user_id=#{userId}

​ 2、在SQL语句中使用别名,将表中的字段名用AS关键字重新命名为实体类中的属性名。

select user_name as userName, user_age as userAge from user where user_id=#{userId}

8、模糊查询like语句怎么写?

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

9、MyBatis是如何分页的,分页插件的原理是什么?

​ Mybatis使用RowBounds对象进行分页,针对ResultSet结果集执行的内存分页,非物理分页。可以在sql内直接书写带有物理分页的参数完成物理分页功能,也可以使用分页插件。

(1)使用RowBounds分页。

	int pageNum = 2; // 查询第2页
	int pageSize = 10; // 每页10条记录
	// 使用RowBounds对象进行分页查询
	RowBounds rowBounds = new RowBounds((pageNum - 1) * pageSize, pageSize);
	List<User> userList = sqlSession.selectList("getUserList", null, rowBounds);

RowBounds的第一个参数表示查询的起始位置,第二个参数表示查询的记录数。

​ 2、使用PageHelper插件进行分页。

int pageNum = 2; // 查询第2页
int pageSize = 10; // 每页10条记录

// 使用PageHelper插件进行分页查询
PageHelper.startPage(pageNum, pageSize);
List<User> userList = sqlSession.selectList("getUserList");

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

​ 1、使用标签,逐个定义数据库列名和对象属性名映射。

<select id="getUserById" resultMap="userResultMap">  SELECT id, name, age, email FROM user WHERE id = #{id} </select>

​ 2、使用sql列别名,

SELECT id, name AS userName, age, email FROM user WHERE id = #{id}

11、如何执行批量插入

SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); 

try {    

// 获取 Mapper 接口    

YourMapper yourMapper = sqlSession.getMapper(YourMapper.class);        

// 构建对象列表    
List<YourObject> objectList = new ArrayList<>();    
objectList.add(new YourObject(...));   

 objectList.add(new YourObject(...));    

objectList.add(new YourObject(...));        

// 执行批量插入    
for (YourObject object : objectList) {        		
	yourMapper.insertObject(object);    
}    
sqlSession.commit();
 } finally {    
 		sqlSession.close(); 
 		}

定义一个Mapper接口

public interface YourMapper {
    void insertObject(YourObject object);
}

xml实现:

<insert id="insertObject" parameterType="YourObject">
    INSERT INTO your_table (column1, column2, column3)
    VALUES (#{column1}, #{column2}, #{column3})
</insert>

12、在mapper中如何传递多个参数

1、dao层传参,xml用#{}接收。0代表第一个,以此类推。

public UserselectUser(String name,String area);
<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:

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

select id, username, hashedpassword

from some_table

where username = #{username}

and hashedpassword = #{hashedpassword}

</select>

3、多个参数封装成map

Map < String, Object > map = new HashMap();
​		map.put("start", start);
​		map.put("end", end);return sqlSession.selectList("StudentID.pagination", map);

13、什么是MyBatis动态SQL?

​ 根据不同的条件生成不同的SQL语句,以满足不同的需求。可以在 Xml 映射文件内,以标签的形式编写动态 sql,执行原理

是根据表达式的值 完成逻辑判断并动态拼接 sql 的功能。

14、MyBatis动态SQL有哪些常用的标签和功能?

标签功能
if条件判断
choose/when/otherwise多条件判断
trim修剪sql语句,删除前后缀,逗号等
where拼接where语句
set用于update
foreach循环
bind绑定变量
sql定义可重用的sql语句,可在其他sql中使用。

15、MyBatis一对一、一对多查询如何实现?

一对一

​ 1、创建Student,Class类,添加关联

public class Class {   

 	private Integer id;   

 	private String username; 

    private String password;   

    private Student student;     

 } 
public class Student{    
	
	private Integer id;    
	
	private String name ;
	
	private int age;    
	
	private Class class;      
	}

2、创建Mapper接口,定义查询方法。

public interface StudentMapper {    
	StudentgetStudentWithClass(Integer id); 
	}

3.配置xml

<resultMap id="studentResultMap" type="Student">
  <id property="id" column="student_id" />
  <result property="name" column="student_name" />
  <result property="age" column="student_age" />
  <association property="class" javaType="Class">
    <id property="id" column="class_id" />
    <result property="name" column="class_name" />
  </association>
</resultMap>

编写查询语句

<select id="StudentMapper" resultMap="studentResultMap">
  SELECT s.id AS student_id, s.name AS student_name, s.age AS student_age, 
         c.id AS class_id, c.name AS class_name 
  FROM student s 
  JOIN class c ON s.class_id = c.id 
  WHERE s.id = #{id}
</select>

16、Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?

​ 支持延迟加载(懒加载)。在需要某些数据时才加载,而不是查询时立即加载所有数据。多表关联查询支持,单表不支持。

17、mybatis支持缓存吗,有几级缓存,

​ MyBatis支持缓存,提供了两级缓存“

​ 一级缓存: MyBatis默认开启的,程序调用SqlSession的查询方法,MyBatis会在当前线程池创建一个SqlSession对象,在对象中创建一个本地缓存。执行查询时,先查缓存,没有结果再执行sql查数据库,查完结果同样会缓存到本地。

​ 二级缓存:可以被多个SqlSession共享,当应用程序调用 SqlSession 的查询方法时,MyBatis 会先查看二级缓存中是否有相应的结果,如果有,则直接返回缓存中的结果;如果没有,则执行 SQL 语句查询数据库,并将查询结果存储到二级缓存中。

​ 二级缓存是可以选择开启或关闭的:

SELECT * FROM user WHERE id = #{id}

如果在执行 SQL 语句的过程中发生了更新操作(如 INSERT、UPDATE、DELETE),则缓存会被清空,下一次查询时会重新执行 SQL 语句。

18、什么是 MyBatis 的接口绑定?有哪些实现方式?

​ 接口绑定就是实现接口和SQL语句的关联。

实现方式:

​ 1、xml映射文件。

接口:

public interface UserMapper {User getUserById(int id);}

xml:

<mapper namespace="com.example.UserMapper">    		
		<select id="getUserById" resultType="com.example.User"> 
		SELECT * FROM 	users WHERE id = #{id}    
		</select> 
	</mapper>

​ 2、注解方式:

接口:

public interface UserMapper {    
	@Select("SELECT * FROM users WHERE id = #{id}")    
	User getUserById(int id); 
	}

调用:

​ userMapper.getUserById(1);

19、使用MyBatis的mapper接口调用要求有哪些?

​ 1、Mapper接口方法名和xml中定义的sql的id相同。

​ 2、Mapper接口方法的入参类型和xml的parameterType类型相同

​ 3、Mapper接口方法的出参类型和xml的resultType类型相同。

20、MyBatis的工作原理是什么?执行流程是什么?

1、加载配置文件:MyBatis通过读取配置文件(mybatis-config.xml)来获取全局配置信息,包括数据库连接信息、缓存配置、插件配置等。

2、创建SqlSessionFactory:根据配置文件中的信息,MyBatis会创建一个SqlSessionFactory对象。SqlSessionFactory是MyBatis的核心对象,负责创建SqlSession对象。

3、创建SqlSession:通过SqlSessionFactory,MyBatis会创建一个SqlSession对象。SqlSession是与数据库交互的会话,可以用于执行SQL语句、提交事务、获取映射器等操作。

4、加载映射器:MyBatis会加载映射器(Mapper)接口,映射器接口定义了数据库操作的方法。

5、执行SQL操作:当调用映射器接口的方法时,MyBatis会根据方法名找到对应的SQL语句,然后使用参数执行该SQL语句。MyBatis支持多种方式定义SQL语句,包括XML映射文件和注解。

6、处理结果映射:执行SQL语句后,MyBatis会将数据库返回的结果映射到映射器接口方法的返回值或参数中。MyBatis支持将结果映射为Java对象、集合或其他复杂结构。

7、提交事务:如果开启了事务管理,MyBatis会在合适的时机提交事务,确保数据的一致性。

21、如何使用动态SQL来构建动态查询语句?

​ 1、if

<select id="getUserList" parameterType="User" resultType="User">  SELECT * FROM users  WHERE 1=1  <if test="id != null">    AND id = #{id}  </if>  <if test="username != null">    AND username = #{username}  </if> </select>

​ 2、choose、when、otherwise

<select id="getUserList" parameterType="User" resultType="User">
  SELECT * FROM users
  WHERE 1=1
  <choose>
    <when test="id != null">
      AND id = #{id}
    </when>
    <when test="username != null">
      AND username = #{username}
    </when>
    <otherwise>
      AND status = 'ACTIVE'
    </otherwise>
  </choose>
</select>

​ 3、foreach

<select id="getUserList" parameterType="List" resultType="User">
  SELECT * FROM users
  WHERE id IN
  <foreach collection="ids" item="id" separator="," open="(" close=")">
    #{id}
  </foreach>
</select>			

22、MyBatis中的ResultMap和ResultType有什么区别?

​ ResultMap: 通常处理复杂查询,设计多个结果列,关联对象,嵌套对象等。

ResultType: 用于指定查询结果的目标类型,java类(User,Class等),也可以指定基本类型。类似于String,Int等等。

23、MyBatis中的插件是什么?如何编写和配置一个自定义的插件?

24、MyBatis的常用注解有哪些?请举例说明如何使用它们。

@Mapperpublic interface userMapper;

​ @Mapper

public interface UserMapper{@Select("select * from user where id = #{id}")	
 		User getUserById(int id);
}

@Insert:用于执行插入操作的注解。

	@Mapper 
	public interface UserMapper {    
		@Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")    
		void insertUser(User user); }

@Update:用于执行更新操作的注解。

	@Mapper 
	public interface UserMapper {    
	@Update("UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}")    
	void updateUser(User user); }

@Delete:用于执行删除操作的注解。

	@Mapper 
	public interface UserMapper {    
	@Delete("DELETE FROM users WHERE id = #{id}")   
	 void deleteUser(int id); }

@ResultMap: 将查询结果映射到Java对象。

	@Mapper 
	public interface UserMapper {    
	@Select("SELECT * FROM users")   
 	@ResultMap("userMap")    
	List<User> getAllUsers();     
	@ResultMap("userMap")    
	User getUserById(int id); }

@Param:用于传递参数的注解,在SQL语句中引用参数。

	@Mapper public interface UserMapper {    
	@Select("SELECT * FROM users WHERE name = #{name} AND email = #{email}")    
User getUserByNameAndEmail(@Param("name") String name, @Param("email") String email); }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值