1、什么是Mybatis?
(1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。
(2)MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
(3)通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。
2、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。
延迟加载的基本原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。
当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。
3、Mybatis的一级、二级缓存?
1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。
2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/> ;
3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
4、Mybatis是如何进行分页的?分页插件的原理是什么?
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。 分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
5、#{}与${}区别
#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
6、什么是 Spring 框架
Spring框架是一个开源的Java平台,它最初由Rod Johnson创建,并在2003年首次公布。它的主要功能是简化Java开发,特别是企业级应用程序的开发。Spring框架的设计哲学是通过提供一系列模块化的组件,帮助开发者创建高性能、易测试、可重用的代码。现在,让我们更深入地了解Spring框架的核心部分和特性。
核心特性
依赖注入(DI):
这是Spring框架的核心特性之一,它通过控制反转(IoC)的方法来管理对象的创建和它们之间的依赖关系。
它允许对象定义它们依赖的组件(例如其他对象),而不是自己构造它们或查找服务定位器模式。
面向切面编程(AOP):
AOP允许开发者将某些功能分割出来进行模块化,如事务管理、日志记录等,这些功能可以横切多个类型和对象。
通过AOP,可以将这些横切关注点从对象的核心业务逻辑中分离出来,从而提高模块性。
模块化和分层架构:
Spring框架具有模块化结构,可以根据需要包含或排除具体的模块。
它支持分层架构,将不同的关注点(如数据访问、业务逻辑、表示层等)分离到不同的层次。
事务管理:
Spring提供了一致的事务管理接口,可以支持声明式或编程式的事务管理。
这降低了对特定数据库或JTA事务API的依赖。
MVC框架:
Spring Web MVC是一个基于模型-视图-控制器设计模式的富特性Web框架。
它轻松集成了其他Spring功能,如依赖注入,并提供了灵活的URL映射和视图解析。
7、Spring 框架中的核心模块有哪些,它们都是干什么的?
1、Spring Core:Spring 核心模块提供了 IOC(控制反转)和 DI(依赖注入)的支持,用于管理应用程序中的对象和依赖关系。
2、Spring AOP:Spring AOP 模块提供了 AOP(面向切面编程)的支持,用于解决应用程序中的横切关注点。
3、Spring Context:Spring 上下文模块是 Spring 核心模块的扩展,提供了 BeanFactory 的功能,并且还提供了许多企业级服务,例如 JNDI(Java 命名和目录接口)访问、EJB(企业 Java Bean)集成、远程访问和国际化等。
4、Spring JDBC:Spring JDBC 模块提供了 JDBC(Java 数据库连接)的支持,并且还提供了更高级别的抽象,使得开发者更容易地访问和操作数据库。
5、Spring ORM:Spring ORM 模块提供了对 ORM(对象关系映射)框架的支持,如 Mybatis、Hibernate、JPA(Java 持久化 API)等。
6、Spring Web:Spring Web 模块提供了构建 Web 应用程序所需的各种特性和工具,如 MVC(模型-视图-控制器)框架、RESTful Web 服务、WebSocket 和 Servlet 等。
7、Spring Test:Spring Test 模块提供了对单元测试和集成测试的支持,如 JUnit 和 TestNG 等。
8、请描述5个AOP术语以及作用
Join Point: 连接点,程序执行过程中明确的点,如方法的调用或异常的抛出。
Advice: 通知,切面在特定连接点采取的动作。
Pointcut: 切点,匹配连接点的表达式。
Aspect: 切面,由通知和切点组成,它既包括横切逻辑也包括逻辑的执行点。
Weaving: 织入,把切面应用到目标对象并创建代理对象的过程。
9、Spring 中的依赖注入(DI)是什么,它的作用是什么?它有哪些常用的注入方式?
依赖注入(Dependency Injection,DI)是Spring框架的核心功能之一。它是一种设计模式,目的是为了减少组件之间的耦合度。通过DI,组件的依赖项不是由组件本身创建,而是由外部容器(在Spring中通常指的是Spring容器)在运行时注入。这样做的优点是可以提高组件的可测试性、可维护性和可扩展性。
作用
1. 松耦合
松耦合是DI的主要优点。组件不需要知道依赖的具体实现,只需要知道依赖的接口。这意味着,如果一个组件的依赖改变了实现方式,只要新的实现满足了接口的要求,该组件无需做任何修改。
2. 易于测试
DI使得在单元测试时可以轻松地替换组件使用的实际依赖为mock对象。
3. 易于维护
由于组件间的耦合度降低,系统的各个部分可以独立地发展,不会对其他部分产生影响,这使得维护和更新变得更简单。
4. 易于扩展
DI容器通常支持配置文件或注解,使得替换组件或添加新的依赖成为可能,这在不修改已有代码的情况下实现扩展。
常用的注入方式
在Spring中,有几种常见的依赖注入方式:
1. 构造器注入
通过类的构造器来注入依赖,这是推荐的注入方式,因为它可以保证所需的依赖不会是null,并且依赖项可以是不可变的。
@Component
public class MyService {
private final Dependency dependency;
@Autowired
public MyService(Dependency dependency) {
this.dependency = dependency;
}
}
2. Setter注入
通过类的setter方法注入依赖,这种方式使得你的对象在构造后仍然可以改变其依赖。
@Component
public class MyService {
private Dependency dependency;
@Autowired
public void setDependency(Dependency dependency) {
this.dependency = dependency;
}
}
3. 字段注入
直接在字段上注入依赖,虽然它简单方便,但通常不推荐使用,因为这种方式破坏了封装性,使得依赖项在类外部可被修改,并且这种方式不利于单元测试。
@Component
public class MyService {
@Autowired
private Dependency dependency;
}
4. 方法注入
这种方式较少使用,但在某些情况下可能会用到,比如当你需要在某个方法执行时才决定如何注入依赖。
@Component
public class MyService {
private Dependency dependency;
@Autowired
public void prepare(Dependency dependency) {
this.dependency = dependency;
}
}
10、Spring 中的注解有哪些?它们的具体作用是什么?写出十个注解
Spring 中的注解有很多,以下是一些常用的注解和它们的作用:
1、@Autowired
@Autowired 注解用于自动装配,将匹配类型的 bean 自动连接到指定的字段、方法或构造函数上,从而简化了依赖注入的过程。
@Autowired和@Resource都是Spring中用于依赖注入的注解,它们的作用都是将一个bean注入到另一个bean中,
但两者有以下区别:
1.1、注入方式不同:
@Autowired是按照类型来自动装配的,它通过byType的方式实现自动装配,如果容器中有多个类型匹配的bean,那么会抛出异常。
@Resource默认按照名称来装配,它通过byName的方式实现自动装配,如果指定了name属性,那么会按照名称装配,如果没有指定name属性,那么会按照类型装配。
1.2、来源不同:
@Autowired是Spring提供的注解,而@Resource是JSR-250规范中定义的注解,因此@Autowired是Spring特有的注解,而@Resource是JavaEE的注解,它们的使用范围不同。
1.3、注入方式不同:
@Autowired只能注入其他bean类型的属性。
@Resource既可以注入其他bean类型的属性,也可以注入普通类型的属性。
1.4、属性不同:
@Autowired没有额外的属性。
@Resource有两个重要的属性,分别是name和type,其中name属性用于指定bean的名称,type属性用于指定bean的类型。
总的来说,@Autowired和@Resource都是用于实现依赖注入的注解,但使用方式和实现方式略有不同,开发者可以根据需要选择使用哪个注解。
2、@Qualifier
@Qualifier 注解与 @Autowired 注解配合使用,用于指定注入的 bean 的名称。当有多个同类型的 bean 时,可以使用该注解指定要注入的 bean 的名称。
3、@Component
@Component 注解用于将类标记为一个组件,告诉 Spring 要将其放入容器中管理。它是一个通用的注解,可以用于任何类,但通常用于服务层、数据访问层和控制器等组件类中。
4、@Controller
@Controller 注解用于标记一个类作为 Spring MVC 中的控制器,用于处理请求和响应。它通常与 @RequestMapping 注解一起使用,将请求映射到控制器处理方法。
5、@RequestMapping
@RequestMapping 注解用于将请求映射到控制器处理方法。它可以用于类级别和方法级别,用于指定请求的 URL 地址、请求方法、请求参数、请求头等信息。
6、@Service
@Service 注解用于标记一个类作为服务层的组件,通常用于封装业务逻辑的方法。
7、@Repository
@Repository 注解用于标记一个类作为数据访问层的组件,通常用于封装数据访问的方法。
8、@Configuration
@Configuration 注解用于标记一个类为 Spring 的配置类,用于定义 bean。它通常与 @Bean 注解一起使用,将方法返回的对象注册为一个 bean。
9、@Bean
@Bean 注解用于将方法返回的对象注册为一个 bean。它通常与 @Configuration 注解一起使用,用于定义 bean。
10、@Value
@Value 注解用于将属性值注入到一个 bean 中。它可以用于类级别和字段级别,用于指定属性的值。
11、@Scope
@Scope 注解用于指定 bean 的作用域。它可以用于类级别和方法级别,用于指定 bean 的生命周期、作用域和代理方式等信息。
12、@Transactional
@Transactional 注解用于标记一个方法或类为事务处理方法。它通常用于封装数据库操作的方法,保证数据库操作的原子性、一致性和隔离性。
这些注解可以帮助 Spring 容器自动完成依赖注入、bean 的创建和管理、请求的处理等工作,从而简化了应用程序的开发。