技术标签: spring java maven 三大框架学习理解笔记
目录
4.3 mybatis升级版MP(mybatis-plus)
每个核心jar包形成一个依赖,maven底层进行它相关的jar的自动导入
前言:本文是对于SSM三大框架的简单总结,涉及三大框架的主要功能和相关的一些工具,也希望此文是对于个人知识点的一个总结。
现在流行的三大框架是指spring ,springMVC,mybatis 三层框架结合运用的一个框架,其是当前各公司开发的主流。现行的大部分项目的开发都是采用三大框架,单项目过于复杂时,springMvc中的控制层往往抽离出来,成为单独的前端访问界面,并与前端进行数据交互。
原始时代我们用一个jsp搞定一切,但如此开发大型项目时我们遇到了问题,前端美化的代码和后端的代码交织,代码中又有html、js、css样式,又有业务逻辑和数据库访问代码,杂乱不清晰,美工和开发打架。
于是mvc分层架构封建时代出现,把我们写代码的地方硬性分成3个地方,Model层封装数据,View视图层页面展现,Controller控制层访问转发。代码之间的耦合度降低。概念有了,需要实际干活的。于是随着mvc分层概念的深入人心,业界涌现出很多实现框架,最著名的莫过于struts1和struts2。随着前端框架的成熟,后端框架也应运而生如:dbutils、jdbcTemplate、hibernate、ibatis、mybatis。前端WEB层框架有了,后端数据库层访问框架有了,那中间呢?谁来胜任?spring破石而出。
只能完成一部分工作,不能整体解决前后端的事务。spring正是抓住这点,在地位上并没有抹杀它们,而是依然给它们高官厚禄,承认它们的市场地位,还赠与一个事务管理。通过一边打压一边拉拢的方式,spring在软件开发中获得了举足轻重的地位,一个经典的三层框架诞生SSH (Strut2+Spring+Hibernate)。
spring创新的形成了一套新的理论体系,可谓前无古人后无来者。其中最核心的是:IoC控制反转、DI依赖注入、Bean工厂、SpringAOP面向切面编程、事务控制。spring在开发升级的路上也并未停止不前,而是不断更新换代,占领市场。spring占领市场后,开始对有功之臣进行清洗,struts2不再优秀,致命bug层出不穷,刚好落井下石,spring推出了springmvc,最终终结了struts2。hibernate想用jdbcTemplate和jdo替代,却被mybatis超越,目前还未统一。世界又达到新的平衡,经典的新三大框架诞生,SSM(SpringMVC+Spring+MyBatis)。
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一 般不用),Struts2(一般老项目使用)等。
SpringMVC就是基于MVC设计模式来实现的。
我们的POJO就是Model层,我们的JSP就是视图层,我们的Controller就是控制层。
现在主流基于SSM三大框架开发都是在MVC上继续演化,又分为持久层DAO,业务层Service,控制层Controller。持久层用来和数据库读写ORM,业务层用来处理复杂的业务逻辑,控制层用来处理MVC的控制。
mvc模型用来进行分层的结构,这样代码分离结构清晰,各层代码,各司其职,易于开发大型项目。而在Springboot整合的思想中,也采用了Mvc设计模式,具体如下图:
MVC(Model模型、View视图、Control控制层),将软件进行分层达到松耦合的效果。
通用的软件编程思想, 在MVC设计模式中认为, 任何软件都可以分三层:控制层(Controller)、数据处理模型(Model)、负责展示数据的视图(View)。
Springmvc架构原理解析
1、前端控制器DispatcherServlet(不需要程序员开发)
作用接收请求,响应结果,相当于转发器,中央处理器。
有了DispatcherServlet减少了其它组件之间的耦合度。
2、处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的url查找Handler
3、处理器适配器HandlerAdapter
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler
4、处理器Handler(需要程序员开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler
5、视图解析器View resolver(不需要程序员开发)
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)
6、视图View(需要程序员开发jsp)
View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)
1.2结构图
2.三层核心代码
//控制层
@RestController //@Controller + @ResponseBody
@RequestMapping("car")
public class CarController {
@RequestMapping("get")
public String get(){
return "123";
}
//pojo层
@Data
public class Car {
private int id;
private String name;
private String type;
private String color;
private double price;
}
//自启动类
@SpringBootApplication
public class RunApp {
public static void main(String[] args) {
SpringApplication.run(RunApp.class);
}
}
测试结果:
案例2:提交用户数据
3.2 Spring核心概念
(两大核心,三大组件,五大模块)
模块 | 说明 |
---|---|
BeanFactory | Spring内部使用,创建bean的工厂 |
ApplicationContext | 外部应用程序调用,也成为spring容器 |
IoC控制反转Inversion of Control | 开发者在无需自己new对象,无需关心对象的创建过程User user = new User(); 手动创建对象User user = context.getBean(user); 容器创建对象 |
DI依赖注入Dependency Injection | 松耦合方式实现对象直接的依赖 |
AOP面向切面编程 | 补充java面向对象的不足 |
1.模拟bean工厂
public class SpringContext {//模拟Spring框架是spring的核心
//1,创建容器管理bean->[user,dept,hello]
//2,创建Spring容器->{hello=new Hello(),user=new User()}
//3.getBean(),有就取出,没有就创建并放入容器
//1,创建容器管理bean->[user,dept,hello]
private List<Bean> bf=new ArrayList<>();
public void SC01() throws Exception {
Bean a=new Bean();
a.setName("hello");//设置bean的扫描值
a.setPath("cn.tedu");//设置bean的扫描路径
bf.add(a);
init01();
}
//2,创建Spring容器->{hello=new Hello(),user=new User()}
private final Map<String, Object> fbo = new ConcurrentHashMap<>();//初始化bean工厂
private void init01() throws Exception {
for(Bean b:bf){
//map里的key
String key=b.getName();
//反射创建对象,作为value存入map
String path=b.getPath();
Object value=Class.forName(path).newInstance();//反射技术,将对象的值作为其的重要依据
fbo.put(key,value);
}
}
//3.getBean()有就直接取出来,没有就创建并放入容器
public Object getBean(String name){
return fbo.get(name);
}
}
public class Testioc {
@Test
public void ioc2(){
//1.读取核心配置文件
ClassPathXmlApplicationContext Spring02=
new ClassPathXmlApplicationContext("" +
"Spring-config01l.xml");
//2,getBean---参数是类名,但首字母要编变成小写才行
Object o=Spring02.getBean("student");
System.out.println(o);
Student a=(Student)o;
a.get();
Object o2= Spring02.getBean("studentscore");
System.out.println(o2);
StudentScore b=(StudentScore)o2;
b.get03();
StudentInfo c=(StudentInfo)Spring02.getBean("studeninfo");
c.get02();
}
}
Bean、Context、Core三大核心组件的关系:
Bean 包装的是 Object,而 Object 必然有数据,如何给这些数据提供生存环境就是 Context要解决的问题,对 Context 来说它就是要发现每个 Bean 之间的关系,为它们建立这种关系并且要维护好这种关系。所以 Context 就是一个Bean关系的集合,这个关系集合又叫 Ioc 容器,一旦建立起这个 Ioc 容器后 Spring 就可以为你工作了。那 Core 组件又有什么用武之地呢?其实Core 就是发现、建立和维护每个 Bean 之间的关系所需要的一些类的工具,从这个角度看来,Core 这个组件叫 Util 更能让你理解。
把Bean 比作一场演出中的演员的话,那 Context 就是这场演出的舞台背景,而 Core应该就是演出的道具了。只有他们在一起才能具备能演出一场好戏的最基本的条件。当然有最基本的条件还不能使这场演出脱颖而出,还要他表演的节目足够的精彩,这些节目就是 Spring 能提供的特色功能了。
- IoC(Inversion of Control)简单来说就是将对象Object的创建的权力及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不在需要关注对象的创建和生命周期的管理,而是在需要的时候由Spring框架提供,这个由Spring框架管理对象创建和生命周期的机制称之为控制反转。
- 在创建对象的过程中Spring可以依据对象的关系,自动把其它对象注入(无需创建对象,直接拿着使用)进来,这个过程称之为DI(Dependency Injection)依赖注入。
1 IOC(Inversion of Control),控制反转。
就是指将对象的创建,对象的存储(map),对象的管理(依赖查找,依赖注入)交给了spring容器。
具体案例:
2 DI(Dependency Injection)依赖注入 。
相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。
Spring的功能核心是系统自动创建并管理对象;主要是以下两件事:
MyBatis的前身就是iBatis,iBatis本是apache的一个开源项目,2010年5月这个项目由apahce sofeware foundation 迁移到了google code,并且改名为MyBatis。
MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。
1. XML映射
1.1参数解析
a)别名:alias
在sqlMapConfig.xml配置,在映射文件中直接写对象名称即可
b)参数值:paramterType
指定参数类型,通常制定一个对象类型。c)返回值:resultType
非常重要的东西,即完成ORM的映射关系所在。这里指定的cd.tedu.mybatis.domain.User代表把结果集转换成一个User对象实例。d)返回值:resultMap
resultMap 用于对复杂对象结构时,对应的ResultMap结构名称
1.2动态SQL
Mybatis提供使用ognl表达式动态生成sql的功能。
Sql标签用来提取SQL片段,来提高SQL的复用.使用位置需要通过include引用指定的SQL片段.
if: 执行SQL时,可以添加一些判断条件.
where:去掉条件中可能多余的and或者or
foreach:用于in子查询中的多个值的遍历
mybatis-plus官网:简介 | MyBatis-Plus
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库
get 查询单行
remove 删除
list 查询集合
page 分页
前缀命名方式区分 Mapper
层避免混淆,T
为任意实体对象IBaseService
继承 Mybatis-Plus
提供的基类Wrapper
为 条件构造器自 3.3.0 开始,默认使用雪花算法+UUID(不含中划线)
自定义示例工程:
1.企业级架构架构图
2.业务逻辑以及调用顺序
经典的业务请求过程如下:
- 前端html页面发起ajax请求,访问SpringMVC框架的Controller控制层,
- SpringMVC框架解析请求,找到要调用的某个Controller,找到其中的findAll方法,同时把请求提交的参数封装到java对象中。
- Controller层把请求传递给Spring框架的Service业务层,Service层在把请求传递给Mybatis框架的Mapper持久层,Mapper访问MySQL数据库进行数据库表的查询,
- 查询结果返回给MapperMapper再返回给Service层,Service再返回给Controller层。
- Controller把java数据转换为json字符串,返回给ajax调用
- ajax进行回调并把json字符串转换为js对象,再在页面中就可以通过js/vue解析js对象,最终把数据展现到html页面中。
调用情况如下图:
3 开发使用的工具
Java工程中我们自己去找jar,或者来自官网,或者来自网友的分享,或者来自项目团队的共享,不论何种方式,都需要把jar文件复制到lib目录中,并且buildpath。
Maven改变这种手动维护jar的方式,设计出一套自动维护jar的体系,已经广泛在软件项目中使用,是软件开发人员必须掌握的技术。
meven采用全新的设计体系:创先河的发明pom模型,引入了“仓库”、“依赖”、“坐标”和“命令”这四大特征,具体说明如下:
全球仓库(中央仓库):全球开发者都可以连接它来自动下载jar包,而无需去厂家官网下载。
镜像仓库:中国就有网易、阿里等镜像仓库。
本地仓库:下载一次后,不会再次下载的,除非你删除了。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
3.坐标 coordinate
4.命令 mvn cmd
常用命令:
Jar管理起来更加轻松,已经被业界广泛采用,springboot就是maven的延伸
仓库的独特设计,实现仓库自行维护
依赖管理方便很多,把开发人员从手工导包解脱出来
坐标体系使不同厂商的文件也井然有序,不会冲突覆盖
生命周期对应命令,使一键做完以前手动的n步事情
下载异常让初学者手足无措,不得不删掉仓库重新下就好了,为什么好了,不知道
部分包因为版本问题,需要手工导入
引发新的问题,版本冲突:大型项目中jar中依赖其它jar包,会发生你调3.1,我调3.2,臭名昭著的版本冲突问题,如何解决呢?上面方式手工排除,而maven采用就近原则
本地仓库日积月累巨大,本人的达到2g,很多低版本的jar已经无用,或者过气的技术的jar
大型项目中jar冲突非常厉害,仍需手动排除,而且实现方式很多,没有统一规则。如当年加入dubbo的jar时,那冲突叫做满天飞,项目做完也没很良好的解决。但这点springboot却解决了,maven的失败却早就了今天springboot能大行其道的根本原因。
1.前端是简单的网页,由直接访问请求和Post请求
2后端结构
在项目中搭建前端连接层 service层 controller层 pojo层 以及自启动类RunSpringboot;在后端连接数据库配置核心文件Application ,映射文件UseMapper.xml 以及映射接口;在中间整合层创建pojo层封装对象,依靠DI 以及Ioc控制对象,以及service层接受用户的请求,再在测试类中创建TestSpringboot,测试前后端的联通。
具体结构如图:
<head>
<meta charset="utf-8">
<title>SpringMvc</title>
<script>
function a(){
/**请求类型:1.get 查询 2.post */
let user={
id:1,name:"tomact",
age:18,sex:"女"
}
let url="http://localhost:8080/getUserBYId"
$.get(url,user,function(data){
console.log(data)
alert(data)
})
}
</script>
<script src="./jquery-1.8.3.min.js"></script>
</head>
<body>
<a href="#" onclick="a()">点我获取ajax</a>
</body>
@RestController //控制请求
@CrossOrigin //跨域
public class UserController {
@Autowired //依赖注入
private UserService userService;
/**需求:查询全部用户信息
* URL:/getAll
* 返回值:List<User>*/
@RequestMapping("/getAll") //控制参数
public List<User> getAll(){
return userService.getAll();
}
类
@Service//服务层
@Repository//@Mapper //MapperScan
public class UserServiceImp implements UserService{
@Autowired //依赖注入
private UserMapper userMapper;
@Override
public List<User> getAll(){
//重写方法
return userMapper.selectList(null);
}
接口
@Service
public interface UserService {
List<User> getAll();
/**独享关系映射配置:
* 1.User对象需要与demo_user表绑定
* 2.User对象中的属性与表中的字段一一绑定
* */
@Data //get set toString
@Accessors(chain = true) //链式编程
@TableName("demo_user")
public class User implements Serializable {
@TableId(type=IdType.AUTO)//id 代表主键
//拓展:uuid
//主键自增
private Integer id;
//@TableField("name")
//如果属性与字段同名(包括驼峰规则) 注解可以省略
private String name;
private Integer age;
private String sex;
}
@SpringBootApplication
@MapperScan("com.jt.mapper" ) //开启扫描功能
public class RunSpringBoot {
public static void main(String[] args) {
SpringApplication.run(RunSpringBoot.class,args);
}
}
接口
@Component
//注意事项:继承接口时,必须添加泛型对象,否则映射表报错
public interface UserMapper extends BaseMapper<User>{
//Mp规则: 对象的方式操作数据库 curd操作
List<User> getAll();
映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--规则: namespace必须与接口一一对应 -->
<mapper namespace="com.jt.mapper.UserMapper">
<!--驼峰命名规则
表字段: user_id,user_name
对象的属性: userId,userName
resultType: 保证属性与字段名称必须一致.
Mybatis提供了驼峰命名规则:
规则: 字段user_id~~~去除_线~~~之后映射对象的属性userId-->
<select id="getAll" resultType="User">
select * from demo_user
</select>
</mapper>
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver 设置数据库连接
url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowM
ultiQueries=true 连接数据库
username: root 用户名
password: lydon 密码
#SpringBoot整合mp配置
mybatis-plus:
type-aliases-package: com.jt.pojo
mapper-locations: classpath:/mybatis/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
#不打印日志
##debug: false
#Mapper接口执行 打印Sql日志
logging:
level:
com.jt.mapper: debug
在前后端交互过程中,springboot整合了三大框架,用户在页面发送请求,请求首先传递到控制层,控制层继续传递数据给业务层,业务层经过一定的处理,继续将数据传递给下一层,最后在持久层执行数据的操作。在数据库得到对对应的数据后,又返回传递给前端,显示在网络的页面上。
springMvc交互过程
前端发送ajax请求,将请求传递给控制层。控制层通过@RestController实现java与we的连接,再通过@CrossOrigin//实现跨域,再通过扫描请求头,在网页中输入相应网址即可访问java程序端
具体如下图
文章浏览阅读7.9k次,点赞19次,收藏50次。本博客将会介绍一些集成后子函数,可直接调用,用于Lammps的后处理,子函数内容和功能会及时更新,请关注博客更新时间_matlab处理lammps介电常数
文章浏览阅读1.1k次。方法反射:1、如何获取某个方法,方法的名称和方法的参数列表才能唯一决定某个方法2、方法反射的操作 method.invoke(对象,参数列表)public class MethodDemo1 { public static void main(String[] args) { /** * 要获取print(int,int)方法 * 1、要获取一个方法就是获取类的信息,首先要获取类的类型 */ A a1 = _方法 反射
文章浏览阅读1.5w次,点赞8次,收藏17次。前言一般来说,下载完NoteExpress后,打开word就能够直接出现NoteExpress插件了,如下之前我的都是能用的,但是有一天在我写论文需要导入参考文献的时候,却意外发现,它它它不见了!!!去网上检索,无非就是这两种方法:方法1:在noteexpress中安装1如图所示,找到noteexpress的快捷方式,然后右键单击该快捷方式,然后选择“获取管理员权限”,有的人的电脑显示的是“以管理员身份运行”,都一样的。打开noteexpressWord中noteexpress插件无法安装的_noteexpress导入不了
文章浏览阅读2.6k次。基本信息书名:数字图像处理——使用MATLAB分析与实现(高等学校电子信息类专业定价:69.05元。注 定价是图书封底的标价,售价是顾客支付的价格。作者:蔡利梅,王利娟出版社:清华大学出版社出版日期:注 出版时间受保存的自然因素,未使用的还是新书。ISBN:9787302518228字数:563000页码:356版次:1装帧:平装开本:16开商品标识:[bianma]编辑推荐本书是在作者总结多年从..._数字图像处理蔡利梅课后答案
文章浏览阅读779次。python机器学习——决策树_python实现连续型变量的回归预测
文章浏览阅读1.4k次。我的秋招经验分享(内附笔面试干货)本文出自公众号:程序员江湖。满满干货,关注就送。时间过得很快,已经到了九月中旬,从16年读研到现在将近两年的时间里,从一个Java初...
文章浏览阅读2.3k次,点赞3次,收藏14次。5.3节我们会推导一些矩阵的性质,这些性质可以被用来计算坐标系之间相对速度转化关系,这些转化关系里面包括了旋转矩阵的推导。而通过介绍反对称矩阵可以简化其中的一些计算。定义一. 当一个矩阵S有且仅有..._机器人学导论反对称矩阵有什么性质
文章浏览阅读4.8w次,点赞17次,收藏70次。【问题描述】貌似multicols环境中不能放图片,即\begin{multicols}{2}\begin{figure}\centering\includegraphics[width=0.309\textwidth]{fig0001.eps}\caption{图} \label{fig:1}\end{figure}\end{multicols} 是不允许的,图片_latex两栏图片
文章浏览阅读4.9k次。我有一个输入字符串:result = '"testing","0.8841","642000.0","80.014521","-60.940653","4522126666","1500854400","","1500842014000","name","80.014521","-60.996532","sampledevice","3","name"'data = result.split("\..._列表 单引号
文章浏览阅读229次。0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。 示例 1:输入: n = 5, m = 3输出: 3示例 2:输入: n = 10, m = 17输出: 2..._c++问题即,1, 2, ..., n这n个数字排成一个圆圈,从数字1开始,每次从这个圆圈里删除
文章浏览阅读1.8w次。Android采取了一种有别于Linux的进程管理策略,有别于Linux的在进程活动停止后就结束该进程,Android把这些进程都保留在内存中, 直到系统需要更多内存为止。这些保留在内存中的进程通常情况下不会影响整体系统的运行速度,并且当用户再次激活这些进程时,提升了进程的启动速度。那Android什么时候结束进程?结束哪个进程呢?Android是依据一个名为LRU(last recent_手机内存回收机制如何更改
文章浏览阅读1.5k次。Query接口1.不可省略的formString hql="form Student";//创建Query实例Query query = Session.createQuery(hql);//执行HQL调用list(),返回List集合List studentList = query.list();2.select//别名的使用String hql="select s.nam_hql 面向对象