1.创建项目,导入坐标,pom.xml文件如下
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2.配置
3.建立数据库
4.创建实体类
lombok是一个java类库,提供了一组注解,简化pojo实体类开发。
(1)在pom中导入坐标
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
(2)写@Getter注解时,会得到所有的get方法,写@Setter注解时,包含所有的set方法,写@Data注解时,会将get和set方法都包含。
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
//lombok
@Getter
@Setter
@Data
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
5.配置mybatis和druid
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url:jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username:root
password:123456
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
6.创建数据层接口
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lpf.domain.Book;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BookDao extends BaseMapper<Book> {
}
7.测试
@SpringBootTest
class Springboot04SsmpApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
System.out.println(bookDao.selectById(1));
}
@Test
void testSave(){
Book book=new Book();
book.setType("测试数据");
book.setName("测试数据123");
book.setDescription("测试数据456");
bookDao.insert(book);
}
@Test
void testUpdate(){
Book book=new Book();
book.setId(2);
book.setType("测试数据");
book.setName("测试数据123");
book.setDescription("测试数据456");
bookDao.updateById(book);
}
@Test
void testDelete(){
bookDao.deleteById(1);
}
@Test
void testGetAll(){
System.out.println(bookDao.selectList(null));
}
8.配置
在测试testSave方法时,会报错,报错内容是不能设置属性值id,要给id值设置成“1454562254855”,这是由于mybatis-plus默认生成id值的策略是雪花算法。解决方法是在application.yml文件中配置。
id-type是设置自增策略,不然mybatis使用的是assign_id,
?9.开启mp运行日志
在测试过程中,只能看见数据结果,看不见查询,添加等方法的执行过程。
开启方式是在配置文件中配置。
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
id-type: auto
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
10.分页
@Test
void testGetPage(){
IPage page=new Page(1,5);
bookDao.selectPage(null,null);
}
当运行程序时,和预期结果不符,预期是每页五条,结果是数据结果都显示了。
控制台显示的SQL语句是,SELECT? ?,,,,FROM? ,,
而要实现分页的SQL语句是SELECT ,,,,FROM,,Limit,,,
造成的原因是mp默认不会加上limit。解决方法是使用mp提供的拦截器做。
创建MPConfig.java
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MPConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
?分页操作需设定分页对象IPage
IPage对象中封装了分页操作中的所有数据(数据,当前页码值,每页数据总量,最大页码值,数据总量)
11.按条件查询
@Test
void testGetBy(){
QueryWrapper<Book> qw=new QueryWrapper<>();
qw.like("name","Spring");
bookDao.selectList(qw);
}
调用的like方法类似于API,
为了避免将对象名写错,可以使用如下的对象,进行语法级的检查。
@Test
void testGetBy2(){
LambdaQueryWrapper<Book> qw=new LambdaQueryWrapper<>();
qw.like(Book::getName,"Spring");
bookDao.selectList(qw);
}
如果将查询条件Spring改为null时,SQL语句为select ,,,from ,,,where? name like null
为了避免这种情况,可以加上判断语句。
@Test
void testGetBy2(){
String name=null;
LambdaQueryWrapper<Book> lqw=new LambdaQueryWrapper<>();
if(name!=null) lqw.like(Book::getName,name);
bookDao.selectList(lqw);
}
还可以在like里边加条件,如果是true将连接,如果是false,不连接
@Test
void testGetBy2(){
String name=null;
LambdaQueryWrapper<Book> lqw=new LambdaQueryWrapper<>();
//if(name!=null) lqw.like(Book::getName,name);
//lqw.like(true,Book::getName,name);
lqw.like(name!=null,Book::getName,name);
bookDao.selectList(lqw);
}
12.业务层快速开发,基于MyBatisPlus构建
创建业务层接口IBookService
import com.baomidou.mybatisplus.extension.service.IService;
import com.lpf.domain.Book;
public interface IBookService extends IService<Book> {
}
实现类的创建
继承的ServiceImpl<BookDao, Book>,第一个泛型是实现类,第二个泛型是模型类。
import com.baomidou.mybatisplus.extension.service.IService;
import com.lpf.domain.Book;
import org.springframework.stereotype.Service;
@Service
public interface IBookService extends IService<Book> {
}
测试
@SpringBootTest
public class BookServiceTest {
@Autowired
private IBookService bookService;
@Test
void testGetById() {
System.out.println(bookService.getById(1));
}
@Test
void testSave(){
Book book=new Book();
book.setType("测试数据");
book.setName("测试数据123");
book.setDescription("测试数据456");
bookService.save(book);
}
@Test
void testUpdate(){
Book book=new Book();
book.setId(2);
book.setType("测试数据");
book.setName("测试数据123");
book.setDescription("测试数据456");
bookService.updateById(book);
}
@Test
void testDelete(){
bookService.removeById(1);
}
@Test
void testGetAll(){
System.out.println(bookService.list());
}
@Test
void testGetPage(){
IPage<Book> page=new Page<Book>(1,5);
bookService.page(page);
System.out.println(page.getCurrent());
System.out.println(page.getSize());
System.out.println(page.getTotal());
System.out.println(page.getPages());
System.out.println(page.getRecords());
}
业务层都是使用了定义好的方法,需要手工编辑,
@Service
public interface IBookService extends IService<Book> {
boolean saveBook(Book book);
boolean modify(Book book);
boolean delete(Book book);
}
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
@Autowired
private BookDao bookDao;
@Override
public boolean saveBook(Book book){
return bookDao.insert(book)>0;
}
@Override
public boolean modify(Book book) {
return bookDao.updateById(book)>0;
}
@Override
public boolean delete(Book book) {
return bookDao.deleteById(id)>0;
}
}
快速开发时,使用MyBatisPlus提供有业务层通用接口(IService<T>)与业务层通用实现类(ServiceImpl<M,T>)
在通用类基础上做功能重载或功能追加
注意重载时不要覆盖原始操作,避免原始提供的功能丢失。
13.表现层
基于Restful进行表现层接口开发
使用Postman测试表现层接口功能
创建BookController
import java.util.List;
@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);
}
//使用请求体传json数据,@RequestBody
@PutMapping
public Boolean update(@RequestBody Book book){
return bookService.modify(book);
}
//@PathVariable 是表明参数从路径中获取
@DeleteMapping("{id}")
public Boolean delete(@PathVariable Integer id){
return bookService.delete(id);
}
//getmapping请求是使用路径传参数,所以是,http://localhost/books/2
@GetMapping("{id}")
public Book getById(@PathVariable Integer id){
return bookService.getById(id);
}
}
分页操作实现
在 IBookService中重写方法
@Service
public interface IBookService extends IService<Book> {
boolean saveBook(Book book);
boolean modify(Book book);
boolean delete(Book book);
IPage<Book> getPage(int currentPage,int pageSize);
}
实现IPage
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
@Autowired
private BookDao bookDao;
@Override
public boolean saveBook(Book book){
return bookDao.insert(book)>0;
}
@Override
public boolean modify(Book book) {
return bookDao.updateById(book)>0;
}
@Override
public boolean delete(Book book) {
return bookDao.deleteById(id)>0;
}
@Override
public IPage<Book> getPage(int currentPage, int pageSize) {
IPage page=new Page(currentPage,pageSize);
bookDao.selectPage(page,null);
return page;
}
}
controller层
@GetMapping("{currentPage}/{pageSize}")
public IPage<Book> getPage(@PathVariable int currentPage,@PathVariable int pageSize){
return bookService.getPage(currentPage,pageSize);
}
新增使用post
删除delete
修改put
查询get
接收实体数据:@RequestBody
接收路径变量参数:@PathVariable
14.前后端协议联调
前后端分离结构设计中页面归属前端服务器。
单体工程中页面放置在resources目录下的static目录中,(如果程序出现莫名其妙的问题,先clean一下,在重新编译,可能是由于IDEA工具引起的)
?
<body>
<h1>图书管理</h1>
<script>
var vue =new vue(
created(){
this.getAll();
},
methods:{
getAll()
{
axios.get("/books").then((res) => {
console.log(res.data);
});
},
}
</script>
</body>
created钩子函数用于初始化页面时发起调用。
页面使用axios发送异步请求获取数据后确认前后端是否联通。
15.数据处理
<script>
var vue =new Vue({
el:'#app',
data:{
dataList[],
dialogFormVisible:false,
dialogFormVisibleEdit:false,
formData:{},
rules:{
type:[{required:true,message:'图书类别为必填项',trigger:'blur'}],
name:[{required:true,message:'图书名称为必填项',trigger:'blur'}]
},
pagination:{
currentPage:1,
pageSize:10,
total:0
}
},
created() {
this.getAll();
},
methods: {
getAll() {
axios.get("/books").then((res) => {
console.log(res.data);
this.dataList = res.data.data;
});
},
}
}
</script>
this.dataList = res.data.data;
外面设置了读取dataList,然后将数据初始化。
|