SSM
SSM:
即是Spring SpringMVC Mybatis的开头字母
Spring
SSM里的Spring其实主要常用的是IoC和Aop,还有Test
- Spring默认的xml配置文件为 applicationContext.xml
Spring IoC
中文译名:控制反转/依赖注入,简单来说,即是原来的new xxx();
用spring中content的bean代替,实现在构造函数的时候自动注入参数,有三种配置方式:基于xml,基于注解,基于java类,有三种注入方式:构造注入,set注入,工厂注入(不常用).
基于xml的配置
1 | <!--标识符(identifiers)即bean的身份标识--> |
基于注解的配置
1 | //自动生成Bean. 与@Repository(用于DAO),@Service(用于Service),@Controller(用于Controller)作用相同 |
另外还要在Spring的xml配置文件中配置以使注解生效
1 | <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> |
基于java配置类的配置
即是将xml配置文件里的配置提出来,放到一个java文件里,成为一个配置类.这样的好处即是不需要xml文件了,实现去xml化.
1 | //btw spring boot里的@SpringBootApplication一条等于@Configuration,@EnableAutoConfiguration,@ComponentScan三条 |
btw: Scope标识此bean的作用域,常在多线程问题中使用.
什么时候该在xml里定义bean什么时候该用扫描
在xml里定义bean
- 非常严谨需要一个个定义
- 外部引入,无法修改的类
- 我就是享受那种一个个定义的快感的时候
不需要定义bean
- 怕在xml中配置的时候手滑
- 懒
Spring AOP
Aspect-Oriented Programming(AOP,面向切面的程序设计)是对于Object-oriented programming(OOP,面向对象程序设计)的一个改进.
我对于AOP的理解: 即hook住了一个类(要代理的类)中的函数,使得我们可以在函数的之前之后跑一段其他代码.SpringAOP使得获取到的对象(Bean)为代理后的而不是原有的.
btw:当代理类中的函数互相调用时,SpringAOP不会起作用.
通过继承接口实现的AOP
此处的接口指的是SpringAOP拦截器的接口,具体来说即继承org.springframework.aop下的函数:
- MethodBeforeAdvice.before()
- AfterReturningAdvice.afterReturning()
- MethodInterceptor.invoke()
- ThrowsAdvice的AfterThrowing()(ThrowAdvice并没有此接口,但是继承后的函数名依然要是AfterThrowing,原因)
1 | public class xxxxHelper_or_u_want implements MethodBeforeAdvice,MethodInterceptor,AfterReturningAdvice { |
Spring的xml配置文件
1 | <bean id="xxxxImpl" class="com.test.xxxxImpl"> |
通过xml来配置(AspectJ)
此种方法相比较第一种方法的最大区别即是不用继承接口.
1 | public class xxxxHelper_or_u_want { |
Spring的xml配置文件
1 | <bean id="xxxxHelper" class="com.test.xxxxHelper_or_u_want"> |
通过注解来配置(AspectJ)
1 | //使得Spring可以自动扫描 |
Spring的xml配置文件
1 | <aop:aspectj-autoproxy /><!-- 扫描@Aspect --> |
AspectJ表达式
AspectJ表达式通配符
符号 | 作用 |
---|---|
*** | 匹配任何数量的字符 |
.. | 匹配任何数量的任何数量的字符,换句话说即匹配任何数量的*** |
+ | 跟在类后面,表示此类的子类(不包含其本身) |
- 对于简单的例子
- execution(public com.test.xxxxImpl.fun_name(..)))
参数 | 作用 |
---|---|
public | public类型 |
com.test.xxxxImpl | 包名 |
. | 连接包名与函数(方法)名 |
fun_name | 函数(方法)名 |
(..) | 所有参数 |
那么可以推出
表达式 | 作用 |
---|---|
execution(public com.test.xxxxImpl.fun_name(..))) | 任意参数的public的com.test.xxxImple.fun_name函数 |
execution(public com.test.xxxx+.fun_name(..))) | 任意参数的public的实现了com.test.xxx的fun_name函数的函数 |
execution(public com.test.xxxx+.(..)))* | 任意参数的public的实现了com.test.xxx的任何函数的函数 |
execution( com.test.xxxx+.(..))) | 任意参数的任意类型的实现了com.test.xxx的任何函数的函数 |
execution(public com.test.(..)))* | 任意参数的public的com.test包下的任何类(com.test.*)的任何函数 |
execution(public com.test..(..)))* | 任意参数的public的com.test./com.test..*的任何函数 |
Test
配置log4j后,使用context.getBean()获取Bean,调用类中的函数
SpringMVC
SpringMvc(全称Spring Web MVC,位于spring-webmvc.jar)通过一个叫做DispatcherServlet的Servlet来获取 ModelAndView 来传递内容,并在View
(一般是.jsp)中将Model
渲染出来从而生成web页面.
btw: Spring5中引入了一个新的web框架Spring-webflux
SpringMVC与Servlet容器(如Tomcat)的配置
有多个Servlet的配置
- 需要配置*[Servlet-name]-serlvet.xml*
在web.xml中配置DispatcherServlet即可,就如其名,它是个Servlet,他将url-pattern中的请求转发到关联的的serlet-name中,这样的好处即是可以将多个Servlet的Bean分离(或者说是每个Servlet的WebApplicationContext),互不影响.
在web.xml下进行如此配置
1 | <web-app> |
即配置*/example/下的所有请求都被名叫servlet_name的servlet处理(具体配置文件为/WEB-INF/servlet_name-servlet.xml)
当然也有用java配置类的方法,只需要继承org.springframework.web下的WebApplicationInitializer接口即可
1 |
|
仅有单个Servlet的配置(特殊)
- 仅需要配置applicationContext.xml
如果仅有一个Servlet,那么可以将将所有请求拦截,然后交由Spring的ApplicationContext(或者说Root的WebApplicationContext)处理.
在web.xml下进行如下配置
1 | <web-app> |
btw: 除了ContextLoaderListener,还有ContextLoaderServlet的实现
SpringMVC的Controller
基于注解的配置
IndexController.java(在com.test)
1 | // 类似于@Component但是是由springmvc解析 |
index.jsp(在*/WEB-INF/views/*下)
1 | <p>${message}</p> |
servlet_name-servlet.xml
1 | <!-- 拦截所有请求时,需要此配置来使@Controller获得比<mvc:default-servlet-handler/> 更高的优先级 --> |
此时访问http://localhost:8080/example/*即可看到由*IndexController传递message给*/WEB-INF/views/index.jsp*并显示的页面
- Controller中的model的区别
Model|特点|使用|返回
–|–|–|–|–
ModelMap|由Spring自动创建|作为函数方法的参数接受,并使用addAttribute传递参数|返回String
ModelAndView|自己手动创建|使用new来创建,并使用addObject传递参数|返回Model
- 返回字符串的关键字
String | 作用 |
---|---|
forward: | 服务器转发 |
redirect: | 客户端转发 |
基于xml的配置
java继承并重写Controller(org.springframework.web.servlet.mvc)的handleRequest函数即可
1 | public class IndexController implements Controller { |
index.jsp不变
servlet_name-servlet.xml
1 | <!-- 因为id不能包括'/' --> |
基于java配置类的配置
参见Srping部分
即是*@Configuration* ,@ComponentScan 和*@Bean* 等的使用
RESTFul
RESTFul,即符合REST(Representational State Transfer) principles的系統,通常用来做api,使用json(大多数)或xml通过http的方法来传递参数
我的理解即是视任何东西为对象,用各种http方法(PUT,GET,DELETE,PATCH等)来标识作用,真正要用的时候查查github的Api看看怎么写的照猫画虎就OK 😂
SpringMVC中使用*@RequestMapping*,@PathVariable,@RequestBody和*@ResponseBody来方便的实现RESTFul*
注解 | 作用 |
---|---|
@RequestMapping | 绑定Controller到指定路径(api的) |
@PathVariable | 标识路径中的变量与函数方法参数的关系 |
@RequestBody | 用来获取传入的数据(json/xml) |
@ResponseBody | 用来直接返回数据而不是调用model |
- Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TestController {
public String index({ Id_And_Name ian)
StringBuffer sb=new StringBuffer("");
sb.append(ian.id);
sb.append("---->");
sb.append(ian.name)
model.addAttribute("message", sb.toString());
return "index";
}
public Id_And_Name index(int uid){
Id_And_Name ian=new Id_And_Name().get_name_by_id(uid)
return ian;
}
}
btw: RPC就是使用二进制,而不是http,实现不同系统间相互通信
Mybatis
Mybatis(ibatis)
他通过SqlSession(由SqlSessionFactory创建)来执行(Excutor())各种操作
我个人感觉折腾这个比折腾hibernate麻烦(当然是在使用Intellij IDEA的情况下)
Mybatis配置
配置环境
通过mybatis-config.xml来进行配置坏境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<configuration>
<!-- 引入.properties文件,使得可以在下面的配置中引用 -->
<!-- db.properties文件中有jdbc.password=toor等 -->
<properties resource="db.properties">
<environments default="development">
<environment id="development">
<!-- 采用jdbc的事务管理 -->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value=${jdbc.password} />
</dataSource>
</environment>
</environments>
</configuration>选择的数据表每条数据包含id,username,password内容
实体类User(com.test.entity)
1
2
3
4
5
6public class User{
int id;
String username;
String password;
// set,get方法略
}
配置数据库方法
仅使用xml文件配置
mybatis-config.xml
1
2
3
4
5
6<configuration>
<mappers>
<!-- 引用具体的mapper文件 -->
<mapper resource="com/test/mapper/UserMapper.xml" />
</mappers>
</configuration>被引用的UserMapper.xml文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<!-- namespace的值习惯上设置成包名+sql映射文件名 -->
<mapper namespace="com.test.mapper.UserMapper">
<select id="selectUserById" parameterType="int" resultType="user">
select * from user where id=#{id}
<if test="name !=null">
and name=#{name}
</if>
</select>
<select id="selectUserListByName" parameterType="string" resultType="user">
select * from user where username=#{name}
</select>
<insert id="saveUser" parameterType="user">
insert into user values(#{username},#{password})
</insert>
<delete id="deleteUserById" parameterType="int">
delete from user where id=#{id}
</delete>
<update id="udpateUserById" parameterType="user">
update user set username=#{username} where id=#{id}
</update>
</mapper>或者使用Mapper代理方式(写个接口)的方式配置
UserMapper.java
1
2
3
4public interface UserMapper {
public User selectUserById(int id);
public int deleteUserById(int id);
}mybatis-config.xml与UserMapper.xml文件不变
UserMapper.xml中的namespace等于mapper接口地址
接口中的函数方法名与xml中的statemen的id一致
输入输出的类型要一致
或者直接在Mapper接口上进行注解
- UserMapper.java
1
2
3
4
5
6public interface UserMapper {
public User selectUserById(int id);
public int deleteUserById(int uid);
} - UserMapper.xml
1
2
3
4
5
6<configuration>
<mappers>
<!-- 引用mapper的class -->
<mapper class="com.test.mapper.UserMappe" />
</mappers>
</configuration>
- UserMapper.java
另外,使用typeAliases可设置别名从而精简书写量
1
2
3
4
5
6
7
8<configuration>
<typeAliases>
<!-- 手动 -->
<typeAlias type="com.test.entity.User" alias="user"/>
<!-- 自动,以首字母小写的非限定类名来作为它的别名-->
<package name="com.test.mapper.UserMapper"/>
</typeAliases>
</configuration>
mapper | 特点 |
---|---|
resource | xml文件 |
class | 接口上注解 |
使用Spring管理Mybatis
这里的管理指的是
- 数据源
- sqlSession
- Mapper
在Spring-context.xml中
1 | <!-- 数据源 --> |
这样搞完后,只需要
- 写好DAO层调数据库的接口,并写好操作数据库的sql语句(xml/注解),自动注入Mapper的配置
- 在Service层中配置SqlSession类型的变量,即可注入sqlSession,调用DAO层的接口
- 在Controller层调用Service层的方法,并使得SpringMVC可以传递输入输出数据
- Tomcat等Servlet容器在启动之后将特定的数据传递到SpringMVC
- 浏览器将其转换成从Tomcat或其他http服务器获得数据,展示给用户
分页
使用阿里巴巴的pagehelper即可,有中文文档
一对多,多对一,多对多
在实体类中设置某其他实体类变量即可实现多对多的功能
Mybatis Generator
maven中添加*mybatis-generator-maven-plugin(org.mybatis.generator)*插件
可自动生成mybatis所需的各种文件
1 |
|
参考链接
详解 Spring 3.0 基于 Annotation 的依赖注入实现