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类中直接装在对象进行测试
两种情况
Mybatis【需要勾选mybatis framework 和 MySQL driver】
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使用】
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
配好需要的包:springweb,mybatisplus+druid+Lombok
配置,一般这里需要配置的是jdbc/durid的datadriver,配置mybatis的prefix,配置服务器端口号
domain+Lombok:新建数据库对象,作为操作的基本返回
写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;
}
```