一、什么是SSM整合
SSM整合用到两个容器,web容器是root容器的子容器,父子容器关系。
为了方便编写,我们可以三层架构每层对应一个配置类,分别指定两个容器加载
Ioc如何初始化?
二、简单实现整合SSM
(一)service层实现
1.数据库准备
2.pojo包下准备实体类
3.until包下准备R类,用于接收返回状态码&状态&具体数据
4.service包下创建ScheduleService
5.config包下配置service
6.mapper包下创建ScheduleMapper类
(二)mapper配置实现
1.准备dataSource
1.1 resource文件夹下创建jdbc.properties
1.2 config包下实现DataSourceJavaConfig配置
2.mapper包下创建ScheduleMapper类
3. resource文件夹下创建com/example/mapper包存放ScheduleMapper.xml文件
(三) controller层实现
1.untils包下准备PageBean数据结构用于实现分页功能
2.service/impl包下创建ScheduleServiceImpl实现ScheduleService的增/删/改/分页查询功能
3.controller包下ScheduleController实现响应结果
4.config包下实现WebMvcJavaConfig
(四) 配置IOC
测试
所有代码在gitee可自行下载
SSM整合学习https://gitee.com/cx293824/ssm-learning.git
一、什么是SSM整合
-
SSM整合用到两个容器,web容器是root容器的子容器,父子容器关系。
容器名 | 盛放组件 |
web容器 | web相关组件(controller,springmvc,web等组件) |
root容器 | 业务和持久层相关组件(service,aop,tx,dataSource,mybatis,mapper等) |
-
为了方便编写,我们可以三层架构每层对应一个配置类,分别指定两个容器加载
配置名 | 对应内容 | 对应容器 |
WebJavaConfig | controller,springmvc相关 | web容器 |
ServiceJavaConfig | service,aop,tx相关 | root容器 |
MapperJavaConfig | mapper,datasource,mybatis相关 | root容器 |
-
Ioc如何初始化?
对于web项目,可以选择web.xml和配置类方式进行ioc配置,相较于xml配置,配置类更简介方便
public class SpringIoCInit extends AbstractAnnotationConfigDispatcherServletInitializer {
//rootioc容器的配置类
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{DataSourceJavaConfig.class, MapperJavaConfigNew.class,ServiceJavaConfig.class};
}
//webioc容器的配置类指定
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebMvcJavaConfig.class};
}
//dispatcherServlet的拦截路径
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
二、简单实现整合SSM
(一)service层实现
1.数据库准备
CREATE TABLE schedule (
id INT NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
completed BOOLEAN NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO schedule (title, completed)
VALUES
('学习java', true),
('学习Python', false),
('学习C++', true),
('学习JavaScript', false),
('学习HTML5', true),
('学习CSS3', false),
('学习Vue.js', true),
('学习React', false),
('学习Angular', true),
('学习Node.js', false),
('学习Express', true),
('学习Koa', false),
('学习MongoDB', true),
('学习MySQL', false),
('学习Redis', true),
('学习Git', false),
('学习Docker', true),
('学习Kubernetes', false),
('学习AWS', true),
('学习Azure', false);
2.pojo包下准备实体类
@Data
public class Schedule implements Serializable {
private Integer id;
@NotBlank
private String title;
@NotNull
private Boolean completed;
private static final long serialVersionUID = 1L;
}
3.until包下准备R类,用于接收返回状态码&状态&具体数据
@Data
public class R {
private int code = 200; //200成功状态码
private boolean flag = true; //返回状态
private Object data; //返回具体数据
public static R ok(Object data){
R r = new R();
r.data = data;
return r;
}
public static R fail(Object data){
R r = new R();
r.code = 500; //错误码
r.flag = false; //错误状态
r.data = data;
return r;
}
}
4.service包下创建ScheduleService
@Service
public interface ScheduleService {
R page(int pageSize, int currentPage);
R remove(Integer id);
R save(Schedule schedule);
R update(Schedule schedule);
}
5.config包下配置service
/**
* description: 业务层配置类: service , aop , tx
* @author UserName
*
* 1.service
* 2.开启aop注解的支持 aspect : @Before @After @AfterReturning @AfterThrowing @Around @Aspect @Order
* 3.tx声明式事务管理: 1.对应的事务管理器实现 [TransactionManager DataSource。。 Hibernate。。 Jpa。。]
* 2.开启事务注解支持 @Transactional
*/
@Configuration
@EnableAspectJAutoProxy
@EnableTransactionManagement
@ComponentScan("com.example.service") //advice
public class ServiceJavaConfig {
@Bean
public TransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
System.out.println("dataSource = " + dataSource.toString());
return dataSourceTransactionManager;
}
}
6.mapper包下创建ScheduleMapper类
public interface ScheduleMapper{
List<Schedule> queryList();
int deleteById(Integer id);
int insert(Schedule schedule);
int update(Schedule schedule);
}
(二)mapper配置实现
1.准备dataSource
1.1 resource文件夹下创建jdbc.properties
jdbc.user=root
jdbc.password=123456
jdbc.url=jdbc:mysql://localhost:3306/studb
jdbc.driver=com.mysql.cj.jdbc.Driver
1.2 config包下实现DataSourceJavaConfig配置
@Configuration
@PropertySource("classpath:jdbc.properties")
public class DataSourceJavaConfig {
@Value("${jdbc.user}")
private String user;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driver}")
private String driver;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(user);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setDriverClassName(driver);
return dataSource;
}
}
2.mapper包下创建ScheduleMapper类
public interface ScheduleMapper{
List<Schedule> queryList();
int deleteById(Integer id);
int insert(Schedule schedule);
int update(Schedule schedule);
}
3. resource文件夹下创建com/example/mapper包存放ScheduleMapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 全限定符 -->
<mapper namespace="com.example.mapper.ScheduleMapper">
<select id="queryList" resultType="schedule">
select * from schedule
</select>
<!-- int deleteById(Integer id);-->
<delete id="deleteById">
delete from schedule where id = #{id}
</delete>
<insert id="insert" >
insert into schedule (title,completed) value (#{title},#{completed});
</insert>
<update id="update" >
update schedule set title = #{title} ,completed = #{completed}
where id = #{id}
</update>
</mapper>
4.使用配置类代替xml配置,config包下创建MapperJavaConfig配置mybatis
@Configuration
public class MapperJavaConfigNew {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
//指定配置文件等信息
//指定数据库连接池对象
sqlSessionFactoryBean.setDataSource(dataSource);
//指定mybatis配置文件的功能,使用代码的形式
org.apache.ibatis.session.Configuration configuration
= new org.apache.ibatis.session.Configuration();
// <setting name="mapUnderscoreToCamelCase" value="true"/>
configuration.setMapUnderscoreToCamelCase(true);
configuration.setLogImpl(Slf4jImpl.class);
configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL);
//org.apache.ibatis.session.Configuration // 存储setting的配置文件
sqlSessionFactoryBean.setConfiguration(configuration);
//别名设置
sqlSessionFactoryBean.setTypeAliasesPackage("com.example.pojo");
//分页插件
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect","mysql");
pageInterceptor.setProperties(properties);
sqlSessionFactoryBean.addPlugins(pageInterceptor);
return sqlSessionFactoryBean;
}
//mapper代理对象加入到ioc
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
// Mapper代理兑现的factoryBean -> 指定一个包 -> mapper接口 -》sqlSessionFactory -> sqlSession -> getMapper -> mapper代理对象 -》 ioc
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.example.mapper"); //mapper接口和mapperxml所在的共同包
return mapperScannerConfigurer;
}
}
(三) controller层实现
1.untils包下准备PageBean数据结构用于实现分页功能
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean<T> {
private int currentPage; // 当前页码
private int pageSize; // 每页显示的数据量
private long total; // 总数据条数
private List<T> data; // 当前页的数据集合
}
2.service/impl包下创建ScheduleServiceImpl实现ScheduleService的增/删/改/分页查询功能
/**
* @author UserName
* @description 针对表【schedule】的数据库操作Service实现
* @createDate 2024-04-10 22:49:02
*/
@Service
public class ScheduleServiceImpl implements ScheduleService{
private ScheduleMapper scheduleMapper;
@Autowired(required = false)
public ScheduleServiceImpl(ScheduleMapper scheduleMapper) {
this.scheduleMapper = scheduleMapper;
}
@Override
public R page(int pageSize, int currentPage) {
//分页
PageHelper.startPage(currentPage,pageSize); // sql limit x,y;
//查询
List<Schedule> scheduleList = scheduleMapper.queryList();
//把查询到的List放入PageInfo进行分页数据装配
PageInfo<Schedule> info = new PageInfo<>(scheduleList);
//再装配入我们设定好的PageBean结构中
PageBean<Schedule> pageBean = new PageBean<>(currentPage,pageSize,info.getTotal(),info.getList());
return R.ok(pageBean);
}
@Override
public R remove(Integer id) {
int rows = scheduleMapper.deleteById(id);
if (rows > 0){
return R.ok(null);
}
return R.fail(null);
}
@Override
public R save(Schedule schedule) {
int rows = scheduleMapper.insert(schedule);
if (rows > 0){
return R.ok(null);
}
return R.fail(null);
}
@Override
public R update(Schedule schedule) {
//判断id不能为null
if (schedule.getId() == null) {
return R.fail("核心参数为null,无法修改!");
}
int rows = scheduleMapper.update(schedule);
if (rows > 0){
return R.ok(null);
}
return R.fail(null);
}
}
3.controller包下ScheduleController实现响应结果
@CrossOrigin //解决跨域问题,允许其他源访问我们的controller 浏览器大哥就不拦截了!
@RestController
@RequestMapping(value = "schedule")
@Slf4j
public class ScheduleController {
private ScheduleService scheduleService;
@Autowired
public ScheduleController(ScheduleService scheduleService) {
this.scheduleService = scheduleService;
}
//接收参数
//响应结果 springmvc
@GetMapping("{pageSize}/{currentPage}")
public R page(@PathVariable int pageSize,
@PathVariable int currentPage){
R r = scheduleService.page(pageSize,currentPage);
//sl4fj
log.info("查询的数据为:{}",r);
return r;
}
@DeleteMapping("{id}")
public R remove(@PathVariable Integer id){
return scheduleService.remove(id);
}
@PostMapping
public R save(@Validated @RequestBody Schedule schedule, BindingResult result){
if (result.hasErrors()){
return R.fail("参数为null,不能保存!");
}
return scheduleService.save(schedule);
}
@PutMapping
public R update(@Validated @RequestBody Schedule schedule, BindingResult result){
if (result.hasErrors()){
return R.fail("参数为null,不能修改!");
}
return scheduleService.update(schedule);
}
}
4.config包下实现WebMvcJavaConfig
@EnableWebMvc
@Configuration
@ComponentScan("com.example.controller")
public class WebMvcJavaConfig implements WebMvcConfigurer {
//通过重写这个方法,启用默认Servlet处理器,使得对静态资源的请求能够被容器处理。
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//配置视图解析器,将逻辑视图名称解析为具体的视图。
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views/","jsp");
}
//添加拦截器,通过这个方法可以配置自定义的拦截器,对请求进行预处理或后处理。
@Override
public void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(new xx()).addPathPatterns().excludePathPatterns()
}
}
(四) 配置IOC
@EnableWebMvc
@Configuration
@ComponentScan("com.example.controller")
public class WebMvcJavaConfig implements WebMvcConfigurer {
//通过重写这个方法,启用默认Servlet处理器,使得对静态资源的请求能够被容器处理。
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//配置视图解析器,将逻辑视图名称解析为具体的视图。
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views/","jsp");
}
//添加拦截器,通过这个方法可以配置自定义的拦截器,对请求进行预处理或后处理。
@Override
public void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(new xx()).addPathPatterns().excludePathPatterns()
}
}
测试
每页五个数据,第一页