MyBatis的目录
- 1、什么是MyBatis?
- 2、MyBatis的优点:
- 3、MyBatis的缺点
- 4、MyBatis框架适用场合
- 5、MyBatis和Hibernate有什么不同
- 6.#{}和${}的区别是什么?
- 7.实体类中属性名和表中字段名不一致,怎么处理?
- 8、模糊查询like语句怎么写?
- 9、MyBatis是如何分页的,分页插件的原理是什么?
- 10、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
- 11、如何执行批量插入
- 12、在mapper中如何传递多个参数
- 13、什么是MyBatis动态SQL?
- 14、MyBatis动态SQL有哪些常用的标签和功能?
- 15、MyBatis一对一、一对多查询如何实现?
- 16、Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?
- 17、mybatis支持缓存吗,有几级缓存,
- 18、什么是 MyBatis 的接口绑定?有哪些实现方式?
- 19、使用MyBatis的mapper接口调用要求有哪些?
- 20、MyBatis的工作原理是什么?执行流程是什么?
- 21、如何使用动态SQL来构建动态查询语句?
- 22、MyBatis中的ResultMap和ResultType有什么区别?
- 23、MyBatis中的插件是什么?如何编写和配置一个自定义的插件?
- 24、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的常用注解有哪些?请举例说明如何使用它们。
@Mapper
public 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); }