spring cloud vue thymeleaf实现CRUD的简单案例

现在关于Vue的实例说明很少,最近由于给学生们讲课,自己亲自做了一个Demo,贴出来与大家共享,还望大家多多批评指点。

项目架构:

1:创建pom(student-vue)项目,并导入如下依赖:

<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
    <artifactId>student-vue</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>student-base</module>
        <module>student-erueka</module>
        <module>student-view</module>
    </modules>
    <packaging>pom</packaging>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath />
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

2:创建注册中心模块:student-eureka、导入如下依赖:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>student-vue</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>student-erueka</artifactId>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
    </dependencies>

</project>

配置文件:application.yaml

#注册中心配置
server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

主类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class,args);
    }
}

3:创建DAO模块:student-base

导入如下依赖:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>student-vue</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>student-base</artifactId>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

</project>

启动类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@SpringBootApplication
@EnableDiscoveryClient
public class BaseApplication {

    @Bean
    public BCryptPasswordEncoder encoder(){return  new BCryptPasswordEncoder();}

    public static void main(String[] args) {
        SpringApplication.run(BaseApplication.class,args);
    }
}

实体类:


import javax.persistence.*;
import java.io.Serializable;

@Entity
@Data
@Table(name="tb_student")
public class Student implements Serializable {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String username;
    private String password;
    private String email;

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

Dao:

@Repository
public interface StudentDao extends JpaRepository<Student,Integer> {


    /**
     * 登录:根据用户名称查询对象
     * @param username
     * @return
     */
    Student findStudentByUsername(String username);

    /**
     * 验证用户名唯一
     * @param username
     * @return
     */
    Integer countByUsername(String username);
    
}

业务类:

import com.bw.dao.StudentDao;
import com.bw.pojo.Student;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
@Transactional
public class StudentService {

    @Resource
    private StudentDao studentDao;

    @Resource
    private BCryptPasswordEncoder encoder;

    /**
     * 添加学生
     * 对密码进行加密
     * @param student
     * @return
     */
    public Student addStudent(Student student){
         //对密码进行加密
         student.setPassword(this.encoder.encode(student.getPassword()));
         return this.studentDao.saveAndFlush(student);
    }

    public Student login(String username,String password){
        //首先根据用户名称查询是否有该对象
        Student student= this.studentDao.findStudentByUsername(username);
        //根据对象获取数据库的密码
        if(student.getPassword()!=null) {
            String pwd = student.getPassword();
            boolean flag = this.encoder.matches(password, pwd);//顺序不能错误,第一个必须是string
            if (student != null && flag) {//对象存在并且密码是正确的:登录成功
                return student;
            }
        }
        return  null;
    }

    /**
     * 列表
     * @return
     */
    public List<Student> findAll(){
        return this.studentDao.findAll();
    }

    /**
     * 修改
     * @param student
     * @return
     */
    public Student update(Student student){
        student.setPassword(this.encoder.encode(student.getPassword()));
        return this.studentDao.saveAndFlush(student);
    }

    /**
     * 根据id进行删除
     * @param id
     */
    public void delete(int id){
        this.studentDao.deleteById(id);
    }

    /**
     * 根据id查询
     * @param id
     * @return
     */
    public Student findById(int id){
        return this.studentDao.findById(id).get();
    }

    /**
     * 验证用户名称是否唯一
     * @param username
     * @return
     */
    public  boolean hasUsername(String username){
        return this.studentDao.countByUsername(username)>=1;
    }

}

控制器:

import com.bw.pojo.Student;
import com.bw.service.StudentService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@CrossOrigin
@RequestMapping("/base")
public class StudentController {

    @Resource
    private StudentService studentService;

    /**
     * 添加
     * @param student
     * @return
     */
    @RequestMapping(value = "/add",method = RequestMethod.POST)
    public Student add(@RequestBody Student student){
        return this.studentService.addStudent(student);
    }

    /**
     * 列表
     * @return
     */
    @RequestMapping("/stus")
    public List<Student> findAll(){
        return this.studentService.findAll();
    }

    /**
     * 查询
     * @param id
     * @return
     */
    @RequestMapping(value = "/find/{id}",method = RequestMethod.GET)
    public Student findOne(@PathVariable("id") int id){
        return this.studentService.findById(id);
    }

    /**
     * 修改
     * @param student
     * @return
     */
    @RequestMapping(value = "/update",method = RequestMethod.PUT)
    public Student modify(@RequestBody Student student){
        return this.studentService.update(student);
    }

    /**
     * 删除
     * @param id
     * @return
     */
    //@RequestMapping(value = "/delete/{id}",method = RequestMethod.DELETE)
    @RequestMapping(value = "/delete/{id}",method=RequestMethod.GET)
    public boolean delete(@PathVariable("id")int id){
          try {
              this.studentService.delete(id);
              return  true;
          }catch (Exception e){
              e.printStackTrace();
              return  false;
          }
    }

    /**
     * 登录
     * @param student
     * @return
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public Student login(@RequestBody Student student){

        return this.studentService.login(student.getUsername(),student.getPassword());
    }
}

加密工具类:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
          http
                  .authorizeRequests()
                  .antMatchers("/**").permitAll() //所有路径放行
                  .anyRequest().authenticated()
                  .and().csrf().disable();

    }
}

4:视图模块:student-view

pom:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>student-vue</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>student-view</artifactId>

    <dependencies>
        <!-- 导入DAO模块 -->
        <dependency>
            <artifactId>student-base</artifactId>
            <groupId>org.example</groupId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.webjars/vue -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>vue</artifactId>
            <version>2.6.11</version>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.1.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.webjars.bowergithub.axios/axios -->
        <dependency>
            <groupId>org.webjars.bowergithub.axios</groupId>
            <artifactId>axios</artifactId>
            <version>0.18.0</version>
        </dependency>


    </dependencies>

</project>

启动类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ViewApplication {

    public static void main(String[] args) {
        SpringApplication.run(ViewApplication.class,args);
    }
}

配置文件:

#界面层配置
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
    instance:
      prefer‐ip‐address: true
server:
  port: 8763
feign:
  hystrix:
    enabled: true
spring:
  application:
    name: user-view
  datasource:
    hikari:
      username: root
      password: root
    url: jdbc:mysql:///test?serverTimezone=UTC

Feign接口:


import com.bw.pojo.Student;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@FeignClient(value = "user-service")
public interface StudentFeignService{

    @RequestMapping("/base/stus") //调用user-service 的控制器中的/stus
    public List<Student> students();

    @RequestMapping("/base/delete/{id}")
    boolean delete(@PathVariable("id") int id);

    @PostMapping(value = "/base/add")
    Student add(Student student);

    @GetMapping("/base/find/{id}")
    Student findById(@PathVariable("id") int id);

    @RequestMapping(value = "/base/update",method = RequestMethod.PUT)
    Student update(Student student);
}

控制器(结果)

import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController //返回结果的控制器
@CrossOrigin
public class ViewController {

    @Resource
    private StudentFeignService studentFeignService;

    @RequestMapping("/findAll")
    public List<Student> findAll(){
        return this.studentFeignService.students();
    }

    @RequestMapping("{id}/del")
    public  boolean delete(@PathVariable("id")int id){
        return this.studentFeignService.delete(id);
    }

    @GetMapping("/show")
    public Student findById(int id){
        System.out.println(".....show ............."+id);
        return this.studentFeignService.findById(id);
    }
}

控制器(url)

package bw.song.view.controller;

import bw.song.view.service.StudentFeignService;
import com.bw.pojo.Student;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.RequestMapping;

import javax.annotation.Resource;

@Controller //跳转页面的控制器
public class UrlController {

    @Resource
    private StudentFeignService studentFeignService;

    @RequestMapping("/")
    public String index(){
        return "list";
    }

    @GetMapping("/save")
    public String toadd(){
        return "add";
    }

    @PostMapping("/save")
    public String add(Student student, Model model){
         Student stu=this.studentFeignService.add(student);
         if(stu!=null){
             return "redirect:/";
         }else{
             model.addAttribute("mess","添加失败!");
             return "add";
         }
    }

    @PostMapping("/modify")
    public String update(Student student, Model model){
        Student stu=this.studentFeignService.update(student);
        if(stu!=null){
            return "redirect:/";
        }else{
            model.addAttribute("mess","修改失败!");
            return "update";
        }
    }

    @GetMapping("/find")
    public String find(int id){
        System.out.println("---find----------->>"+id);
        return "update";
    }
}

界面:list.html

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="webjars/jquery/3.1.1/jquery.min.js"></script>
    <script src="webjars/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="webjars/bootstrap/3.3.5/css/bootstrap.min.css">
    <!--导入vue-->
    <script src="webjars/vue/2.6.11/vue.min.js"></script>
    <script src="webjars/axios/dist/axios.min.js"></script>
    
</head>
<body>
   <h1>列表</h1>
   <div class="container" id="app">
        <br>
       <table class="table table-hover table-bordered">
            <tr>
                <td>编号</td><td>账号</td><td>密码</td><td>邮箱</td>
                <td>
                    <button class="btn btn-success" onclick="location='save'">添加</button>
                </td>
            </tr>
            <tr v-for="stu in blist">
                 <td>{{stu.id}}</td>
                <td>{{stu.username}}</td>
                <td>{{stu.password}}</td>
                <td>{{stu.email}}</td>
                <td>
                    <button class="btn btn-warning" v-on:click="greet(stu.id)" >删除</button>
                    <button class="btn btn-primary" v-on:click="find(stu.id)" >修改</button>
                </td>
            </tr>
       </table>

   </div>
     <script src="list.js"></script>
</body>
</html>

list.js

new Vue({
    el: "#app",
    data: {blist: []},
    created:function(){
        axios.get("findAll").then(req => {this.blist = req.data});
    },
    methods: {
        find: function(id){
             //请求修改页面
             location="find?id="+id;
        },
        greet: function (id) {
            alert(id);
            if(confirm("确认吗?")){
                $.get(
                    id+"/del",
                    function (obj) {
                        if(obj){
                            alert("ok");
                            location.reload();
                        }else{
                            alert("Sorry");
                        }
                    }
                )
            }
        }
    }
});

修改页面:update.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="webjars/jquery/3.1.1/jquery.min.js"></script>
    <script src="webjars/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="webjars/bootstrap/3.3.5/css/bootstrap.min.css">
    <!--导入vue-->
    <script src="webjars/vue/2.6.11/vue.min.js"></script>
    <script src="webjars/axios/dist/axios.min.js"></script>
</head>
<body>
   <h1>修改</h1>
   <div class="container" id="app" >
           <form method="post" action="modify">
               <input type="hidden" name="id" v-model="user.id">
                账号:<input type="text" name="username" v-model="user.username" required="required"><br>
               密码:<input type="text" name="password" v-model="user.password" required="required"><br>
               邮箱:<input type="text" name="email" v-model="user.email" required="required"><br>
               <button class="btn btn-success">修改</button>
           </form>
   </div>
<script>
     new Vue({
         el: "#app",
         data: {user:""},
         created:function(){
             var m=location.toString();
             id= m.substring(m.lastIndexOf("=")+1);
             axios.get("show?id="+id).then(req => {this.user = req.data});
         }
     })
</script>
</body>
</html>

添加页面:add.html

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="webjars/jquery/3.1.1/jquery.min.js"></script>
    <script src="webjars/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="webjars/bootstrap/3.3.5/css/bootstrap.min.css">
 
</head>
<body>
   <h1>添加</h1>
   <div class="container" >
           <form method="post">
                账号:<input type="text" name="username" required="required"><br>
               密码:<input type="text" name="password" required="required"><br>
               邮箱:<input type="text" name="email" required="required"><br>
               <button class="btn btn-success">添加</button>
           </form>
   </div>

</body>
</html>

源代码下载:https://gitee.com/tonysong1110/my-spring-cloud.git

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值