1. ORM框架的原理是什么?
ORM是对象-关系映射(Object-Relational Mapping,简称ORM)
它是java中持久层框架技术的一种实现思想,基于这种思想常见的框架有MyBatis、Hibernate等。其原理是建立java中类(实体类)和数据表之间的映射关系,然后通过反射的思想,动态获取类中的属性,此时属性对应了表中的列,所以能够动态产生JDBC代码从而达到操作数据库的目的。
2. 什么是DAO模式?
dao全称是data access object,数据库访问对象,主要的功能就是用于进行数据操作的,在程序的标准开发架构中属于数据层的操作
DAO组成
在整个DAO中实际上都是以接口为操作标准的,即:客户端依靠DAO实现的接口进行操作,而服务端要将接口进行具体的实现。DAO由以下几个部分组成。
1.DatabaseConnection:专门负责数据库的打开与关闭操作的类
2.VO:主要由属性、setter、getter方法组成,VO类中的属性与表中的字段相对应,每一个VO类的对象都表示表中的每一条记录;
3.DAO:主要定义操作的接口,定义一系列数据库的原子性操作,例如:增加、修改、删除、按ID查询等;
4.Impl : DAO接口的真实实现类,完成具体的数据库操作,但是不负责数据库的打开和关闭;
5 Proxy :代理实现类,主要完成数据库的打开和关闭,并且调用真实实现类对象的操作
6 Factory :工厂类,通过工厂类取得一个DAO的实例化对象
3. 举一个多对多关联的例子,并说明如何实现多对多关联映射。
例如:商品和订单、学生和课程都是典型的多对多关系。首先在数据库表中需要通过第三张关系表来进行数据的维护,该关系表中主要包含了两个外键。具体代码中实现根据框架的不同也有不同的实现方式,比如JPA中可以在实体类上通过@ManyToMany注解配置多对多关联或者通过映射文件中的和标签配置多对多关联,但是实际项目开发中,很多时候都是将多对多关联映射转换成两个多对一关联映射来实现的。
4. 谈一下你对继承映射的理解。
继承关系的映射策略有三种:
① 每个继承结构一张表(table per class hierarchy),不管多少个子类都用一张表。
② 每个子类一张表(table per subclass),公共信息放一张表,特有信息放单独的表。
③ 每个具体类一张表(table per concrete class),有多少个子类就有多少张表。
第一种方式属于单表策略,其优点在于查询子类对象的时候无需表连接,查询速度快,适合多态查询;缺点是可能导致表很大。后两种方式属于多表策略,其优点在于数据存储紧凑,其缺点是需要进行连接查询,不适合多态查询。
5. 什么是Hibernate,好处是什么?
1、Hibernate是一个基于ORM思想的操作数据库的框架技术,实现了对JDBC的封装;
2、Hibernate用的是面向对象的方法,但是在关系型数据库里,存的是一条条的记录;为了用纯面向对象的思想解决问题,所以需要将程序中的对象和数据库中的记录建立起映射关系,ORM就是将对象和数据库中的记录建立起映射的技术;
3、Hibernate通过方言来自动切换不同的数据库,无需在代码中编写;
4、使用Hibernate的基本流程是:配置Configuration对象、产生SessionFactory、创建session对象,启动事务,完成CRUD操作,提交事务,关闭session;
5、使用Hibernate时,先要配置hibernate.cfg.xml文件,其中配置数据库连接信息和方言等,还要为每个实体配置相应的hbm.xml文件,hibernate.cfg.xml文件中需要登记每个hbm.xml文件。
6. Hibernate的核心思想?
Hibernate是一个采用ORM(Object/Relation Mapping对象关系映射)机制持久层的开源框架其主要核心思想是面向对象,而非面向过程,而这个面向对象则主要通过ORM实现。
7. 什么是Mybatis?
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
8. MyBatis中使用#和$书写占位符有什么区别?
1.#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
2.$将传入的数据直接显示生成在sql中。
3.#方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象
6.一般能用#的就别用$
注意: 一般如果将表名、列名作为参数的动态功能操作时,必须使用$,而不能使用#。如MyBatis排序时使用order by 动态参数时需要使用$。
9. Hibernate 与 Mybatis区别(MyBatis与Hibernate有什么不同)。
相同点:
都是基于ORM思想的java持久层框架技术,都封装了JDBC实现数据库操作,提高了开发数据库编码的效率。
不同点:
1) Hibernate是一个全自动的orm映射工具,它可以自动生成sql语句;MyBatis需要我们自己在xml配置文件中写sql语句。因为hibernate自动生成sql语句,我们无法控制该语句,我们就无法去写特定的高效率的sql。对于一些不太复杂的sql查询,hibernate可以很好帮我们完成,但是,对于特别复杂的查询,hibernate就很难适应了,这时候用MyBatis就是不错的选择,因为MyBatis还是由我们自己写sql语句;
2) Mybatis比hibernate对存储过程的支持更好一些。
10. 持久层设计要考虑的问题有哪些?
所谓"持久"就是将数据保存到存储设备中以便今后使用,简单的说,就是将内存中的数据保存到关系型数据库、文件系统、消息队列等提供持久化支持的设备中。持久层就是系统中专注于实现数据持久化的相对独立的层面。
持久层设计的目标包括: - 数据存储逻辑的分离,提供抽象化的数据访问接口。
- 数据访问底层实现的分离,可以在不修改代码的情况下切换底层实现。
- 资源管理和调度的分离,在数据访问层实现统一的资源调度(如缓存机制)。
- 数据抽象,提供更面向对象的数据操作。
11. 你用过的持久层框架有哪些
持久层主要是负责将数据进行持久化,早期的JDBC代码太麻烦繁琐,所以出现了一系列基于ORM思想的持久层框架,我主要使用的是MyBatis框架,其他的比如Hibernate以及JPA有一些了解。
技巧:选自己最熟的持久化框架,说明其关键特点
12. @OneToMany注解的mappedBy属性有什么作用?
技巧:mappedBy 属性的主要作用是告诉hibernate关联关系是通过对方外键引用完成关联映射,这一点必须说清楚。One的一方会成为主控方,加入mappedBy以后,就不会生成这两张关联表的中间表了,而是在Many的一方的表中生成一列作为外键。
13. MyBatis中的动态SQL是什么意思?
MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,一般在我们的Mapper.xml映射文件中使用,MyBatis中用于实现动态SQL的标签元素主要有:
if
choose(when,otherwise)
trim
where
set
foreach
14. 如何解决 Mybatis “n+1”问题。
N+1问题主要是数据库表中的级联问题,就是在查询的时候使用了association或collection标签进行关联数据时,如果使用了嵌套的select方式,则会造成N+1的问题,解决方案是:
第一种方法是使用一条多表关联的SQL语句,一次性查询出需要的数据。
第二种方法是使用MyBatis的延迟加载机制,在具体使用到的时候再去加载数据。
15. Mybatis 动态SQL相关标签作用及含义?
1.MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。
2.MyBatis中用于实现动态SQL的元素主要有ifchoose(when,otherwise)trimwheresetforeach可以看出MyBatis的动态SQL的标签元素和接近JSP中的JSTL语法,下面我就分别详细的介绍一下
3.动态SQL中if的用法
4.动态SQL中choose用法
5.动态SQL中where语句的作用主要是简化SQL语句中where中的条件判断的注意: where元素的作用是给SQL语句添加一个条件判断. 如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上
6.动态SQL中set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的
7.动态SQL中foreach主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close
8.动态SQL中trim语句
16. 什么是JDBC,简述实现方法?
JDBC是java进行数据库操作时的技术统称,提供了很多操作接口,但是编写的代码非常繁琐麻烦,创建一个以JDBC连接数据库的程序,包含7个步骤:
1、加载JDBC驱动程序: Class.forName(“com.mysql.jdbc.Driver”)
2、提供JDBC连接的URL: “jdbc:mysql://localhost:3306/数据库名”
3、创建数据库的连接 Connection conn = DriverManager.getConnection(“URL”,”root”,”123456”)
4、创建一个执行sql命令的Statement对象 PreparedStatement pstmt = conn.prepareStatement(sql);
5、执行SQL语句 1)增删改 pstmt.executeUpdate() à返回int为影响的行数2)查询 pstmt.executeQuery()à返回ResultSet为查询的结果集
6、循环读取结果: while(rst.next())
7、关闭JDBC相关资源对象
17. 请介绍一下数据库连接池技术?
1)数据库连接池技术主要是提高应用程序和数据库交互时的性能问题,因为连接数据库是非常耗费资源的,如果每个操作都去频繁连接和断开,则会造成巨大的开销,连接池技术即在系统初始化时,就创建一系列的连接对象放入集合中管理,需要连接数据库时从连接池中取出使用,使用完毕归还给连接池,这样的目的是提高同一个连接的可重用性。
2)java中有很多连接池框架,比如dbcp、c3p0,我个人比较喜欢使用阿里的druid连接池,因为性能稳定,功能强大。注:一般项目使用时直接添加maven引用
18. MySQL、Oracle、SQL Server各数据库服务的默认端口号?
1、MySQL:3306
2、Oracle:1521
3、SQL Server:14331
19. MyBatis中如何实现分页?
分页的目的是减少一次性查询出数据的额外开销,提高应用的性能。Mybatis中可以使用如下几种方案:
1、 sql语句分页,利用传递的页码和每页显示数,使用limit分页
2、 采用mybatis拦截器插件实现分页
20. MyBatis中如何实现数据映射?
Mybatis要求我们自己完成查询sql语句,然后对查询的类进行映射,默认情况下如果类和实体属性一致,则可以直接使用reusltType进行关联映射,如果不一致,则需要自定义resultMap进行映射说明。当然如果数据库列是下划线,而java中是驼峰命名,则可以在mybatis主配置中添加驼峰命名的全局setting配置即可。
21. MyBatis中的缓存如何使用?
1) 缓存是为了提高程序的性能,把从数据库中查询出来和使用过的对象保存在内存中,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。
2) Mybatis中有一级缓存和二级缓存,其中一级缓存是SqlSession级别的缓存,在同一个SqlSession操作时都会默认使用,当会话关闭则会自动清空无法使用。二级缓存是Mapper级别的缓存,需要在主配置中声明开启,然后在Mapper.xml中使用<cache>标签声明后才能使用。
3) 缓存使用时需要注意,经常修改和准确度要求很高的数据不适合放入缓存中,因为很容易产生脏数据,从而造成程序中的数据不准确。
22. MyBatis中的使用流程?
1) 首先项目中加入mybatis的依赖,如maven的pom.xml中添加
2) 创建并修改mybatis-config.xml核心配置文件(配置全局属性、别名、数据库连接、注册的Mapepr等)
3) 创建实体类和数据表映射
4) 创建功能操作接口,完成抽象方法
5) 针对抽象方法完成对应的Mapper.xml中的映射或者使用注解实现
6) 运行时加载配置,产生SqlSessionFactory对象,然后调用openSession方法获取SqlSession,然后拿到Mappper接口代理对象,调用方法完成操作。
7) 关闭会话
23. MyBatis中的关联如何实现?
1) 一般使用< association>标签进行一对一的对象关联映射
2) 使用< collection>标签进行一对多的集合关联映射具体映射时候可以采用一次性查询出结果(推荐)然后映射,也可以采用嵌套的select查询方式。
24. MyBatis中的插件如何实现?
插件也可以理解为拦截器,即在mybatis执行某个sql语句或者结果处理前后,均可以自己编写代码进行额外的操作,Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件。Mybatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke()方法,只会拦截那些你指定需要拦截的方法,具体使用时还需要在拦截器类上进行签名以及在主配置文件中声明才能使用。
25. 请描述MyBatis中的优缺点?
1) MyBatis的优点:屏蔽jdbc api的底层访问细节;自己定制sql能自定义映射,和将sql语句与java代码进行分离;提供了将结果集自动封装称为实体对象和对象的集合的功能,queryForList返回对象集合,用queryForObject返回单个对象;提供了自动将实体对象的属性传递给sql语句的参数。其次mybatis很好的跟spring集成。
2) Mybatis的缺点:SQL 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL 语句的功底有一定要求,SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
26. 请描述MyBatis如何进行批量操作?
mybatis中提供了<foreach>标签,可以对集合、数组进行循环,从而实现动态的批量操作
27. 请描述MyBatis如何获取自增的主键值?
Mybatis中可以在<insert>标签中添加usegeneratedkeys=”true” keyproperty=”id”属性获取自增后的主键值,比如增加操作时传入的实体对象没有id,调用带有该属性的增加操作后,则会将自增主键放入实体对象中。
也可以在<insert>标签中使用<selectKey>标签查询获取自增主键列数据。
28. 请描述MyBatis的Mapper功能方法如何传递多个参数?
Mybatis如果参数是一个,或者实体对象,则直接可以使用#{名称或属性}取出对应的数据,那么如果不是实体对象,但是有多个参数,实现如下:1) 使用Map集合封装传递的多个参数,因为map有键作为名称。2) 使用@Param注解实现参数名的标注。 28. Hibernate如何实现分页查询?技巧:hibernate 实现分页的关键是通过方言的方式隔离数据差异,在分页处理上,由于各种数据库处理差异很大,未在hql中实现相应关键字,是利用查询接口两个关键方法完成(setFirstResult,setMaxResult),说明这两个方法是关键。说明之后,可根据场景使用代码示例,进一步可阐述分页实现原理。Hibernate 实现分页查询的关键 是两个方法 setFirstResult: 设置第一数据开始位置setMaxResult :设置查询总记录数 29. @OneToMany注解的mappedBy属性有什么作用?技巧:mappedBy 属性的主要作用是告诉hibernate关联关系是通过对方外键引用完成关联映射,这一点必须说清楚。One的一方会成为主控方,加入mappedBy以后,就不会生成这两张关联表的中间表了,而是在Many的一方的表中生成一列作为外键。 30. MyBatis中的动态SQL是什么意思?MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。
MyBatis中用于实现动态SQL的元素主要有:
if
choose(when,otherwise)
trim
where
set
foreach
29. hibernate中的update()和saveOrUpdate()的区别
1、update针对的是已存在的实体对象,数据库中如果没有实体所对应的数据记录,将会抛出异常;
2、saveOrUpdate()对象存在与否都不会有任何影响,有则更新,没则插入。
30. hibernate中对象的三种状态?
1、瞬时态:用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;
2、持久态:已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;
3、游离态(托管态): 持久化对象脱离了Session的对象。如Session缓存被清空的对象。特点:已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象;
31. 如何理解Hibernate的延迟加载机制?在实际应用中,延迟加载与Session关闭的矛盾是如何处理。
延迟加载就是并不是在读取的时候就把数据加载进来,而是等到使用时再加载。Hibernate使用了虚拟代理机制实现延迟加载,我们使用Session的load()方法加载数据或者一对多关联映射在使用延迟加载的情况下从一的一方加载多的一方,得到的都是虚拟代理,简单的说返回给用户的并不是实体本身,而是实体对象的代理。代理对象在用户调用getter方法时才会去数据库加载数据。但加载数据就需要数据库连接。而当我们把会话关闭时,数据库连接就同时关闭了。
延迟加载与session关闭的矛盾一般可以这样处理:
① 关闭延迟加载特性。这种方式操作起来比较简单,因为Hibernate的延迟加载特性是可以通过映射文件或者注解进行配置的,但这种解决方案存在明显的缺陷。首先,出现"no session or session was closed"通常说明系统中已经存在主外键关联,如果去掉延迟加载的话,每次查询的开销都会变得很大。
② 在session关闭之前先获取需要查询的数据,可以使用工具方法Hibernate.isInitialized()判断对象是否被加载,如果没有被加载则可以使用Hibernate.initialize()方法加载对象。
③ 使用拦截器或过滤器延长Session的生命周期直到视图获得数据。Spring整合Hibernate提供的OpenSessionInViewFilter和OpenSessionInViewInterceptor就是这种做法。
32. session的load()和get()的区别?
1、get()采用立即加载方式;而load()采用延迟加载;
2、get()方法执行的时候,会立即向数据库发出查询语句,而load()方法返回的是一个代理(此代理中只有一个id属性),只有等真正使用该对象属性的时候,才会发出sql语句;
3、如果数据库中没有对应的记录,get()方法返回的是null。而load()方法出现异常ObjectNotFoundException 。
33. 介绍一下Hibernate的二级缓存。
1、按照以下思路来回答:(1)首先说清楚什么是缓存,(2)再说有了hibernate的Session就是一级缓存,即有了一级缓存,为什么还要有二级缓存,(3)最后再说如何配置Hibernate的二级缓存。
2.1、缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。
2.2、Hibernate中Session内置了一种缓存,我们通常将之称为Hibernate的一级缓存(Session级别的),当想使用session从数据库中查询出一个对象时,Session也是先从自己内部查看是否存在这个对象,存在则直接返回,不存在才去访问数据库,并将查询的结果保存在自己内部。由于Session代表一次会话过程,一个Session与一个数据库连接相关连,所以Session最好不要长时间保持打开,通常仅用于一个事务当中,在事务结束时就应关闭。
2.3、二级缓存是SessionFactory级别的缓存,能被此SessionFactory里的所有Session共享。多个厂商和组织都提供有缓存产品,例如,EHCache和OSCache等等。在Hibernate中使用二级缓存,首先就要在hibernate.cfg.xml配置文件中配置使用哪个厂家的缓存产品,接着需要配置该缓存产品自己的配置文件,最后要配置Hibernate中的哪些实体对象要纳入到二级缓存的管理中。
34. 谈一谈Hibernate的一级缓存、二级缓存和查询缓存?
Hibernate的Session提供了一级缓存的功能,默认总是有效的,当应用程序保存持久化实体、修改持久化实体时,Session并不会立即把这种改变提交到数据库,而是缓存在当前的Session中,除非显示调用了Session的flush()方法或通过close()方法关闭Session。通过一级缓存,可以减少程序与数据库的交互,从而提高数据库访问性能。
SessionFactory级别的二级缓存是全局性的,所有的Session可以共享这个二级缓存。不过二级缓存默认是关闭的,需要显示开启并指定需要使用哪种二级缓存实现类(可以使用第三方提供的实现)。一旦开启了二级缓存并设置了需要使用二级缓存的实体类,SessionFactory就会缓存访问过的该实体类的每个对象,除非缓存的数据超出了指定的缓存空间。
一级缓存和二级缓存都是对整个实体进行缓存,不会缓存普通属性,如果希望对普通属性进行缓存,可以使用查询缓存。查询缓存是将HQL或SQL语句以及它们的查询结果作为键值对进行缓存,对于同样的查询可以直接从缓存中获取数据。查询缓存默认也是关闭的,需要显示开启。
35. 简述Hibernate常见优化策略?
① 制定合理的缓存策略(二级缓存、查询缓存)。
② 采用合理的Session管理机制。
③ 尽量使用延迟加载特性。
④ 设定合理的批处理参数。
⑤ 如果可以,选用UUID作为主键生成器。
⑥ 如果可以,选用基于版本号的乐观锁替代悲观锁。
⑦ 在开发过程中, 开启hibernate.show_sql选项查看生成的SQL,从而了解底层的状况;开发完成后关闭此选项。
⑧ 考虑数据库本身的优化,合理的索引、恰当的数据分区策略等都会对持久层的性能带来可观的提升,但这些需要专业的DBA(数据库管理员)提供支持。
36. 锁机制有什么用?简述Hibernate的悲观锁和乐观锁机制。
有些业务逻辑在执行过程中要求对数据进行排他性的访问,于是需要通过一些机制保证在此过程中数据被锁住不会被外界修改,这就是所谓的锁机制。
Hibernate支持悲观锁和乐观锁两种锁机制。悲观锁,顾名思义悲观的认为在数据处理过程中极有可能存在修改数据的并发事务(包括本系统的其他事务或来自外部系统的事务),于是将处理的数据设置为锁定状态。悲观锁必须依赖数据库本身的锁机制才能真正保证数据访问的排他性。乐观锁,顾名思义,对并发事务持乐观态度(认为对数据的并发操作不会经常性的发生),通过更加宽松的锁机制来解决由于悲观锁排他性的数据访问对系统性能造成的严重影响。最常见的乐观锁是通过数据版本标识来实现的,读取数据时获得数据的版本号,更新数据时将此版本号加1,然后和数据库表对应记录的当前版本号进行比较,如果提交的数据版本号大于数据库中此记录的当前版本号则更新数据,否则认为是过期数据无法更新。Hibernate中通过Session的get()和load()方法从数据库中加载对象时可以通过参数指定使用悲观锁;而乐观锁可以通过给实体类加整型的版本字段再通过XML或@Version注解进行配置。
37. 阐述Session加载实体对象的过程。
Session加载实体对象的步骤是:
① Session在调用数据库查询功能之前,首先会在一级缓存中通过实体类型和主键进行查找,如果一级缓存查找命中且数据状态合法,则直接返回;
② 如果一级缓存没有命中,接下来Session会在当前NonExists记录(相当于一个查询黑名单,如果出现重复的无效查询可以迅速做出判断,从而提升性能)中进行查找,如果NonExists中存在同样的查询条件,则返回null;
③ 如果一级缓存查询失败则查询二级缓存,如果二级缓存命中则直接返回;
④ 如果之前的查询都未命中,则发出SQL语句,如果查询未发现对应记录则将此次查询添加到Session的NonExists中加以记录,并返回null;
⑤ 根据映射配置和SQL语句得到ResultSet,并创建对应的实体对象;
⑥ 将对象纳入Session(一级缓存)的管理;
⑦ 如果有对应的拦截器,则执行拦截器的onLoad方法;
⑧ 如果开启并设置了要使用二级缓存,则将数据对象纳入二级缓存;
⑨ 返回数据对象。
38. 描述Hibernate 对象状态转换过程。
瞬时状态 (Transient)
持久状态 (Persistent)
脱管状态 (Detached)
Save() 方法将瞬时对象保存到数据库,对象的临时状态将变为持久化状态。当对象在持久化状态时,它一直位于 Session 的缓存中,对它的任何操作在事务提交时都将同步到数据库,因此,对一个已经持久的对象调用 save()或 update() 方法是没有意义的。
update() 方法两种用途重新关联脱管对象为持久化状态对象,显示调用 update() 以更新对象。调用 update() 只为了关联一个脱管对象到持久状态,当对象已经是持久状态时,调用 update() 就没有多大意义了。
saveOrUpdate() 方法兼具 save() 和 update() 方法的功能,对于传入的对象, saveOrUpdate() 首先判断其是脱管对象还是临时对象,然后调用合适的方法。
39. 如何解决hibernate “N+1”问题。
1.延迟加载,当需要的时候才查询,不需要就不查询,但是感觉这种方式治标不治本,尤其是在那种报表统计查询的时候更为明显。
2.fetch="join",默认是fetch="select",这个其实说白了就是一个做外连接,允许外键为空的情况之下。
3.二级缓存,第一次查询之后存在内存中,后面的相同查询就快了。但是有2个缺点:a.二级缓存首先是有点浪费内存空间,如果多了的话浪费还比较严重,这是一个不好的方面,当然这不是主要的,主要的问题在于,二级缓存的特性决定的,那就是很少的增删改才做二级缓存,而对于普通的CRUD系统,其实不太适合。所以感觉也不是首选。
39. 如何解决 Mybatis “n+1”问题。
第一种方法是使用一条SQL语句。
第二种方法是使用MyBatis的延迟加载机制。
40. Mybatis 动态SQL相关标签作用及含义?
1.MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。
2.MyBatis中用于实现动态SQL的元素主要有
if
choose(when,otherwise)
trim
where
set
foreach
可以看出MyBatis的动态SQL的标签元素和接近JSP中的JSTL语法,下面我就分别详细的介绍一下
3.动态SQL中if的用法
4.动态SQL中choose用法
5.动态SQL中where语句的作用主要是简化SQL语句中where中的条件判断的注意: where元素的作用是给SQL语句添加一个条件判断. 如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上
6.动态SQL中set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的
7.动态SQL中foreach主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close
8.动态SQL中trim语句
41. 什么是JDBC,简述实现方法?
创建一个以JDBC连接数据库的程序,包含7个步骤:
1、加载JDBC驱动程序: Class.forName(“com.mysql.jdbc.Driver”)
2、提供JDBC连接的URL “jdbc:mysql://localhost:3306/数据库名”
3、创建数据库的连接 Connection conn = DriverManager.getConnection(“URL”,”root”,”123456”)
4、创建一个Statement PreparedStatement pstmt = conn.prepareStatement(sql);
5、执行SQL语句 增删改 pstmt.executeUpdate() àint 查询 pstmt.executeQuery()àResultSet
6、处理结果 while(rst.next())
7、关闭JDBC对象
42. 什么是事务?
1、事务是一系列的数据库操作,是数据库应用的基本逻辑单位,事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。
2、事务具有如下特性:(其中原子性最为重要,必须掌握)
l原子性(atomicity) 一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency) 事务必须是使数据库从一个一致性状态变到另一个一致性状态。
隔离性(isolation) 一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability) 持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
43. 请介绍一下数据库连接池技术?
1、数据库连接池技术,就是数据库启动时会建立一定数量的数据库连接(也称为池连接),并一直维持不少于此数目的池连接。
2、客户端程序需要连接数据库时,数据库连接池会返回一个未使用的池连接给数据库使用。如果当前没有空闲连接,数据库连接池就新建一定数量的连接。当使用的池连接调用完成后,连接池将此连接表记为空闲,其他调用就可以使用这个连接。这样做的目的是提高了应用程序访问数据库的性能。
44. MySQL、Oracle、SQL Server各数据库服务的默认端口号?
1、MySQL:3306
2、Oracle:1521
3、SQL Server:1433