导图社区 java开发框架
java开发的一个框架,有助于进行相关的开发,分别代表着spring springmvc mybatis
编辑于2023-07-22 23:21:23 江西用于Web学习者和开发者使用,为Web前端开发的新手和有经验的开发者提供了一个清晰、全面的资源,帮助他们了解Web开发的核心技能和实践。感兴趣的小伙伴可以收藏一下~
随着TT的飞速发展,“大智物移云的时代已经来临。”大智物移云“分别指的是大数据、人工智能、物联网、移动互联、云计算技术。现在是一个计算无处不在、软件定义一切、网络包容万物、连接随处可及、宽带永无止境、智慧点亮未来时代。云技术是指实现云计算的一些技术,包括虚拟化、分布式计算、并行计算等;云计算除了技术之外更多的指一种新的IT服务模式,可以说目前提到较多的云计算30%是指技术,70%是指模式。大数据基础相关知识点,用于帮助同学们复习相关知识点。
Java面向对象编程思维导图,主要是用于期末复习自学作参考,导图精简且有助于知识点的理解与记忆。
社区模板帮助中心,点此进入>>
用于Web学习者和开发者使用,为Web前端开发的新手和有经验的开发者提供了一个清晰、全面的资源,帮助他们了解Web开发的核心技能和实践。感兴趣的小伙伴可以收藏一下~
随着TT的飞速发展,“大智物移云的时代已经来临。”大智物移云“分别指的是大数据、人工智能、物联网、移动互联、云计算技术。现在是一个计算无处不在、软件定义一切、网络包容万物、连接随处可及、宽带永无止境、智慧点亮未来时代。云技术是指实现云计算的一些技术,包括虚拟化、分布式计算、并行计算等;云计算除了技术之外更多的指一种新的IT服务模式,可以说目前提到较多的云计算30%是指技术,70%是指模式。大数据基础相关知识点,用于帮助同学们复习相关知识点。
Java面向对象编程思维导图,主要是用于期末复习自学作参考,导图精简且有助于知识点的理解与记忆。
ssm
框架
框架的定义
他是我们软件开发中的一套解决方案,不同的框架解决不同的问题
定义一
框架是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的
应用方面
定义二
框架是可被应用开发者定制的应用骨架
目的方法
简要定义
框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统
使用框架的好处
框架封装了很多细节,使开发者可以使用极简的方式实现功能,大大提高开发效率
三层架构
表现层
是用于展现数据的
业务层
是处理业务需求
持久层
是和数据库交互的
持久层技术解决方案
JDBC技术
Connection
PreparedStatement
ResultSet
Spring的jdbcTemplate
Spring中对jdbc的简单封装
Apache的DBUtils
它和Spring的jdbcTemplate很像,也对jdbc的简单封装
以上这些都不是框架
JDBC是规范
Spring的JdbcTemplate和Apache的DBUtils都只是工具类
mybatis
mybatis概述
mybatis是一个持久层框架,用java编写
它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等繁杂过程,它使用ORM思想实现了结果集的封装。
ORM
object Relational Mappging 对象关系映射
就是把数据库表和实体类及实体类的属性对应起来,让我们可以操作实体类就实现操作数据库表
今天我们需要做到实体类中的属性和数据库表的字段名称保持一致
优点
mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动,创建连接,创建statement等繁杂的过程
mybatis通过xml或注解的方式将要执行各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象返回
采用ORM思想解决了实体和数据库问题,对jdbc进行封装,屏蔽了jdbc api底层访问细节,使我们不同与jdbc api打交道,就可以完成数据库持久化操作
mybatis入门
mybatis的环境搭建
第一步
创建maven工程并导入坐标
第二步
创建实体类和dao接口
第三步
创建mybatis的主配置文件SqlMapConfig.xml
第四步
创建映射配置文件
IUserDao.xml
环境搭建的注意事项
第一个
创建·IUserDao.xml和IUserDao.java时名称是为了和我们之前的知识保持一致,在Mybatis中它把持久层的操作接口名称和映射文件也叫做Mapper 所以:IUserDao和IUserMapper是一样的
第二个
在idea中创建目录的时候,它和包是不一样的,包在创建的时:com.itheima.dao他是三级目录。目录在创建的时候:com.itheima.dao是一级目录
第三个
mybatis的映射配置文件位置必须和dao接口的包结构相同
第四个
映射配置文件的mapper标签namespace属性取值必须和dao接口的权限定类
第五个
映射配置文件的操作配置(select),id属性的取值必须是dao接口的方法名
当我们遵从了第三、四、五点之后,我们在开发中就无需再写dao的实现类
Mybatis入门案例
1.读取配置文件
2.创建sqlsessionFactory工厂
3.使用工厂生产sqlsession对象
4.使用sqlsession创建dao接口代理对象
5.使用代理对象执行方法
6.释放资源
注意事项
不要忘记在映射配置中告知mybatis要封装到哪个实体类中 配置方式:指定实体类的全限定类名
mybatis注解开发和编写dao实现类的方式
总结
mybatis基于注解的入门案例
把IUserDao.xml移除,在dao接口的方法上使用@Select注解,并且指定sql语句,同时需要在SqlMapConfig.xml中的mapper配置时,使用class属性指定dao接口的全限定名
明确
我们在实际开发中,都是越简便越好,所以都是采用不写dao实现类的方式,不管使用XML还是注解配置。但是Mybatis他是支持写dao实现类
Mybatis中参数的深入-使用实体类的包装对象为查询条件
OGNL表达式
Object Graphic Navigation Language 对象图导航语言
它是通过对象取值方法获取数据。在写法上把get给省略了
在Mybatis中直接写username,因为parameterType中已经提供了属性所属的类,所以不需要写对象名
properties标签的使用及细节
配置properties
2.可以在标签内部配置连接数据库信息。也可以通过属性引用外部配置文件信息
resource属性:常用的
用于指定配置文件的位置,是按类类路径的写法来写,并且必须存于类路径下
步骤
在classpath下定义db.propeties文件
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/eesy jdbc.username=root jdbc.password=1234
propeties标签配置
resource="jdbcConfig.properties"
url属性
是要求url的写法来写地址
URL: Uniform Resource Locator统一资源定位符。他是可以唯一表示一个资源的位置
写法
http://localhost:8080/mybatisserver/demo1Servlet
协议+主机+端口+URI
URI Uniform Resource Identify统一资源标识符。他是在应用中唯一可以定位一个资源
<properties url= file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.prop erties"> </properties>
或者直接在properties中配置
<properties> <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/><property name="jdbc.url" value="jdbc:mysql://localhost:3306/eesy"/><property name="jdbc.username" value="root"/> <property name="jdbc.password" value="1234"/> </properties>
此时我们的dataSource标签就变成了引用上面的配置
<dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource>
typeAliases
别名
批量别名的定义
扫描整个包下的类,别名为类名(首字母大写或小写都可以)
<package name="com.itheima.domain"/>
用法
子主题
单个别名的定义
<typeAlias alias="user" type="com.itheima.domain.User"/>
mappers(映射器)
<mapper resource=" " />
<mapper resource="com/itheima/dao/IUserDao.xml" />
相对于类路径的资源
<mapper class=" " />
使用mapper接口类路径
<mapper class="com.itheima.dao.UserDao"/>
注意
此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一目录下
<package name=""/>
注册指定包下所有mapper接口
<package name="cn.itcast.mybatis.mapper"/>
注意
此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一目录中
自定义Mybatis的分析-执行查询所有分析
mybatis在使用代理dao的方式实现增删改查需要
第一
创建代理对象
第二
在代理对象中调用selectList
自定义mybatis开发流程
SqlSessionFactoryBuilder接受SqlMapConfig.xml文件流,构建SqlSessionFactory对象
SqlSessionFactory读取SqlMapConfig.xml连接数据库和mapper映射信息,用来生产出真正操作数据库的SqlSession对象
SqlSession对象两大作用
生成接口代理对象
定义通用增删改查方法
注:无论哪个分支,除了连接数据库信息,还需要得到sql语句
作用
作用1:在SqlSession对象的getMapper方法中分两步来实现。第一先用SqlSessionFactory读取数据库连接信息创建Connnection对象。第二:通过jdk代理模式创建出代理对象作为getMapper方法的返回值,这里主要工作是在创建代理对象时第三个参数处理类里面得到sql语句。执行对应CRUD操作
作用2:在SqlSessionImpl对象中提供selectList()方法【当然实际mybatis框架中还有selectOne,insert等方法]这些方法也分两步
第一:用SqlSessionFactory读取的数据库连接信息创建出jdbc的Connection对象
第二:直接得到sql语句,使用jdbc的Connection对象进行对应CRUD操作
封装结果集:无论使用分支一生成代理对象,还是直接使用分支二提供的通用CRUD方法,我们都要对返回数据库结果集进行封装,变成java对象返回给调用者,所以我们还需要知道调用者所需要的返回类型
通过以上流程我们不难看出,无论是让mybatis帮我们1创建代理对象还是直接使用mybatis提供的CRUD方法,其本质都是得到jdbc的connection对象,执行sql语句,最终封装结果集。只是注解和xml配置文件两种开发模式在传递sql和返回值类型的方式有差异而已
自定义Mybatis框架-定义框架中的接口和实现
#{}与${}区别
#{}表示一个占位符号
通过#{}可以实现prepareStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。#{}可以接受简单类型值或pojo属性值。如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称
${}表示拼接sql串
通过$[}可以将parameterType传入内容拼接在sql中且不进行jdbc类型转换,${}可以接收简单类型值或pojo属性值,如果parameterType传输简单类型值,${}括号只能是value
4
加载
缓存
mybatis中的连接词以及事务控制 (原理部分了解,应用部分会用)
连接池
我们在实际开发中都会使用连接池,因为它可以减少我们获取连接所消耗的时间
mybatis中的连接池
mybatis连接池提供了3种方式的配置
配置位置
主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种连接方式
type属性的取值
POOLED
采用传统的java.sql.DataSouurce规范中的连接池,mybatis有针对规范的实现
UNPOOLED
采用传统的获取连接方式,虽然实现Java.sql.DataSource接口,但是并没有使用池的思想
JNDI
采用服务器提供JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到的DataSource是不一样的
注意
如果不是web或者maven的war工程,是不能使用的,我们课程使用的是tomcat服务器,采用连接池就是dbcp连接池
mybatis中连接池使用分析
mybatis事务控制的分析
mybatis基于xml配置的动态SQL语句使用 会用即可
mappers配置文件中的几个标签
if
我们根据实体类的不同取值,使用不同的SQL语句进行查询。比如id如果不为空时可以根据id查询,如果username不为空时还要加入用户名作为条件
用法
<select id="findByUser" resultType="user" parameterType="user"> select * from user where 1=1 <if test="username!=null and username != '' "> and username like #{username} </if> <if test="address != null"> and address like #{address} </if> </select>
注意
<if>标签的test属性中写的是对象的属性名,如果包装类的对象要使用OGNL表达式写法。另外注意where 1=1(永远为真)的作用~!
where
为了简化上面where 1=1的条件拼装,我们可以采用<where>标签来简化开发
用法
<select id="findByUser" resultType="user" parameterType="user"> <include refid="defaultSql"></include> <where> <if test="username!=null and username != '' "> and username like #{username} </if> <if test="address != null"> and address like #{address} </if> </where> </select>
foreach
用于遍历集合,他是属性
sql
抽取重复的sql语句语句
<sql id="">
<sql id="defaultSql"> select * from user </sql>
Sql中可将重复的sql提取出来,使用时用include即可,最终达到sql重用目的
<select id="findAll" resultType="user"> <include refid="defaultSql"></include> </select>
<include>标签使用,其中<include>标签的refid属性的值就是<sql>标签定义id取值。注意:如果引用其它mapper.xml的sql片段,则在引用需要加上namespace,如下:<include refid="namespace.sql">
collection
代表要遍历的集合元素,注意编写时不要写#{}
open
代表语句开始部分
close
代表语句结束部分
item
代表遍历集合的每个元素,生成的变量名
sperator
代表分隔符
用法
<where> <if test="ids != null and ids.size() > 0"> <foreach collection="ids" open="id in ( " close=")" item="uid" separator=","> #{uid} </foreach> </if> </where>
mybatis中的多表操作
一对多
示例:用户和账户
一个用户可以有多个账户
一个账户只能属于一个用户(多个账户也可以属于同一个用户)
步骤
建立两张表,用户表,账户表,让用户和账户表之间具备一对多的关系,需要使用外键在账户中添加
建立两个实体类:用户实体类和账户实体类,让用户和账户的实体类体现出来一对多的关系
建立两个配置文件
用户配置文件
账户配置文件
实现配置
当我们查询用户时,可以同时得到用户下所包含的账户信息
当我们查询账户时,可以同时得到账户的所属用户信息
一对一
多对多
实例:用户和角色
一个角色可以赋予多个用户
一个用户可以有多个角色
步骤
1.建立两张表:用户表,角色表
让用户表和角色表具有多对多的关系,需要使用中间表。中间表中含有各自的主键,在中间表是外键
2.建立两个实体类:用户实体类和角色实体类
让用户和角色的实体类能体现出来多对多的关系
各自包含对方一个集合引用
3.建立两个配置文件
用户配置文件
角色的配置文件
4.实现配置
当我们查询用户时,可以得到用户所包含的角色信息
当我们查询角色,可以同时得到角色的所赋予的用户信息
延迟加载
在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
使用association实现延迟加载(一对一)
应用
<resultMap type="account" id="accountMap"> <id column="aid" property="id"/> <result column="uid" property="uid"/> <result column="money" property="money"/> <!-- 它是用于指定从表方的引用实体属性的 --> <association property="user" javaType="user" select="com.itheima.dao.IUserDao.findById" column="uid"> </association> </resultMap>
使用collection实现延迟加载
同样我们也可以在一对多关系配置的collection结点中配置延迟加载策略
用法
<resultMap type="user" id="userMap"> <id column="id" property="id"></id> <result column="username" property="username"/> <result column="address" property="address"/> <result column="sex" property="sex"/> <result column="birthday" property="birthday"/> <!-- collection 是用于建立一对多中集合属性的对应关系 ofType 用于指定集合元素的数据类型 select 是用于指定查询账户的唯一标识(账户的 dao 全限定类名加上方法名称) column 是用于指定使用哪个字段的值作为条件查询 --> <collection property="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findByUid" column="id"> </collection> </resultMap
需求
完成加载用户对象时,查询用户所拥有的账户信息
collection标签
主要用于加载关联的集合对象
select属性
用于指定查询account列表的sql语句,所以填写的是该sql映射的id
column属性
用于指定select属性的sql语句来源,上面参数来自于user的id例,所以就写成字段名了
<settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
配置延迟加载
坏处
因为只有当需要用到数据时,才进行数据库查询,这样在大批数据查询时,因为查询工作也要消耗时间,所以可能造成用户时间变长,造成用户体验下降
立即加载
不管用不用,只要一调用方法,马上发起查询
定义
存在于内存中的临时数据
使用缓存原因
减少和数据库的交互次数,提高执行效率
适合使用缓存的数据条件
经常查询并且不经常改变。数据正确与否对最终结果影响不大的
不适用于缓存
经常改变数据
数据的正确与否对最终结果影响很大的
一级缓存和二级缓存
一级缓存
它指的是Mybatis中SqlSession对象的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存
当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中,该区域的结构是一个Map.当我们再次查询同样的数据。mybatis会先去sqlsession中查询是否有,有的话直接拿出来用,当SqlSession对象消失时,mybayis的一级缓存也就消失了
二级缓存
它指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存
二级缓存使用步骤
让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
<settings> <!-- 开启二级缓存的支持 --> <setting name="cacheEnabled" value="true"/> </settings> 因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为 false 代表不开启二级缓存。
让当前的映射文件支持二级缓存(在·IUserDao.xml中配置)
<cache></cache>
让当前操作支持二级缓存(在select标签中配置)
<!-- 根据 id 查询 --> <select id="findById" resultType="user" parameterType="int" useCache="true"> select * from user where id = #{uid} </select> 将 UserDao.xml 映射文件中的<select>标签中设置 useCache=”true”代表当前这个 statement 要使用 二级缓存,如果不使用二级缓存可以设置为 false。 注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。
mybatis中的注解开发
环境搭建
单表CRUD操作(代理DAO方式)
多表查询操作
缓存配置
Spring
spring简要概述
Spring是分层的java SE/EE应用full-stack轻量级开发框架,以IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架
Spring 的优势
方便解耦,简化开发
通过Spring提供的IoC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以专注于上层的应用
AOP编程的支持
通过Spring的AOP功能,方便进行面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付
声明式事物的支持
可以将我们从单调烦闷的事物管理代码中解脱出来,通过声明式方式灵活进行事务的管理,提高开发效率和质量
方便程序测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情
方便集成各种优秀框架
Spring可以降低各种框架的使用难度,提供了对各种优秀框架的直接支持
降低JAVAEE API的使用难度
Spring对JavaEE API(如JDBC等)进行了薄薄的封装层,使这些API使用难度大为降低
JAVA源码是经典学习范例
Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。它的源代码无意是对Java技术最佳的实践范例
Spring体系结构
IOC的概念和作用
程序得耦合和解耦
耦合性
耦合度,是对模块间关联程度的度量。
划分模块的一个准则就是高内聚低耦合
解耦
工厂模式解耦
在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象并存起来。在接下来使用的时候,直接拿过来就好,那么,这个读取配置文件,创建获取三层对象的类就是工厂
使用spring的IOC解决程序耦合
前期准备
准备spring的开发包
创建业务接口和实现类
创建持久层接口和实现类
基于xml的配置
拷贝必要的jar包到工程的lib目录中
在类路径下创建一个任意名称的xml文件(不能是中文)
让spring管理资源,在配置文件中配置service和dao
测试是否成功
基于xml的IOC细节
BeanFactory和ApplicationContext的区别
BeanFactory才是Spring容器中的顶层接口,ApplicationContext是它的子接口
创建的时间点不一样
ApplicationContext
只要一读取配置文件,默认情况下就会创建对象
BeanFactory
什么时候使用什么时候创建对象
ApplicationContext接口类的实现
ClassPathXmlApplicationContext:
它是从类路径下加载配置文件
推荐使用这种
FileSystemXmlApplicationContext
它是从磁盘路径上加载配置文件,配置可以在磁盘任意位置
AnnotationConfigApplicationContext
当我们使用注解配置容器对象时,需要使用此类来创建spring容器,他用来读注解
bean的作用范围和生命周期
单例对象:scope="singleton"
一个应用只有一个对象实例。它的作用范围就是整个引用
生命周期
对象出生:
当应用被加载,创建容器时,对象就被创建了
对象活着
只要容器在,对象一直活着
对象死亡
当应用卸载,销毁容器时,对象就被销毁了
多例对象 scope="prototype"
没吃访问对象时,都会重新创建对象实例
生命周期
对象出生
当使用对象时,创建新的对象实例
对象活着
只要对象在使用时,就一直活着。
对象死亡
当对象长时间不用时,被java的垃圾回收器回收了
实例化Bean的三种方式
使用默认无参构造函数
它会根据默认无参构造函数来创建类对象。如果bean中没有默认无参构造函数,将会创建失败
示例
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"/>
spring管理静态工厂-使用静态的方法创建对象
id属性:指定bean的id,用于从容器中获取,class属性:指定静态工厂的全限定类名,factory-method属性:指定生产对象的静态方法
spring管理实例工厂-使用实例工厂的方法创建对象
先把工厂创建给spring来管理,然后使用工厂的bean来调用里面的方法,factory-bean属性:用于指定实例工厂bean的id,factory-method属性:用于指定实例工厂中创建对象的方法
spring依赖注入
依赖注入概念
它是spring框架核心ioc的具体实现
构造函数注入
使用构造函数
给service中属性传值
要求
类中需要提供一个对应参数列表构造函数
涉及标签
constructor-arg
属性
index:指定参数在构造函数参数列表的索引位置
type:指定参数在构造函数中的数据类型
name:指定参数在构造函数中的名称
都是找谁赋值
value:它能赋的值是基本数据类型和 String 类型
ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
指的是赋什么值
示例
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> <constructor-arg name="name" value="张三"></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <constructor-arg name="birthday" ref="now"></constructor-arg> </bean> <bean id="now" class="java.util.Date"></bean>
set方法注入
通过配置文件给 bean 中的属性传值:使用 set 方法的方式
涉及标签
property
属性
name:
找的是类中set方法后面部分
ref
给属性赋值是其他bean类型的
value
给属性赋值是基本数据类型和string类型的实际开发中,此种方式用的比较多
示例
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> <property name="name" value="test"></property> <property name="age" value="21"></property> <property name="birthday" ref="now"></property> </bean> <bean id="now" class="java.util.Date"></bean>
使用p名称空间注入数据(本质还是set方法)
注入集合属性
List结构的
array,list,set
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> <!-- 在注入集合数据时,只要结构相同,标签可以互换 --> <!-- 给数组注入数据 --> <property name="myStrs"> <set><value>AAA</value> <value>BBB</value> <value>CCC</value> </set> </property>
Map结构的
map,entry,props,prop
<property name="mySet"> <list><value>AAA</value> <value>BBB</value> <value>CCC</value> </list> </property>
<property name="myMap"> <props> <prop key="testA">aaa</prop> <prop key="testB">bbb</prop> </props> </property>
使用spring的IoC的实现账户的CRUD
拷贝jar包
创建数据库和编写实体类
编写持久层代码
编写业务层代码
创建并编写配置文件
配置步骤
配置service
配置dao
配置dbAssit此处只注入了数据源,表明每条语句独立事务
配置数据源
测试
基于注解的IOC配置
环境搭建
拷贝必备jar包到工程的lib目录
使用@Component注解配置管理资源
创建spring的xml配置文件并开启对注解支持
常用注解
用于创建对象的
相当于<bean id="" class="">
@Component
作用
把资源让spring来管理,相当于xml中配置一个bean
属性
value:指定bean的id如果不指定value属性,默认bean的id是当前类的类名
@Controller @Service @Repository
@Controller
一般用于表现层的注解
@Service
一般用于业务层注解
@Repository
一般用于持久层注解
细节
如果注解中有且只有一个属性要赋值时,且名称是value,value在赋值是可以不写
用于注入数据的
相当于
<property name="" ref=""> <property name="" value="">
@Autowired
作用
自动按类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他类型bean类型。当有多个类型匹配时,使用要注入的对象变量名称作为bean的id,在spring容器查找,找到了也可以注入成功。找不到就报错
@Qualifier
作用
在自动按照类型注入的基础上,再按照Bean的id注入。它在给字段注入时不能独立使用,必须和@Autowire一起使用;但是给方法参数注入时,可以独立使用
属性
value
指定bean的id
@Resource
作用
直接按照Bean的id注入。它也只能注入其他bean类型
属性
name
指定bean的id
@Value
作用
注入基本类型和String类型数据的
属性
用于指定值
用于改变作用范围的
相当于
<bean id="" class"" scope="">
@Scope
作用
指定bean的作用范围
属性
value
指定范围的值
取值:singleton prototype request session globalsession
子主题
和生命周期相关的
相当于<bean id="" class="" init-method="" detory-method="">
@PostConstruct
作用
用于指定初始化方法
@PreDestroy
作用
用于指定销毁方法
新注解说明
@Configuration
作用
用于指定当前类是一个spring配置类,当创建容器时会从该类上加载注解,获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class)。
属性
value用于指定配置类的字节码
@ComponentScan
作用
用于指定spring在初始化容器时要扫描的包。作用和在xml配置文件中的<context:component-scan base-package="com.itheima"/>是一样的。
属性
basePackages
用于指定要扫描的包。该注解中的value属性作用一样
@Bean
作用:
该注解只能写在方法上:表明使用此方法创建一个对象,并且放入spring容器
属性
name:
给当前@Bean注解方法创建的对象制定一个名称(即bean的id)
@PropertySource
作用
用于加载.properties文件的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties配置文件中,就可以使用此注解指定properties配置文件位置
属性
value[]:用于指定properties文件位置。如果在类路径下,需要写上classpath
@import
作用
用于导入其他配置类,在引用其他配置类时,可以不用再写@Configuration注解。
属性
value[]:用于指定其他配置类字节码
通过注解获取容器
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
spring整合Junit
拷贝整合junit的必备的jar包到lib目录spring-test
使用@RunWith注解替换原有的运行器
@RunWith(SpringJUnit4ClassRunner.class)
使用@ContextConfiguration 指定 spring 配置文件的位置
@ContextConfiguration(locations= {"classpath:bean.xml"})
@ContextConfiguration 注解:
locations 属性:用于指定配置文件的位置。如果是类路径下,需要用 classpath:表明
classes 属性:用于指定注解的类。当不使用 xml 配置时,需要用此属性指定注解类的位置。
@ContextConfiguration(locations= {"classpath:bean.xml"})
使用@Autowired 给测试类中的变量注入数据
AoP的相关概念
AOP
面向切面编程
简单地说他就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理技术,在不修改源码的基础上,对我们的已有方法进行增强
作用
在程序运行期间,不修改源码对已有方法进行增强
优势
减少重复代码
提高开发效率
维护方便
AOP实现方式
使用动态代理技术
动态代理的特点
动态代理常用的有两种方式
基于接口的动态代理
提供者
JDK官方的Proxy类
使用JDK官方的Proxy类创建代理对象
要求
被代理类最少实现一个接口
基于子类的动态代理
提供者
第三方的CGLib,如果asmxxxx异常,需要导入asm.jar
使用CGLib的Enhancer类创建代理对象
要求
被代理类不能用finnal修饰的类(最终类)
动态代理的特点
装饰者模式就是静态代理的一种体现
字节码随用随创建,随用随加载
它与静态代理的区别也在于此。因为静态代理是字节码一上来就创建好,并完成加载
spring中的AOP
AOP相关术语
Joinpoint(连接点)
所谓的连接点是指那些被拦截的点。在spring中,这些点指的是方法,因为spring只支持类型的连接点
Pointcut(切入点)
所谓的切入点是指我们要对哪些JointPoint进行拦截的定义
Advice(通知/增强)
所谓的通知是指拦截到Joinpoint之后所要做的事情就是通知
通知的类型
前置通知·
后置通知
异常通知
最终通知
环绕通知
Introduction(引介)
引介是一种特殊的通知在不修改类代码前提下,Introduction可以在运行期为类动态地添加一些方法或Field
Target(目标对象)
代理目标对象
Weaving(织入)
是指增强应用到目标对象来创建地代理对象过程
spring采用动态代理织入,而AspectJ采用编译器织入和类装载织入。
Proxy(代理)
一个类被AOP织入增强,就产生一个结果代理类
Aspect(切面)
是切入点和通知(引介)地结合
学习spring中AOP要明确地事
开发阶段
编写核心业务代码(开发主线):大部分程序员来做,要求熟悉业务需求
把公共代码抽取出来,制成通知。(开发阶段最后再做):AOP编程人员来做
在配置文件中,声明切入点与同之间的关系,即切面。:AOP编程人员来做
运行阶段
spring框架监控切入点方法执行,一旦监控到切入点方法被执行,使用代理机制,动态创建目标对象的代理对象,根据通知类型,在代理对象的对应位置,将通知对应的功能织入,完成完整地代码逻辑
配置标签
aop:config
作用
用于声明开始aop的配置
aop:aspect
用于配置切面
属性
id
给切面提供一个唯一标识
ref
引用配置好的通知类bean的id
aop:pointout
作用
用于配置切入点表达式。就是指对哪些类进行增强
属性
expression
用于定义切入点表达式
id
用于给切入点表达式提供一个唯一标识
aop:before
作用
用于配置前置通知。指定增强方法在切入点方法之前执行
属性
method
用于指定通知类中的增强方法名称
pointcut-ref
用于指定切入点表达式的引用
pointcut
用于指定切入点表达式
执行时间点
切入点执行之前执行
aop:after-returning
作用
用于配置后置通知
属性
method
指定通知中方法名称
pointct
定义切入点表达式
pointcut-ref
指定切入点表达式的引用
执行时间点
切入点方法正常执行之后。它和异常通知只有一个执行
aop:after-throwing
作用
用于配置异常通知
属性
method
指定通知方法的名称
pointct
定义切入点表达式
pointcut-ref
定义切入点表达式的引用
执行时间点
切入点方法执行产生异常后执行。他和后置通知只能执行一个
aop:after
作用
用于配置最终通知
属性
method
指定通知中方法名称
pointcut
定义切入点表达式
pointcut-ref
定义切入点表达式的引用
执行时间点
无论切入点方法执行时是否有异常,它都会在其后面执行
切入点表达式说明
execution
匹配方法的执行(常用)
execution(表达式)
表达式语法:execution([修饰符] 返回值类型 包名.类名.方法名(参数))
写法说明
全匹配方式
public void com.itheima.service.impl.AccountServiceImpl.saveAccount(com.itheima.domain.Account
访问修饰符可以省略
void com.itheima.service.impl.AccountServiceImpl.saveAccount(com.itheima.domain.Account)
返回值可以使用*号,表示任意返回值 * com.itheima.service.impl.AccountServiceImpl.saveAccount(com.itheima.domain.Account) 包名可以使用*号,表示任意包,但是有几级包,需要写几个* * *.*.*.*.AccountServiceImpl.saveAccount(com.itheima.domain.Account) 使用..来表示当前包,及其子包 * com..AccountServiceImpl.saveAccount(com.itheima.domain.Account) 类名可以使用*号,表示任意类 * com..*.saveAccount(com.itheima.domain.Account) 方法名可以使用*号,表示任意方法 * com..*.*( com.itheima.domain.Account) 参数列表可以使用*,表示参数可以是任意数据类型,但是必须有参数 * com..*.*(*) 参数列表可以使用..表示有无参数均可,有参数可以是任意类型 * com..*.*(..) 全通配方式: * *..*.*(..) 注
注意
通常情况下,我们都是对业务层的方法进行增强,所以切入点表达式都是切到业务层实现类。 execution(* com.itheima.service.impl.*.*(..))
环绕通知
配置方式
<aop:config>
<aop:config> <aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="pt1"/> <aop:aspect id="txAdvice" ref="txManager"> <!-- 配置环绕通知 --> <aop:around method="transactionAround" pointcut-ref="pt1"/> </aop:aspect> </aop:config>
aop:around
作用
用于配置环绕通知
属性
method
指定通知中方法名称
pointcut
定义切入点表达式
pointcut-ref
指定切入点表达式的引用
说明
它是 spring 框架为我们提供的一种可以在代码中手动控制增强代码什么时候执行的方式。
注意
通常情况下
环绕通知都是独立使用的
基于注解的AOP配置
@Aspect
作用
把当前类声明为切面类
@Before
作用
把当前方法看成前置通知
属性
value
用于指定切入点表达式,还可以指定切入点表达式的引用
@AfterReturning
作用
把当前方法看成后置通知
属性
value
用于指定切入点表达式,还可以指定切入点表达式的引用
@AfterThrowing
作用
把当前方法看成异常通知
属性
value
用于指定切入点表达式,还可以指定切入点表达式的引用
@After
作用
把当前方法看成最终通知
属性
value
用于指定切入点表达式,还可以指定切入点表达式的引用
@Around
作用
把当前方法看成环绕通知
属性
value
用于指定切入点表达式的引用
@Pointcut
作用
指定切入点表达式
属性
value
指定表达式的内容