图书管理系统(基于SSM + Vue + Restful 实现)

一、项目依赖

<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方式不同,代码更加的简洁、清晰,大大提高了开发效率。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值