1.知识点
1、#{}和${}的区别是什么?
${}是字符串替换,#{}是预处理;使用#{}可以有效的防止SQL注入,提高系统安全性。
Mybatis在处理{}时,就是把{}直接替换成变量的值。
而Mybatis在处理#{}时,会对sql语句进行预处理,将sql中的#{}替换为?号,调PreparedStatement的set方法来赋值;
2.jdbc和nybatis的区别
JDBC是Java提供的一个操作数据库的API。
MyBatis是一个持久层ORM(对相映射关系)框架,底层是在JDBC的基础上进行了扩展和封装。
JDBC,MyBatis的区别:
1)从层次上看,JDBC是较底层的持久层操作方式,而MyBatis都是在JDBC的基础上进行了封装使其更加方便程序员对持久层的操作。
2)从功能上看,JDBC就是简单的建立数据库连接,然后创建statement,将sql语句传给statement去执行,如果是有返回结果的查询语句,会将查询结果放到ResultSet对象中,通过对ResultSet对象的遍历操作来获取数据;MyBatis是将sql语句中的输入参数和输出参数映射为java对象,sql修改和优化比较方便。
3)从使用上看,如果进行底层编程,而且对性能要求极高的话,应该采用JDBC的方式;如果要灵活使用sql语句的话建议采用MyBatis框架。
MyBatis相比JDBC的优势:
(1) mybatis使用已有的连接池管理,避免浪费资源,提高程序可靠性。
(2) mybatis提供插件自动生成DAO层代码,提高编码效率和准确性。
(3) mybatis 提供了一级和二级缓存(需要配置打开),提高了程序性能。
(4) mybatis使用动态SQL语句,提高了SQL维护。(此优势是基于XML配置)
(5) mybatis可使用配置文件管理sql语句:使用JDBC对数据库进行操作时,SQL查询语句分布在各个Java类中,这样可读性差,不利于维护,当我们修改Java类中的SQL语句时要重新进行编译;Mybatis可以把SQL语句放在配置文件中统一进行管理,以后修改配置文件就行,也不需要重新编译部署。
(5) mybatis对数据库操作结果进行自动映射:在使用JDBC进行查询时,返回一个结果集ResultSet,我们要从结果集中取出结果封装为需要的类型;在Mybatis中可以设置将结果直接映射为自己需要的类型,比如:JavaBean对象、一个Map、一个List等等。
(6)一致的编码风格大大减少了代码的沟通交流成本
3. MyBatis的逆向工程是什么?
逆向工程是指通过数据库表结构自动生成MyBatis的实体类、映射文件以及DAO接口,减少手动编写的工作量。
使用逆向工程工具如MyBatis Generator,可以根据数据库表结构生成对应的Java代码。
4.MyBatis的执行流程是什么?
MyBatis的执行流程主要包括:
加载配置文件:加载MyBatis的配置文件,初始化配置信息。
创建SqlSessionFactory:根据配置信息,创建SqlSessionFactory对象。
获取SqlSession:通过SqlSessionFactory对象获取SqlSession。
执行SQL:在SqlSession中执行SQL语句。
返回结果:获取SQL执行的结果。
5.MyBatis中的一级缓存和二级缓存有什么区别?
一级缓存是SqlSession级别的缓存,它在同一个SqlSession中有效,当SqlSession关闭或提交时,缓存失效。
二级缓存是Mapper级别的缓存,多个SqlSession可以共享二级缓存。在不同SqlSession中执行相同的SQL语句,可以共享查询结果。
6.MyBatis的延迟加载是什么?
延迟加载是指在需要使用数据时才真正去查询数据库,而不是立即加载所有关联数据。通过配置lazyLoadingEnabled实现延迟加载。
7.MyBatis 是如何进行分页的?分页插件的原理是什么?
1.MyBatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页;
2.MyBatis可以使用SQL语句中的LIMIT关键字实现简单的分页,但是对于大数据量的分页查询,需要使用更高效的方法。
3.MyBatis提供了一种基于拦截器的分页插件来优化分页查询。
分页插件的原理是在MyBatis执行SQL语句之前,对其进行拦截并修改SQL语句,从而实现分页查询的功能。具体步骤如下:
拦截器初始化:插件在MyBatis启动时进行初始化,创建拦截器对象并将其添加到MyBatis的拦截器链中。
拦截器拦截:当进行分页查询时,拦截器会拦截对应的SQL语句,并在其中添加分页的限制条件,例如使用LIMIT关键字进行分页。
执行SQL语句:修改后的SQL语句会被传递给MyBatis的执行器,执行器会将SQL语句发送到数据库进行查询,并返回查询结果。
封装查询结果:查询结果会被封装到MyBatis的结果对象中,并返回给调用方。
目前比较流行的MyBatis分页插件是PageHelper,其基于拦截器的原理,在拦截器中实现了分页查询的逻辑,并提供了丰富的配置选项和API,可以方便地实现各种复杂的分页查询需求。使用PageHelper进行分页查询的示例代码如下:
java
// 指定分页查询的页码和每页记录数
PageHelper.startPage(pageNum, pageSize);
// 执行查询操作,返回分页查询结果
List<User> userList = userDao.selectUserList();
// 封装分页查询结果
PageInfo<User> pageInfo = new PageInfo<>(userList);
在这段代码中,我们使用了PageHelper的startPage方法来指定分页查询的页码和每页记录数,然后执行普通的查询操作,PageHelper会自动拦截并修改SQL语句,实现分页查询的功能。最后,我们将查询结果封装到PageInfo对象中,以便进行分页信息的显示和处理。
2.项目遇到的问题
1.在用PageHelper进行条件分页查询时,书写mybatis动态sql时报错java.lang.NullPointerException
控制台报错:
UserMapper类中的内容:
UserMapper类对应的UserMapper.xml文件:
测试类:
UserController中的内容不再显示
不难看出:在UserMapper中的方法中,第二个参数sex为char类型,是不能为null的,应该改为Character,一个小小的不细心就会导致bug的出现
未完....