学习笔记14——Springboot以及SSMP项目
SpringBoot
-
Springboot项目
-
相比于spring的特点
-
parent:定义了几百个不冲突的版本信息和坐标,继承parent模块,直接使用就可以避免多个依赖版本冲突
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
-
starter:将一些常用的组合依赖坐标打包,简化每次配置xml的难度
-
引导类:之前的main就是加载配置类springconfig,现在的入口直接就是一个配置类@SpringBootApplication,启动后创建并初始化spring容器,并默认扫描当前配置类所在包以及子包
-
内嵌Tomcat:将tomcat服务器以对象的形式在spring容器运行起来,然后程序(别的对象)要在tomcat中运行
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
-
-
配置、属性的修改【properities、yml、yaml】和不同读取【定义对象挨个value接收、用Environment对象整个接收,定义同样结构的对象@ConfigurationProperties 接收】
-
Common Application Properties (spring.io)
# 对Application启动的容器中的tomcat属性进行修改 server.port=80 # 如果对应的包没有导入,那么这里的properities设置也会无效
-
三种配置格式(properties > yml > ymal):共存叠加并相互覆盖,是所有配置的并集
likes: - game - music - sleep likes: [game,music,sleep]
-
-
读取
# 取变量值 @Value("${country}") private String country; # 取对象的属性 @Value("${User.name}") private String name; @Value("${likes[1]}") private String likes1; # 遇到数组用中括号 @Value("${User[1].age}") private String age1;
-
解决yaml的数据相互引用
baseDir: c:\windows tempDir: ${baseDir}\temp # 转义\为制表位,加上双引号 tempDir: "${baseDir}\temp"
-
一次性加载到Environment对象中,不需要每次新建对象接收
# 将属性数据封装成对象,通过Autowired自动装配 @Autowired private Environment env;
-
主流加载:对应的数据加载到对应的类中
-
创建一个类,对应于ymal中的封装数据,给出set和get方法
-
将该类定义为component
-
指定加载yaml中的哪个数据
-
该对象的属性得到对应的值
-
server就是这种类型
@Component @ConfigurationProperties("datasource")
-
整合第三方配置
-
junit【不需要勾选】
-
Test类需要加@SpringBootTest
-
在Test类中直接装在对象进行测试
-
两种情况
- Test先在自己所属包范围下(上下两个层级都找)配置类,找到就装载
- 如果test类和启动类不在同一个包下,那么就需要@SpringBootTest(classes = SpringbootJunitApplication.class)告诉配置类在哪里
- Test先在自己所属包范围下(上下两个层级都找)配置类,找到就装载
-
-
Mybatis【需要勾选mybatis framework 和 MySQL driver】
- 导入包
- 配置信息 【和tomcat一样,到这一步已经有了tomcat-spring/mybatis-spring对象了】
- 用@Mapper来映射dao层
-
Mybatis-plus
-
导入包,可以手动去mvn网站去添加
-
配置信息
-
Mapper映射(dao层可以简写,用BaseMapper映射到具体库中的表上)
@Mapper public interface BookDao extends BaseMapper<Book> { } # 如果对象叫Book,但是表不叫这个名,就需要配置,就会默认在对象名字前加tbl找到表 mybatis-plus: global-config: db-config: table-prefix: tbl_
-
-
Druid【配合Mybatis使用】
- 导入对应start包
spring: datasource: druid: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test username: root password: 123456
SSM结构流程
-
配好需要的包:springweb,mybatisplus+druid+Lombok
-
配置,一般这里需要配置的是jdbc/durid的datadriver,配置mybatis的prefix,配置服务器端口号
-
domain+Lombok:新建数据库对象,作为操作的基本返回
- @Getter
- @Setter
- @Data:最常用
-
写Dao层的语句(两种方法写操作,并将操作mapper到数据库,对于每个操作都需要在test测试)
-
mybatis-plus :@Mapper + extends BaseMapper
// 操作对象是Book,表是prefix+Book @Mapper public interface BookDao extends BaseMapper<Book> { }
// 如果是分页功能 @Test void testGetPage(){ IPage page = new Page(1,5); bookDao.selectPage(page,null); } // 需要加配置器,动态拼接SQL语句 @Configuration public class MPConfig { // 拦截器 // 传入要拦截的对象,此处是分页功能 @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }
// 查询功能 @Test void testGetBy(){ QueryWrapper<Book> qw = new QueryWrapper<>(); qw.like("name","Spring"); bookDao.selectList(qw); } // 不需要记住列名,直接通过Book调用 @Test void testGetBy2(){ LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>(); lqw.like(Book::getName,"Spring"); bookDao.selectList(lqw); } // 都有动态条件拼装,name为空就不拼接筛选条件 @Test void testGetBy2(){ String name = null; LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>(); lqw.like(name!=null,Book::getName,name); bookDao.selectList(lqw); }
-
mybatis:@Mapper + 自己写语句
@Mapper public interface BookDao { @Select("select * from tbl_book where id = #{id}") Book getById(int id); }
-
-
业务层Service
-
业务层接口
-
业务层实现类
-
// 分页:返回值bookDao.selectPage和IPage<Book>是一样的 @Override public IPage<Book> getPage(int currentPage, int pageSize) { IPage page = new Page(currentPage,pageSize); return bookDao.selectPage(page,null); }
-
public interface IBookService extends IService<Book> { // 可以自己新增方法 // 不要覆盖原始操作 } @Service public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService { } // 以上写法,就可以直接开启下边的测试 @Test void testGetPage(){ IPage<Book> page = new Page<>(1,4); bookService.page(page); System.out.println(page.getRecords()); }
-
-
表现层
-
@RestController @RequestMapping("/books") public class BookController { @Autowired private IBookService bookService; @GetMapping public List<Book> getAll(){ return bookService.list(); } @PostMapping public Boolean save(@RequestBody Book book){ return bookService.save(book); } @PutMapping public Boolean update(@RequestBody Book book){ return bookService.updateById(book); } @DeleteMapping("{id}") public Boolean delete(@PathVariable int id){ return bookService.removeById(id); } @GetMapping("{id}") public Book getById(@PathVariable int id){ return bookService.getById(id); } @GetMapping("{currentPage}/{page}") public IPage<Book> getPage(@PathVariable int currentPage, @PathVariable int page){ return bookService.getPage(currentPage,page); } }
-
-
异常处理:利用AOC来拦截所有异常,统一进行处理,要添加@RestControllerAdvice,设置该类为切面类可以被扫描到
-
@ExceptionHandler(Exception.class) public R deException(Exception ex){ // 控制台要写报错信息 ex.printStackTrace(); return new R("服务器故障"); } // 没有遇到异常,正常执行时 // 所有消息提示应该来自于同一层,不要前后端各自定义 Boolean flag = bookService.save(book); return new R(flag,flag? "添加成功":"添加失败");
-
-
el分页组件
-
// 每次需要更新页面的信息,不然就一直会是初始值 axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize+param).then((res)=>{ this.pagination.pageSize = res.data.data.size; this.pagination.currentPage = res.data.data.current; this.pagination.total = res.data.data.total; this.dataList = res.data.data.records; }); // 防止删页问题 @GetMapping("{currentPage}/{pageSize}") public R getPage(@PathVariable int currentPage, @PathVariable int pageSize){ IPage<Book> page = bookService.getPage(currentPage,pageSize); if (currentPage>page.getPages()){ page = bookService.getPage((int) page.getPages(),pageSize); } return new R(true,page); }
-
-
查询功能
-
v-model:就是拿Vue的data中的数据进行填充或者给到这个值,建立==关系
-
根据拿到的值,按照规定传参:路径+实体类直接传参
@GetMapping("{currentPage}/{pageSize}") public R getPage(@PathVariable int currentPage, @PathVariable int pageSize,Book book)
-
利用LambdaQueryWrapper进行查询
@Override public IPage<Book> getPage(int currentPage, int size, Book book) { LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>(); lqw.like(!book.getType().isEmpty(),Book::getType,book.getType()); lqw.like(!book.getName().isEmpty(),Book::getName,book.getName()); lqw.like(!book.getDescription().isEmpty(),Book::getDescription,book.getDescription()); IPage<Book> page = new Page<>(currentPage,size); bookDao.selectPage(page,lqw); return page; }
-
like(!book.getType().isEmpty(),Book::getType,book.getType());
lqw.like(!book.getName().isEmpty(),Book::getName,book.getName());
lqw.like(!book.getDescription().isEmpty(),Book::getDescription,book.getDescription());
IPage page = new Page<>(currentPage,size);
bookDao.selectPage(page,lqw);
return page;
}
```
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!