这里写目录标题
最近在面试,发现了许多自身的问题,第一就是sql,不论是经典的学生教师成绩课程表,还是员工工资部门表,经常被问到,找几篇专门的文章准备一下。
左连接,右连接,内连接,等等的sql
1.多表left join是会生成一张临时表,并返回给用户
2.where条件是针对最后生成的这张临时表进行过滤,过滤掉不符合where条件的记录,是真正的不符合就过滤掉。
3.on条件是对left join的右表进行条件过滤,但依然返回左表的所有行,右表中没有的补为NULL
4.on条件中如果有对左表的限制条件,无论条件真假,依然返回左表的所有行,但是会影响右表的匹配值。也就是说on中左表的限制条件只影响右表的匹配内容,不影响返回行数。
结论:
1.where条件中对左表限制,不能放到on后面
2.where条件中对右表限制,放到on后面,会有数据行数差异,比原来行数要多
什么是ORM?
Object Relation Mapping,对象关系映射。
对象指的是Java对象,关系指的是数据库中的关系模型,对象关系映射,指的就是在Java对象和数据库的关系模型之间建立一种对应关系,
比如用一个Java的Student类,去对应数据库中的一张student表,类中的属性和表中的列一一对应。Student类就对应student表,一个Student对象就对应student表中的一行数据.
为什么mybatis是半自动的ORM框架?
用mybatis进行开发,需要手动编写SQL语句。而全自动的ORM框架,如hibernate,则不需要编写SQL语句。用hibernate开发,只需要定义好ORM映射关系,就可以直接进行CRUD操作了。
由于mybatis需要手写SQL语句,所以它有较高的灵活性,可以根据需要,自由地对SQL进行定制,
也因为要手写SQL,当要切换数据库时,SQL语句可能就要重写,因为不同的数据库有不同的方言(Dialect),所以mybatis的数据库无关性低。
虽然mybatis需要手写SQL,但相比JDBC,它提供了输入映射和输出映射,可以很方便地进行SQL参数设置,以及结果集封装。并且还提供了关联查询和动态SQL等功能,极大地提升了开发的效率。并且它的学习成本也比hibernate低很多MyBatis是一个持久层ORM框架,底层是在JDBC的基础上进行了扩展和封装。
动态sql
<!-- 示例 -->
<select id="find" resultType="student" parameterType="student">
SELECT * FROM student WHERE age >= 18
<if test="name != null and name != ''">
AND name like '%${name}%'
</if>
</select>
JDBC
JDBC是Java提供的一个操作数据库的API。
我们平时使用jdbc进行编程,大致需要下面几个
步骤:
1,使用jdbc编程需要连接数据库,注册驱动和数据库信息;
2,操作Connection,打开Statement对象;
3,通过Statement对象执行SQL,返回结果到ResultSet对象;
4,使用ResultSet读取数据,然后通过代码转化为具体的POJO(Plain Old Java Objects,普通的Java对象)对象;
5,关闭数据库相关的资源。
jdbc的缺点:
1.工作量比较大,需要连接,然后处理jdbc底层事务,处理数据类型,还需要操作Connection,Statement对象和ResultSet对象去拿数据并关闭他们;
2.我们对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配置)(如果不为空或者null)
(5) mybatis可使用xml文件管理sql语句:使用JDBC对数据库进行操作时,sql语句在Java的各个类中。
(6) mybatis对数据库操作结果进行自动映射:在使用JDBC进行查询时,返回一个结果集ResultSet,我们要从结果集中取出结果封装为需要的类型;在Mybatis中可以设置将结果直接映射为自己需要的类型,比如:JavaBean对象、一个Map、一个List等等。
(7)一致的编码风格大大减少了代码的沟通交流成本。
缓存
一级缓存
默认开启,同一个SqlSesion级别共享的缓存,在一个SqlSession的生命周期内,执行2次相同的SQL查询,则第二次SQL查询会直接取缓存的数据,而不走数据库,当然,若第一次和第二次相同的SQL查询之间,执行了DML(INSERT/UPDATE/DELETE),则一级缓存会被清空,第二次查询相同SQL仍然会走数据库
一级缓存在下面情况会被清除
在同一个SqlSession下执行增删改操作时(不必提交),会清除一级缓存
SqlSession提交或关闭时(关闭时会自动提交),会清除一级缓存
对mapper.xml中的某个CRUD标签,设置属性flushCache=true,这样会导致该MappedStatement的一级缓存,二级缓存都失效(一个CRUD标签在mybatis中会被封装成一个MappedStatement)
在全局配置文件中设置 ,这样会使一级缓存失效,二级缓存不受影响
二级缓存
默认关闭,可通过全局配置文件中的开启二级缓存总开关,然后在某个具体的mapper.xml中增加,即开启了该mapper.xml的二级缓存。二级缓存是mapper级别的缓存,粒度比一级缓存大,多个SqlSession可以共享同一个mapper的二级缓存。注意开启二级缓存后,SqlSession需要提交,查询的数据才会被刷新到二级缓存当中