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


    一、项目依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>com.fasterxml.jackson.coregroupId>
    4. <artifactId>jackson-databindartifactId>
    5. <version>2.9.0version>
    6. dependency>
    7. <dependency>
    8. <groupId>org.springframeworkgroupId>
    9. <artifactId>spring-webmvcartifactId>
    10. <version>5.2.10.RELEASEversion>
    11. dependency>
    12. <dependency>
    13. <groupId>mysqlgroupId>
    14. <artifactId>mysql-connector-javaartifactId>
    15. <version>8.0.29version>
    16. dependency>
    17. <dependency>
    18. <groupId>javax.servletgroupId>
    19. <artifactId>javax.servlet-apiartifactId>
    20. <version>3.1.0version>
    21. <scope>providedscope>
    22. dependency>
    23. <dependency>
    24. <groupId>com.alibabagroupId>
    25. <artifactId>druidartifactId>
    26. <version>1.1.16version>
    27. dependency>
    28. <dependency>
    29. <groupId>org.springframeworkgroupId>
    30. <artifactId>spring-jdbcartifactId>
    31. <version>5.2.10.RELEASEversion>
    32. dependency>
    33. <dependency>
    34. <groupId>org.mybatisgroupId>
    35. <artifactId>mybatisartifactId>
    36. <version>3.5.6version>
    37. <scope>compilescope>
    38. dependency>
    39. <dependency>
    40. <groupId>org.mybatisgroupId>
    41. <artifactId>mybatis-springartifactId>
    42. <version>1.3.0version>
    43. dependency>
    44. dependencies>

    二、结构搭建

     三、数据库数据准备

     四、连接文件

    jdbc.properties 连接数据库的信息

    1. jdbc.driver=com.mysql.cj.jdbc.Driver
    2. jdbc.url=jdbc:mysql://localhost:3306/my_db_01?useSSL=false
    3. jdbc.username=root
    4. jdbc.password=100863

    五、前端代码

    html

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
    9. integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    10. <script src="https://cdn.staticfile.org/jquery/3.6.1/jquery.js">script>
    11. head>
    12. <body style="padding: 15px;">
    13. <div id="app">
    14. <div class="panel panel-primary">
    15. <div class="panel-heading">
    16. <h3 class="panel-title">添加新图书h3>
    17. div>
    18. <div class="panel-body form-inline">
    19. <div class="input-group">
    20. <div class="input-group-addon">书名div>
    21. <input type="text" class="form-control" id="iptBookname" placeholder="请输入书名" v-model="bookForm.name">
    22. div>
    23. <div class="input-group">
    24. <div class="input-group-addon">类型div>
    25. <input type="text" class="form-control" id="iptType" placeholder="请输入书籍类型" v-model="bookForm.type">
    26. div>
    27. <div class="input-group">
    28. <div class="input-group-addon">作者div>
    29. <input type="text" class="form-control" id="iptAuthor" placeholder="请输入作者" v-model="bookForm.author">
    30. div>
    31. <div class="input-group">
    32. <div class="input-group-addon">出版社div>
    33. <input type="text" class="form-control" id="iptPublisher" placeholder="请输入出版社"
    34. v-model="bookForm.publisher">
    35. div>
    36. <button id="btnSelect" class="btn btn-info" @click="likeSelect">查询button>
    37. <button id="btnAdd" class="btn btn-primary" @click="dialogVisible = true">添加button>
    38. div>
    39. div>
    40. <el-row>
    41. <el-button type="danger" plain @click="delByIds">批量删除el-button>
    42. el-row>
    43. <el-dialog
    44. title="添加书籍"
    45. :visible.sync="dialogVisible"
    46. width="30%"
    47. >
    48. <el-form :model="bookForm" ref="bookForm" label-width="100px" class="demo-ruleForm">
    49. <el-form-item label="书名" prop="name">
    50. <el-input v-model="bookForm.name">el-input>
    51. el-form-item>
    52. <el-form-item label="类型" prop="type">
    53. <el-input v-model="bookForm.type">el-input>
    54. el-form-item>
    55. <el-form-item label="作者" prop="author">
    56. <el-input v-model="bookForm.author">el-input>
    57. el-form-item>
    58. <el-form-item label="出版社" prop="publisher">
    59. <el-input v-model="bookForm.publisher">el-input>
    60. el-form-item>
    61. <el-form-item>
    62. <el-button type="primary" @click="saveBook">确定el-button>
    63. <el-button @click="cancelAdd">取消el-button>
    64. el-form-item>
    65. el-form>
    66. el-dialog>
    67. <el-dialog
    68. title="编辑书籍"
    69. :visible.sync="dialogEditVisible"
    70. width="30%"
    71. >
    72. <el-form :model="updateForm" ref="updateForm" label-width="100px" class="demo-ruleForm">
    73. <el-form-item label="书名" prop="name">
    74. <el-input v-model="updateForm.name">el-input>
    75. el-form-item>
    76. <el-form-item label="类型" prop="type">
    77. <el-input v-model="updateForm.type">el-input>
    78. el-form-item>
    79. <el-form-item label="作者" prop="author">
    80. <el-input v-model="updateForm.author">el-input>
    81. el-form-item>
    82. <el-form-item label="出版社" prop="publisher">
    83. <el-input v-model="updateForm.publisher">el-input>
    84. el-form-item>
    85. <el-form-item>
    86. <el-button type="primary" @click="updateBook">确定el-button>
    87. <el-button @click="cancelEdit">取消el-button>
    88. el-form-item>
    89. el-form>
    90. el-dialog>
    91. <template>
    92. <el-table
    93. :data="tableData"
    94. style="width: 100%"
    95. @selection-change="handleSelectionChange"
    96. >
    97. <el-table-column
    98. type="selection"
    99. width="55">
    100. el-table-column>
    101. <el-table-column
    102. type="index"
    103. width="50">
    104. el-table-column>
    105. <el-table-column
    106. prop="name"
    107. label="书名"
    108. align="center"
    109. >
    110. el-table-column>
    111. <el-table-column
    112. prop="type"
    113. label="类型"
    114. align="center"
    115. >
    116. el-table-column>
    117. <el-table-column
    118. prop="author"
    119. label="作者"
    120. align="center"
    121. >
    122. el-table-column>
    123. <el-table-column
    124. prop="publisher"
    125. label="出版社"
    126. align="center"
    127. >
    128. el-table-column>
    129. <el-table-column
    130. prop="address"
    131. label="操作"
    132. align="center"
    133. >
    134. <el-row>
    135. <el-button type="primary" @click="backView">修改el-button>
    136. <el-button type="danger" @click="delById">删除el-button>
    137. el-row>
    138. el-table-column>
    139. el-table>
    140. template>
    141. div>
    142. body>
    143. html>

    js

    1. <script src="../js/vue.js">script>
    2. <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    3. <script src="https://unpkg.com/element-ui/lib/index.js">script>
    4. <script src="https://cdn.bootcdn.net/ajax/libs/qs/6.11.0/qs.js">script>
    5. <script>
    6. new Vue({
    7. el:"#app",
    8. data:{
    9. // 添加表单
    10. bookForm: {
    11. name: '',
    12. type:'',
    13. author:'',
    14. publisher:'',
    15. },
    16. // 更新表单
    17. updateForm:{
    18. name: '',
    19. type:'',
    20. author:'',
    21. publisher:'',
    22. },
    23. tableData:[], // 当前页面要展示的分页列表数据
    24. dialogVisible:false, // 增加表单是否可见
    25. dialogEditVisible:false, // 编辑表单是否可见
    26. pagination:{}, // 分页模型数据,暂时弃用
    27. ids:[], // id数组
    28. selectedId:'', // 单个id
    29. // 复选框
    30. multipleSelection:[],
    31. },
    32. // 钩子函数,VUE对象初始化完成后自动执行
    33. created(){
    34. this.getAll();
    35. },
    36. methods:{
    37. // 添加
    38. saveBook(){
    39. axios.post("/books",this.bookForm).then((resp)=>{
    40. this.dialogVisible = false;
    41. this.getAll();
    42. this.$message({
    43. message: '添加成功!',
    44. type: 'success',
    45. center:true
    46. });
    47. });
    48. },
    49. // 复选框选中后执行的函数
    50. handleSelectionChange(val) {
    51. this.multipleSelection = val;
    52. },
    53. // 取消编辑提示
    54. cancelEdit(){
    55. this.dialogEditVisible = false;
    56. this.$message({
    57. showClose: true,
    58. message: '已取消编辑',
    59. center:true
    60. });
    61. },
    62. // 取消添加提示
    63. cancelAdd(){
    64. this.dialogVisible = false;
    65. this.$message({
    66. showClose: true,
    67. message: '已取消添加',
    68. center:true
    69. });
    70. },
    71. // 查询
    72. likeSelect(){
    73. axios.get(`/books/${this.bookForm.author}`).then((resp)=>{
    74. this.tableData = resp.data;
    75. })
    76. },
    77. // 删除单条数据
    78. delById(){
    79. for (let i = 0; i < this.multipleSelection.length; i++) {
    80. var selectionElement = this.multipleSelection[i];
    81. this.selectedId = selectionElement.id;
    82. }
    83. if (this.selectedId == null || this.selectedId.length < 1){
    84. this.$message({
    85. showClose: true,
    86. message: '请选中您要删除的数据',
    87. type: 'error',
    88. center:true
    89. });
    90. return;
    91. }
    92. axios.delete(`/books/${this.selectedId}`,).then((resp) => {
    93. this.getAll();
    94. this.$message({
    95. message: '删除成功!',
    96. type: 'success',
    97. center: true
    98. });
    99. });
    100. // 清空id
    101. this.selectedId = '';
    102. },
    103. // 批量删除
    104. delByIds(){
    105. this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
    106. confirmButtonText: '确定',
    107. cancelButtonText: '取消',
    108. type: 'warning'
    109. }).then(() => {
    110. this.ids = this.multipleSelection.map(item => item.id);
    111. if (this.ids.length < 1){
    112. this.$message.error('请选中您要删除的数据!').center=true;
    113. }
    114. // 转为JSON数据发送到后台
    115. this.ids = JSON.stringify(this.ids);
    116. axios({
    117. method:"delete",
    118. url:"/books",
    119. data:this.ids,
    120. headers: {
    121. 'Content-Type': 'application/json;charset=UTF-8'
    122. }
    123. }).then((resp)=>{
    124. this.getAll();
    125. this.$message({
    126. type: 'success',
    127. message: '删除成功!'
    128. });
    129. });
    130. // 清空id数组
    131. this.ids = [];
    132. }).catch(() => {
    133. this.$message({
    134. type: 'info',
    135. message: '您已取消删除',
    136. center:true
    137. });
    138. })
    139. },
    140. // 回显数据
    141. backView(){
    142. this.selectedId = this.multipleSelection.map(item => item.id);
    143. if (this.selectedId == null || this.selectedId.length < 1){
    144. this.$message({
    145. showClose: true,
    146. message: '请选中您要编辑的数据',
    147. type: 'error',
    148. center:true
    149. });
    150. return
    151. }
    152. this.dialogEditVisible = true;
    153. axios.get(`/books/${this.selectedId}`).then((resp)=>{
    154. this.updateForm = resp.data;
    155. });
    156. // 清空id
    157. this.selectedId = '';
    158. },
    159. // 更新数据
    160. updateBook(){
    161. axios.put("/books",this.updateForm).then((resp)=>{
    162. // 关闭表单
    163. this.dialogEditVisible = false;
    164. // 查询数据
    165. this.getAll();
    166. // 成功提示
    167. this.$message({
    168. showClose: true,
    169. message: '更新数据成功!',
    170. type: 'success',
    171. center:true
    172. });
    173. });
    174. },
    175. // 主页列表数据查询
    176. getAll(){
    177. axios.get("/books").then((resp)=>{
    178. this.tableData = resp.data;
    179. })
    180. },
    181. }
    182. })
    183. script>

    六、后端代码

    1.domain包 加载实体类

    1. public class Book {
    2. private Integer id;
    3. private String name;
    4. private String type;
    5. private String author;
    6. private String publisher;
    7. @Override
    8. public String toString() {
    9. return "Book{" +
    10. "id=" + id +
    11. ", name='" + name + '\'' +
    12. ", type='" + type + '\'' +
    13. ", author='" + author + '\'' +
    14. ", publisher='" + publisher + '\'' +
    15. '}';
    16. }
    17. public Book() {
    18. }
    19. public Book(Integer id, String name, String type, String author, String publisher) {
    20. this.id = id;
    21. this.name = name;
    22. this.type = type;
    23. this.author = author;
    24. this.publisher = publisher;
    25. }
    26. public Integer getId() {
    27. return id;
    28. }
    29. public void setId(Integer id) {
    30. this.id = id;
    31. }
    32. public String getName() {
    33. return name;
    34. }
    35. public void setName(String name) {
    36. this.name = name;
    37. }
    38. public String getType() {
    39. return type;
    40. }
    41. public void setType(String type) {
    42. this.type = type;
    43. }
    44. public String getAuthor() {
    45. return author;
    46. }
    47. public void setAuthor(String author) {
    48. this.author = author;
    49. }
    50. public String getPublisher() {
    51. return publisher;
    52. }
    53. public void setPublisher(String publisher) {
    54. this.publisher = publisher;
    55. }
    56. }

    2.dao数据层

    1. @Repository
    2. public interface BookDao {
    3. @Insert("insert into ev_books(name,type,author,publisher)values(#{name},#{type},#{author},#{publisher})")
    4. void add(Book book);
    5. @Delete("delete from ev_books where id=#{id}")
    6. void delete(Integer id);
    7. @Delete("")
    8. void deleteByIds(@Param("ids") int[] ids);
    9. @Update("update ev_books set name=#{name},type=#{type},author=#{author},publisher=#{publisher} where id=#{id}")
    10. void update(Book book);
    11. @Select("select * from ev_books where id=#{id}")
    12. Book getById(Integer id);
    13. @Select("select * from ev_books")
    14. List getAll();
    15. }

    3.service业务层

    BookService接口:

    1. public interface BookService {
    2. void add(Book book);
    3. void delete(Integer id);
    4. void deleteByIds(int[] ids);
    5. void update(Book book);
    6. Book getById(Integer id);
    7. List getAll();
    8. }

    BookService实现类:

    1. @Service
    2. public class BookServiceImpl implements BookService {
    3. @Autowired
    4. private BookDao bookDao;
    5. @Override
    6. public void add(Book book) {
    7. bookDao.add(book);
    8. }
    9. @Override
    10. public void delete(Integer id) {
    11. bookDao.delete(id);
    12. }
    13. @Override
    14. public void deleteByIds(int[] ids) {
    15. bookDao.deleteByIds(ids);
    16. }
    17. @Override
    18. public void update(Book book) {
    19. bookDao.update(book);
    20. }
    21. @Override
    22. public Book getById(Integer id) {
    23. return bookDao.getById(id);
    24. }
    25. @Override
    26. public List getAll() {
    27. return bookDao.getAll();
    28. }
    29. }

    4.controller控制层

    1. @RestController
    2. @RequestMapping("/books")
    3. public class BookController {
    4. @Autowired
    5. private BookService bookService;
    6. @PostMapping
    7. public String save(@RequestBody Book book){
    8. bookService.add(book);
    9. return "{'message':'success'}";
    10. }
    11. @DeleteMapping("/{id}")
    12. public String delete(@PathVariable Integer id){
    13. bookService.delete(id);
    14. return "{'message':'success'}";
    15. }
    16. @DeleteMapping
    17. public String deleteByIds(@RequestBody int[] ids){
    18. bookService.deleteByIds(ids);
    19. return "{'message':'success'}";
    20. }
    21. @PutMapping
    22. public String update(@RequestBody Book book){
    23. bookService.update(book);
    24. return "{'message':'success'}";
    25. }
    26. @GetMapping("/{id}")
    27. public Book getById(@PathVariable Integer id){
    28. return bookService.getById(id);
    29. }
    30. @GetMapping
    31. public List getAll(){
    32. return bookService.getAll();
    33. }
    34. }

    5.config配置

    ServletContainersInitConfig.class 用来配置servlet容器

    1. // 4.定义一个servlet容器启动的配置,在里面加载spring的配置
    2. public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    3. // 加载spring配置
    4. @Override
    5. protected Class[] getRootConfigClasses() {
    6. return new Class[]{SpringConfig.class};
    7. }
    8. // 加载springMVC配置
    9. @Override
    10. protected Class[] getServletConfigClasses() {
    11. return new Class[]{SpringMvcConfig.class};
    12. }
    13. // 设置哪些请求归属springMVC处理
    14. @Override
    15. protected String[] getServletMappings() {
    16. return new String[]{"/"};
    17. }
    18. // Post请求乱码处理
    19. @Override
    20. protected Filter[] getServletFilters() {
    21. CharacterEncodingFilter filter = new CharacterEncodingFilter("UTF-8");
    22. return new Filter[]{filter};
    23. }
    24. }

    MyBatisConfig.class 用来替换xml

    1. public class MyBatisConfig {
    2. @Bean
    3. public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
    4. SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
    5. ssfb.setTypeAliasesPackage("cn.itaxu.domain");
    6. ssfb.setDataSource(dataSource);
    7. return ssfb;
    8. }
    9. @Bean
    10. public MapperScannerConfigurer mapperScannerConfigurer(){
    11. MapperScannerConfigurer msc = new MapperScannerConfigurer();
    12. msc.setBasePackage("cn.itaxu.dao");
    13. return msc;
    14. }
    15. }

    SpringConfig.class 用来配置spring

    1. @Configuration
    2. @ComponentScan(value = "cn.itaxu",
    3. excludeFilters = @ComponentScan.Filter(
    4. type = FilterType.ANNOTATION,
    5. classes = Controller.class
    6. )
    7. )
    8. @PropertySource("classpath:jdbc.properties")
    9. @Import({JdbcConfig.class,MyBatisConfig.class})
    10. public class SpringConfig {
    11. }

    SpringMvcConfig.class 用来配置springMVC

    1. // 3.创建springmvc的配置文件,加载controller对应的bean
    2. @Configuration
    3. @ComponentScan({"cn.itaxu.controller","cn.itaxu.config"})
    4. @EnableWebMvc
    5. public class SpringMvcConfig {
    6. }

    SpringMvcSupport.class 用来放行一些静态资源

    1. @Configuration
    2. public class SpringMvcSupport extends WebMvcConfigurationSupport {
    3. @Override
    4. protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    5. // 当访问/pages/???的时候,走/pages目录下的内容
    6. registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    7. // 当访问/js/???的时候,走/js目录下的内容
    8. registry.addResourceHandler("/js/**").addResourceLocations("/js/");
    9. // 当访问/css/???的时候,走/css目录下的内容
    10. registry.addResourceHandler("/css/**").addResourceLocations("/css/");
    11. // 当访问/plugins/???的时候,走/plugins目录下的内容
    12. registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    13. }
    14. }

    六、效果图展示

     

     

     七、总结

     使用SSM框架开发更加的便捷,真正的实现了高内聚、低耦合,与传统的xml方式不同,代码更加的简洁、清晰,大大提高了开发效率。

  • 相关阅读:
    centos系统编译openssl和openssl-lib的rpm安装包
    DDIA读书笔记第八章——分布式系统的麻烦
    【ML】使用支持向量回归器进行时间序列预测
    AUTOSAR DEM (三):故障事件及故障错误码定义
    计算机视觉基础(8)——齐次坐标系与相机内外参
    ​打造企业自己代码规范IDEA插件(上)
    Kubernetes部署单元-Pod
    安装配置ingress-nginx支持https访问
    单元测试(unit testing)到底是什么?
    Aardio - 通过变量名将变量值整合到一串文本中
  • 原文地址:https://blog.csdn.net/weixin_64144937/article/details/127837121