一、项目依赖
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
</dependencies>
二、结构搭建
三、数据库数据准备
四、连接文件
jdbc.properties 连接数据库的信息
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/my_db_01?useSSL=false
jdbc.username=root
jdbc.password=100863
五、前端代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<script src="https://cdn.staticfile.org/jquery/3.6.1/jquery.js"></script>
</head>
<body style="padding: 15px;">
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">添加新图书</h3>
</div>
<div class="panel-body form-inline">
<div class="input-group">
<div class="input-group-addon">书名</div>
<input type="text" class="form-control" id="iptBookname" placeholder="请输入书名" v-model="bookForm.name">
</div>
<div class="input-group">
<div class="input-group-addon">类型</div>
<input type="text" class="form-control" id="iptType" placeholder="请输入书籍类型" v-model="bookForm.type">
</div>
<div class="input-group">
<div class="input-group-addon">作者</div>
<input type="text" class="form-control" id="iptAuthor" placeholder="请输入作者" v-model="bookForm.author">
</div>
<div class="input-group">
<div class="input-group-addon">出版社</div>
<input type="text" class="form-control" id="iptPublisher" placeholder="请输入出版社"
v-model="bookForm.publisher">
</div>
<button id="btnSelect" class="btn btn-info" @click="likeSelect">查询</button>
<button id="btnAdd" class="btn btn-primary" @click="dialogVisible = true">添加</button>
</div>
</div>
<!-- 批量删除-->
<el-row>
<el-button type="danger" plain @click="delByIds">批量删除</el-button>
</el-row>
<!-- 添加表单-->
<el-dialog
title="添加书籍"
:visible.sync="dialogVisible"
width="30%"
>
<el-form :model="bookForm" ref="bookForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="书名" prop="name">
<el-input v-model="bookForm.name"></el-input>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-input v-model="bookForm.type"></el-input>
</el-form-item>
<el-form-item label="作者" prop="author">
<el-input v-model="bookForm.author"></el-input>
</el-form-item>
<el-form-item label="出版社" prop="publisher">
<el-input v-model="bookForm.publisher"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="saveBook">确定</el-button>
<el-button @click="cancelAdd">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
<!-- 编辑表单-->
<el-dialog
title="编辑书籍"
:visible.sync="dialogEditVisible"
width="30%"
>
<el-form :model="updateForm" ref="updateForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="书名" prop="name">
<el-input v-model="updateForm.name"></el-input>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-input v-model="updateForm.type"></el-input>
</el-form-item>
<el-form-item label="作者" prop="author">
<el-input v-model="updateForm.author"></el-input>
</el-form-item>
<el-form-item label="出版社" prop="publisher">
<el-input v-model="updateForm.publisher"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="updateBook">确定</el-button>
<el-button @click="cancelEdit">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
<!-- 表格数据-->
<template>
<el-table
:data="tableData"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
type="index"
width="50">
</el-table-column>
<el-table-column
prop="name"
label="书名"
align="center"
>
</el-table-column>
<el-table-column
prop="type"
label="类型"
align="center"
>
</el-table-column>
<el-table-column
prop="author"
label="作者"
align="center"
>
</el-table-column>
<el-table-column
prop="publisher"
label="出版社"
align="center"
>
</el-table-column>
<el-table-column
prop="address"
label="操作"
align="center"
>
<el-row>
<el-button type="primary" @click="backView">修改</el-button>
<el-button type="danger" @click="delById">删除</el-button>
</el-row>
</el-table-column>
</el-table>
</template>
</div>
</body>
</html>
js
<script src="https://cdn.staticfile.org/axios/1.1.3/axios.js"></script>
<script src="../js/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/qs/6.11.0/qs.js"></script>
<script>
new Vue({
el:"#app",
data:{
// 添加表单
bookForm: {
name: '',
type:'',
author:'',
publisher:'',
},
// 更新表单
updateForm:{
name: '',
type:'',
author:'',
publisher:'',
},
tableData:[], // 当前页面要展示的分页列表数据
dialogVisible:false, // 增加表单是否可见
dialogEditVisible:false, // 编辑表单是否可见
pagination:{}, // 分页模型数据,暂时弃用
ids:[], // id数组
selectedId:'', // 单个id
// 复选框
multipleSelection:[],
},
// 钩子函数,VUE对象初始化完成后自动执行
created(){
this.getAll();
},
methods:{
// 添加
saveBook(){
axios.post("/books",this.bookForm).then((resp)=>{
this.dialogVisible = false;
this.getAll();
this.$message({
message: '添加成功!',
type: 'success',
center:true
});
});
},
// 复选框选中后执行的函数
handleSelectionChange(val) {
this.multipleSelection = val;
},
// 取消编辑提示
cancelEdit(){
this.dialogEditVisible = false;
this.$message({
showClose: true,
message: '已取消编辑',
center:true
});
},
// 取消添加提示
cancelAdd(){
this.dialogVisible = false;
this.$message({
showClose: true,
message: '已取消添加',
center:true
});
},
// 查询
likeSelect(){
axios.get(`/books/${this.bookForm.author}`).then((resp)=>{
this.tableData = resp.data;
})
},
// 删除单条数据
delById(){
for (let i = 0; i < this.multipleSelection.length; i++) {
var selectionElement = this.multipleSelection[i];
this.selectedId = selectionElement.id;
}
if (this.selectedId == null || this.selectedId.length < 1){
this.$message({
showClose: true,
message: '请选中您要删除的数据',
type: 'error',
center:true
});
return;
}
axios.delete(`/books/${this.selectedId}`,).then((resp) => {
this.getAll();
this.$message({
message: '删除成功!',
type: 'success',
center: true
});
});
// 清空id
this.selectedId = '';
},
// 批量删除
delByIds(){
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.ids = this.multipleSelection.map(item => item.id);
if (this.ids.length < 1){
this.$message.error('请选中您要删除的数据!').center=true;
}
// 转为JSON数据发送到后台
this.ids = JSON.stringify(this.ids);
axios({
method:"delete",
url:"/books",
data:this.ids,
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
}).then((resp)=>{
this.getAll();
this.$message({
type: 'success',
message: '删除成功!'
});
});
// 清空id数组
this.ids = [];
}).catch(() => {
this.$message({
type: 'info',
message: '您已取消删除',
center:true
});
})
},
// 回显数据
backView(){
this.selectedId = this.multipleSelection.map(item => item.id);
if (this.selectedId == null || this.selectedId.length < 1){
this.$message({
showClose: true,
message: '请选中您要编辑的数据',
type: 'error',
center:true
});
return
}
this.dialogEditVisible = true;
axios.get(`/books/${this.selectedId}`).then((resp)=>{
this.updateForm = resp.data;
});
// 清空id
this.selectedId = '';
},
// 更新数据
updateBook(){
axios.put("/books",this.updateForm).then((resp)=>{
// 关闭表单
this.dialogEditVisible = false;
// 查询数据
this.getAll();
// 成功提示
this.$message({
showClose: true,
message: '更新数据成功!',
type: 'success',
center:true
});
});
},
// 主页列表数据查询
getAll(){
axios.get("/books").then((resp)=>{
this.tableData = resp.data;
})
},
}
})
</script>
六、后端代码
1.domain包 加载实体类
public class Book {
private Integer id;
private String name;
private String type;
private String author;
private String publisher;
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", type='" + type + '\'' +
", author='" + author + '\'' +
", publisher='" + publisher + '\'' +
'}';
}
public Book() {
}
public Book(Integer id, String name, String type, String author, String publisher) {
this.id = id;
this.name = name;
this.type = type;
this.author = author;
this.publisher = publisher;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
}
2.dao数据层
@Repository
public interface BookDao {
@Insert("insert into ev_books(name,type,author,publisher)values(#{name},#{type},#{author},#{publisher})")
void add(Book book);
@Delete("delete from ev_books where id=#{id}")
void delete(Integer id);
@Delete("<script> DELETE FROM ev_books WHERE id in <foreach collection='ids' item='id' open='(' separator=',' " +
"close=')" +
"'>#{id}</foreach> </script>")
void deleteByIds(@Param("ids") int[] ids);
@Update("update ev_books set name=#{name},type=#{type},author=#{author},publisher=#{publisher} where id=#{id}")
void update(Book book);
@Select("select * from ev_books where id=#{id}")
Book getById(Integer id);
@Select("select * from ev_books")
List<Book> getAll();
}
3.service业务层
BookService接口:
public interface BookService {
void add(Book book);
void delete(Integer id);
void deleteByIds(int[] ids);
void update(Book book);
Book getById(Integer id);
List<Book> getAll();
}
BookService实现类:
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
@Override
public void add(Book book) {
bookDao.add(book);
}
@Override
public void delete(Integer id) {
bookDao.delete(id);
}
@Override
public void deleteByIds(int[] ids) {
bookDao.deleteByIds(ids);
}
@Override
public void update(Book book) {
bookDao.update(book);
}
@Override
public Book getById(Integer id) {
return bookDao.getById(id);
}
@Override
public List<Book> getAll() {
return bookDao.getAll();
}
}
4.controller控制层
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@PostMapping
public String save(@RequestBody Book book){
bookService.add(book);
return "{'message':'success'}";
}
@DeleteMapping("/{id}")
public String delete(@PathVariable Integer id){
bookService.delete(id);
return "{'message':'success'}";
}
@DeleteMapping
public String deleteByIds(@RequestBody int[] ids){
bookService.deleteByIds(ids);
return "{'message':'success'}";
}
@PutMapping
public String update(@RequestBody Book book){
bookService.update(book);
return "{'message':'success'}";
}
@GetMapping("/{id}")
public Book getById(@PathVariable Integer id){
return bookService.getById(id);
}
@GetMapping
public List<Book> getAll(){
return bookService.getAll();
}
}
5.config配置
ServletContainersInitConfig.class 用来配置servlet容器
// 4.定义一个servlet容器启动的配置,在里面加载spring的配置
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
// 加载spring配置
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
// 加载springMVC配置
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
// 设置哪些请求归属springMVC处理
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
// Post请求乱码处理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter("UTF-8");
return new Filter[]{filter};
}
}
MyBatisConfig.class 用来替换xml
public class MyBatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
ssfb.setTypeAliasesPackage("cn.itaxu.domain");
ssfb.setDataSource(dataSource);
return ssfb;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("cn.itaxu.dao");
return msc;
}
}
SpringConfig.class 用来配置spring
@Configuration
@ComponentScan(value = "cn.itaxu",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MyBatisConfig.class})
public class SpringConfig {
}
SpringMvcConfig.class 用来配置springMVC
// 3.创建springmvc的配置文件,加载controller对应的bean
@Configuration
@ComponentScan({"cn.itaxu.controller","cn.itaxu.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
SpringMvcSupport.class 用来放行一些静态资源
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// 当访问/pages/???的时候,走/pages目录下的内容
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
// 当访问/js/???的时候,走/js目录下的内容
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
// 当访问/css/???的时候,走/css目录下的内容
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
// 当访问/plugins/???的时候,走/plugins目录下的内容
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
六、效果图展示
七、总结
使用SSM框架开发更加的便捷,真正的实现了高内聚、低耦合,与传统的xml方式不同,代码更加的简洁、清晰,大大提高了开发效率。