1.为什么使用Spring(优缺点)
①:方便解耦,简化开发(IOC:通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码造成的过度程序耦合)
②:AOP编程的支持(通过Spring提供的AOP功能,方便进行面向切面的编程)
③:声明式事务的支持(可以从单调烦闷的事务管理代码中解脱出来)
④:方便程序的测试(Spring对Junit4支持,可以通过注解方便的测试Spring程序)
⑤:方便集成各种优秀框架(Spring不排斥各种优秀的开源框架如Struts
,Hibernate)
⑥:Spring属于低浸入式设计,代码得污染极低
2.Spring常用的注解
第一步:在applicationConotext.xml
中引入命名空间,引入的命名空间简单来说就是用来约束xml文件格式的。
第二步:在applicationContext.xml
文件中引入注解扫描器<context:component-scan base-package="com.ys.annotation"></context:componet-scan>
@Component(@Repository:dao层 @Service:service层 @Controller:web层 功能一样)
@Component
public class Person {}
等价于
@Component(“p”)
public class Person {}
等价于
3.谈谈Mybatis
Mybatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使得开发者只需要专注于sql语句本身,而不用去关心注册驱动、创建connection等,Mybatis通过xml文件配置或者注解的方式将要执行的各种statement配置起来,并通过java对象和statement中的sql进行映射成最终执行的sql语句,最后由Mybatis框架执行sql并将结果映射成java对象并返回。
4.Mybatis分为三层
①API接口层:提供给外部使用的接口API
②:数据处理层:负责具体的SQL
③:基础支撑层:负责最基础的功能支撑,如连接管理,事务管理,配置加载和缓存处理
5.Mybatis和jdbc的区别
①数据库链接创建,释放频繁造成系统资源浪费会影响系统性能,使用数据链接池可以解决
在核心配置文件
SqlMapConfig.xml
中配置数据链接池,使用数据链接池管理数据库的链接
②Sql写在代码中不易维护,修改需要变动java代码
在映射文件XxxMapper.xml文件中配置sql语句与java代码分离
③向sql语句传输参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应
Mybatis可以自动将java对象映射到sql语句
④对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,将数据记录封装成pojo对象解析更加方便
Mybatis可自动将sql执行结果映射到java对象
5.映射文件
<mapper namespace="com.neuedu.dao.UserDao">
<select id="queryUserIsExists" resultType="user" parameterType="user">
select * from test_user where phone = #{phone} and password = #{password}
</select>
</mapper>
namespace:名称空间
id:根据id执行sql
parameterType:入参
resultType:出参
#{id} 接收的参数
6.模糊查询
<selectid="findByName2" parameterType="java.lang.String" resultType="com.gugiu.model.User">
select * from user where name like '%${value}%'
</select>
修改
<update id="updateUserById" parameterType="com.gugiu.model.User">
update user set name = #{name},age =#{age},address=#{address}
where id =#{id}
</update>
7.$和#的区别
①** #{} 将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。 如:order by #{user_id},如果传入的值是111,那么解析成sql时的值为order by “111”, 如果传入的值是id,则解析成的sql为order by “id”。**
②** $将传入的数据直接显示生成在sql中。如:order by ${user_id},如果传入的值是111,那么解析成sql时的值为order by user_id,
如果传入的值是id,则解析成的sql为order by id。**
③能用#尽量用#
④MyBatis排序时使用order by 动态参数时需要注意,用$而不是#。
⑤**#很大程度防止SQL注入(语句拼接)**
8.指定别名
- 单个文件
<typeAliases>
<typeAlias type="com.gugiu.model.User" alias="user"/>
</typeAliases>
- 批量
<typeAliases>
<package name="com.guigu.model1"/>
<package name="com.guigu.model2"/>
</typeAliases>
9.映射文件的加载
- 单个文件
<mappers>
<!—加载单个映射文件-->
<mapper resource="com/guigu/mapper/UserMapper.xml"/>
</mappers>
- 批量
<mappers>
<package name="com.guigu.mapper"/>
</mappers>
10.动态SQL的编写
①if
<insert id="addUserVo" parameterType="com.guigu.mybatis.pojo.UserVo">
<if test="user != null">
insert into my_user (name,age,address)
value(#{user.name},#{user.age},#{user.address})
</if>
</insert>
②where
<select id="findByUserVo" parameterType="UserVo"resultType="User">
select * from my_user
<where>
<if test="user!= null">
<if test="user.id != null and user.id !='' ">
and id = #{user.id}
</if>
<if test="user.name != null and user.name !='' ">
and name like '%#{user.name}%'
</if>
</if>
</where>
</select>
③**sql代码片段 **
<sql id="find_user_byId">
<if test="user.id != null and user.id !='' ">
and id = #{user.id}
</if>
</sql>
<sql id="find_user_byAge">
<if test="user.age != null and user.age !='' ">
and age = #{user.age}
</if>
</sql>
<select id="findByUserVo" parameterType="UserVo" resultType="User">
select * from my_user
<where>
<if test="user!= null">
<include ref id="find_user_byId"></include>
<include ref id="find_user_byAge"></include>
</if>
</where>
</select>
④foreach
<insert id="addUsers" parameterType="map">
insert into my_user (name,age,address)
<if test="users != null">
values
<foreach collection="users" item="user" separator=",">
(#{user.name},#{user.age},#{user.address})
</foreach>
</if>
</insert>
<select id="findByIds" parameterType="map" resultType="User">
<if test="userIds != null">
select * from my_user
<where>
<foreach collection="userIds" item="userId" separator="or">
id = #{userId}
</foreach>
</where>
</if>
</select>
11.缓存
Mybatis首先去缓存中查询结果集,如果没有则查询数据库,如果有则从缓存取出返回结果集就不走数据库。
Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象
①一级缓存(SqlSession级别)
Mybatis一级缓存的作用域是同一个SqlSession,在同一个SqlSession中两次执行相同的sql语句,第一次执行后会将查询到的数据存储到缓存当中,第二次会从缓存中进行查找,从而提高查找效率,当一个SqlSession结束之后,一级缓存也将不存在,Mybatis默认开启一级缓存
②二级缓存(Mapper级别)
二级缓存的作用域是mapper的同一个namespace(在同一个namespace中查询sql可以从缓存中获取数据),执行两次相同的SQL语句,第一次执行后会将查询到的数据存储到缓存中,第二次会从缓存中进行查找,从而提高查找效率,默认不开启,二级缓存是可以跨SqlSession的。
③对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
12.Mybatis的编程步骤
(0)创建SqlSessionFactoryBuilder
(1)通过SqlsesionFactoryBuilder创建sqlSessionFactory
(2)通过SqlSessionFactory创建sqlSession
(3)通过sqlSession执行数据库操作
(4)调用**session.commit()**提交事务
(5)调用**session.close()**关闭会话
13.实体类中的属性名和数据表中的列名不一致
(1)在sql语句中使用别名
(2)事先指定映射关系,这样Mybatis也能自动完成映射。Mybatis提供了resultMap标签
<resultMap type="User" id="UserResultMap">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
<result column="user_password" property="userPassword"/>
</resultMap>
Mybatis提供了一个全局属性mapUnderscoreToCamelCase来解决两者名字不一致的问题。
14.使用MyBatis的mapper接口调用有哪些要求?
①Mapper接口方法名和mapper.xml中定义的每个sql的id相同
②Mapper接口中输入的参数类型和mapper.xml中定义的每个sql的ParameterType相同
③Mapper接口中输出的参数类型和mapper.xml中定义的每个sql的resultType相同
④Mapper.xml文件中的namespace即是接口的类路径
15.MyBatis实现一对多有几种方式?怎么操作的?
- 联合查询
联合查询是几个表联合查询,只查询一次,通过在resultMap里面配置collection节点配置一对多的类就可以完成
- 嵌套查询
嵌套查询是先查一个表,根据这个表里面的结果的外键id,再去另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置。
16.MyBatis实现一对一有几种方式?具体怎么操作的?
- 联合查询
联合查询是几个表联合查询,只查询一次,通过在resultMap里面配置association节点配置一对一的类就可完成
- 嵌套查询
嵌套查询是先查一个表,根据这个表里面的结果的外键id,再去另一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。
17.Spring是什么?
Spring是一个轻量级的IoC和AOP的容器框架。是为java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,他使得开发者只需关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置、基于java的配置
主要有以下几个模块组成:
Spring Core :核心类库,提供IoC服务
Spring Context :提供框架式Bean访问方式,以及企业级功能(JNDI、定时任务等)
Spring AOP :AOP服务
Spring MVC :提供面向web应用的Model-View-Controller实现
Spring DAO :对JDBC的抽象,简化了数据访问异常的处理
Spring ORM :对现有的ORM框架的支持
Spring Web :提供了基本的面向Web的综合特效,例如多方文件上传