美文网首页
(四)spring boot + jpa + mysql 后台

(四)spring boot + jpa + mysql 后台

作者: 走走婷婷1215 | 来源:发表于2018-02-07 19:06 被阅读1539次

    上篇文章:https://www.jianshu.com/p/f062c9ff7b48
    这一篇主要是完成spring boot 与 mysql的连接,并使用jpa,来完成一个后台管理系统的增删改查功能。
    先来看最后的效果图:

    后台管理系统.png
    前后台分离后,每个人的习惯也不一样,有的喜欢从前台开始写,有的喜欢从后台开始写,而我习惯从后往前写。
    我们先来看后端代码结构:
    代码结构
    pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>demo.ptt</groupId>
        <artifactId>springDemo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>springDemo</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.4.RELEASE</version>
        </parent>
    
        <dependencies>
            <!-- test -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!-- thymeleaf模版 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <!-- 热部署 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>commons-dbcp</groupId>
                <artifactId>commons-dbcp</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

    重新创建一个控制器:ContractController,增删改查都在这里面。
    ContractController.java

    package demo.ptt.console.controllers;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    import demo.ptt.console.dto.ExecuteResult;
    import demo.ptt.console.po.Contract;
    import demo.ptt.console.services.ContractServer;
    
    @RestController
    @RequestMapping("contract")
    public class ContractController {
    
        @Autowired
        private ContractServer server;
    
        @PostMapping("save")
        public ExecuteResult<?> save(@RequestBody Contract param) {
            return server.save(param);
        }
    
        @PostMapping("findAll")
        public @ResponseBody List<Contract> findAll() {
            return server.findAll();
        }
    
        @GetMapping("remove/{id}")
        public ExecuteResult<?> remove(@PathVariable String id) {
            return server.remove(id);
        }
    
    }
    
    

    其中控制器中用到了一个封装类
    ExecuteResult.java
    package demo.ptt.console.dto;

    import java.io.Serializable;

    public final class ExecuteResult<T> implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -4467073382353735654L;
    
    /**
     * 执行成功
     */
    private boolean success;
    
    private T value;
    
    /**
     * 错误码
     */
    private int errorCode;
    
    /**
     * 错误信息
     */
    private String message;
    
    public boolean isSuccess() {
        return success;
    }
    
    public T getValue() {
        return value;
    }
    
    public void setValue(T value) {
        this.value = value;
    }
    
    public int getErrorCode() {
        return errorCode;
    }
    
    public String getMessage() {
        return message;
    }
    
    private ExecuteResult() {
    
    }
    
    public static <T> ExecuteResult<T> ok() {
        ExecuteResult<T> result = new ExecuteResult<>();
        result.errorCode = 0;
        result.success = true;
        return result;
    }
    
    public static <T> ExecuteResult<T> ok(T value) {
        ExecuteResult<T> result = new ExecuteResult<T>();
        result.errorCode = 0;
        result.success = true;
        result.value = value;
        return result;
    }
    
    public static <T> ExecuteResult<T> fail(String message) {
        ExecuteResult<T> result = new ExecuteResult<>();
        result.errorCode = -1;
        result.success = false;
        result.message = message;
        return result;
    }
    
    public static <T> ExecuteResult<T> fail(int errorCode) {
        ExecuteResult<T> result = new ExecuteResult<>();
        result.errorCode = errorCode;
        result.success = false;
        return result;
    }
    
    public static <T> ExecuteResult<T> fail(int errorCode, String message) {
        ExecuteResult<T> result = new ExecuteResult<>();
        result.errorCode = errorCode;
        result.success = false;
        result.message = message;
        return result;
    }
    

    }
    它可以返回我们的处理状态,在前端显示。
    ContractServer.java

    package demo.ptt.console.services;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import demo.ptt.console.dto.ExecuteResult;
    import demo.ptt.console.po.Contract;
    import demo.ptt.console.repository.ContractRepository;
    
    @Service
    public class ContractServer {
    
        @Autowired
        private ContractRepository repository;
    
        public ExecuteResult<?> save(Contract param) {
            if (param == null) {
                return ExecuteResult.fail("参数为空");
            }
            repository.save(param);
            return ExecuteResult.ok();
        }
    
        public @ResponseBody List<Contract> findAll() {
            return repository.findAll();
        }
        
        public ExecuteResult<?> remove(String id) {
            if (StringUtils.isEmpty(id)) {
                return ExecuteResult.fail("参数为空");
            }
            Contract entity = repository.findOne(id);
            if (entity != null) {
                repository.delete(id);;
            }
            return ExecuteResult.ok();
        }
    
    }
    
    

    ContractRepository.java

    package demo.ptt.console.repository;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    
    import demo.ptt.console.po.Contract;
    
    public interface ContractRepository extends JpaRepository<Contract, String> {
    
    }
    
    

    Contract.java

    package demo.ptt.console.po;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    import org.hibernate.annotations.GenericGenerator;
    
    @Entity
    @Table(name = "t_contract")
    public class Contract {
        
        @Id
        @GeneratedValue(generator = "uuid")
        @GenericGenerator(name = "uuid", strategy = "uuid2")
        @Column(name = "contract_id", length = 36)
        public String id;
        
        /**
         * 姓名
         */
        @Column(name = "name", length = 50)
        public String name;
        
        /**
         * 姓别
         */
        @Column(name = "sex", length = 50)
        public String sex;
        
        /**
         * 手机号
         */
        @Column(name = "phone", length = 50)
        public String phone;
        
        /**
         * 身份证号
         */
        @Column(name = "id_card", length = 50)
        public String idCard;
        
        /**
         * 住址
         */
        @Column(name = "address", length = 50)
        public String address;
        
        /**
         * 省略 get  set
         */
    
    }
    
    

    除了这些以外,我们还需要添加配置:
    application.properties

    server.port=18062  
    spring.profiles.active=dev
    
    spring.datasource.initialize=false
    spring.datasource.url=jdbc:mysql://localhost:3306/www
    spring.datasource.username=root
    spring.datasource.password=
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
    spring.jpa.show-sql=true
    spring.jpa.hibernate.ddl-auto=update
    

    其中:

    spring.datasource.initialize=false
    spring.datasource.url=jdbc:mysql://localhost:3306/www
    spring.datasource.username=root
    spring.datasource.password=
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    

    是连接数据库的配置,我们需要在本地数据库创建www这个数据库,当然,名字数据库的名字可以任意起,不过一定要对应上。

    spring.jpa.show-sql=true
    spring.jpa.hibernate.ddl-auto=update
    

    这两句是省去我们建表的麻烦,建好数据库后,启动后台代码,这两行配置就会自动在数据库中创建表,前提是我们必须把实体类Contract已经写好了。

    现在我们来看前端代码结构:


    前端代码结构.png

    index.js

    import Vue from 'vue'
    import Router from 'vue-router'
    
    import Dashboard from '@/components/Dashboard'
    import Main from '@/components/Main'
    
    
    
    Vue.use(Router)
    
    let routes = [{
        path:'/',
        component: Main,
        hidden: true,
        children: [{
            path: '/',
            component:Dashboard,
            name:'首页'
        }]
    }]
    
    import {
        SystemRouter
    } from './system'
    
    for (let i in SystemRouter){
        routes.push(SystemRouter[i])
    }
    
    const router = new Router({
        routes: routes
    })
    
    export default router;
    
    

    system.js

    import Main from '@/components/Main'
    import Contract from '@/components/system/Contract'
    
    const SystemRouter = [{
        path: '/system',
        name: '系统中心',
        component: Main,
        iconCls: 'fa fa-address-card',
        children: [{
            path: '/system/contract',
            component: Contract,
            name: '联系人管理'
        }]
    }]
    
    export {
        SystemRouter
    }
    

    componments/system/Contract.vue

    <template>
        <section>
            <el-col :span="24" class="toolbar" style="padding-bottom: 0px; height: 100px;">
                <el-button size="mini" @click="save">添加联系人</el-button>
            </el-col>
    
            <el-table :data="rows" highlight-current-row stripe border v-loading="listLoading" style="width: 100%;">
                <el-table-column prop="name" :show-overflow-tooltip="true" label="姓名" min-width="110" sortable="sortable" />
                <el-table-column prop="sex" :show-overflow-tooltip="true" label="性别" min-width="170" sortable="sortable" />
                <el-table-column prop="phone" :show-overflow-tooltip="true" label="手机号" min-width="170" sortable="sortable" />
                <el-table-column prop="idCard" :show-overflow-tooltip="true" label="身份证号" min-width="170" sortable="sortable" />
                <el-table-column prop="address" :show-overflow-tooltip="true" label="住址" min-width="170" sortable="sortable" />
                <el-table-column label="操作" width="180" align="center" fixed="right">
                    <template slot-scope="scope">
                        <el-button size="small" @click="edit(scope.row)">修改</el-button>
                        <el-button size="small" type="danger" @click="remove(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
    
            <el-dialog :title="title" width="80%" :visible.sync="formVisible" :close-on-click-modal="false">
                <el-form :model="form" label-width="120px" ref="form">
                    <el-form-item label="姓名">
                        <el-input v-model="form.name" auto-complete="off" />
                    </el-form-item>
                    <el-form-item label="姓别">
                        <el-input v-model="form.sex" auto-complete="off" />
                    </el-form-item>
                    <el-form-item label="手机号">
                        <el-input v-model="form.phone" auto-complete="off" />
                    </el-form-item>
                    <el-form-item label="身份证号">
                        <el-input v-model="form.idCard" auto-complete="off" />
                    </el-form-item>
                    <el-form-item label="住址">
                        <el-input v-model="form.address" auto-complete="off" />
                    </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                    <el-button @click.native="formVisible = false">取消</el-button>
                    <el-button type="success" @click="submit" :loading="loading">通过</el-button>
                </div>
            </el-dialog>
        </section>
    </template>
    <script>
        import {
            Save,
            GetAll,
            Remove
        } from '@/api/main/contract'
    
        let data = () => {
            return {
                formVisible: false,
                loading: false,
                form: {},
                rows: [],
                listLoading: false,
                title: ''
            }
        }
    
        let save = function() {
            this.title = "添加联系人";
            this.formVisible = true
            this.loading = false
            this.form = {}
            this.getRows()
        }
    
        let submit = function() {
            Save(this.form).catch(() => this.listLoading = false).then(res => {
                this.formVisible = false
                if(!res.data.success) {
                    this.$message({
                        type: 'error',
                        message: res.data.message
                    })
                    return
                }
                this.$message({
                    type: 'success',
                    message: '添加成功!'
                })
                this.getRows()
            })
        }
    
        let getRows = function() {
            this.listLoading = true
            GetAll().then(res => {
                this.rows = res.data
                this.listLoading = false
            })
        }
    
        let edit = function(row) {
            this.formVisible = true;
            this.title = "编辑";
            this.form = Object.assign({}, row);
        }
    
        let remove = function(row) {
            this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                if(this.listLoading)
                    return
                this.listLoading = true
                Remove(row.id).catch(() => this.listLoading = false).then(res => {
                    this.listLoading = false
                    if(!res.data.success) {
                        this.$message({
                            type: 'error',
                            message: res.data.message
                        })
                        return
                    }
                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    })
                    this.getRows()
                })
            }).catch(() => {});
        }
    
        export default {
            data: data,
            methods: {
                getRows: getRows,
                save: save,
                submit: submit,
                edit: edit,
                remove: remove
            },
            mounted: function() {
                this.getRows();
            }
        }
    </script>
    <style>
    
    </style>
    

    api/main/contract.js

    import axios from 'axios';
    
    let base = '/api/contract'
    
    export const Save = params => {
      return axios.post(base + '/save', params);
    }
    
    export const GetAll = params => {
      return axios.post(base + '/findAll', params);
    }
    
    export const Remove = params => {
      return axios.get(base + '/remove/' + params);
    }
    

    将前端代码跑起来,整个系统就完成了,可以去试试奥。
    我这里写的比较粗,基本的代码讲解都没有,但是都是一些很简单很简单的东西,去了解了解就可以了。前端都是用的现成的组件,不了解的可以去看看Element UI,后端增删改查操作也都是用的JPA提供的简单封装好的方法,不了解的可以去查查。
    完整代码克隆地址:https://code.aliyun.com/zouzoutingting/console.git

    相关文章

      网友评论

          本文标题:(四)spring boot + jpa + mysql 后台

          本文链接:https://www.haomeiwen.com/subject/qfpazxtx.html