案例演示
创建数据库
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0 ;
DROP TABLE IF EXISTS ` admin` ;
CREATE TABLE ` admin` (
` id` int ( 11 ) NOT NULL AUTO_INCREMENT ,
` username` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
` password` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
PRIMARY KEY ( ` id` ) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO ` admin` VALUES ( 1 , 'zhangsan' , '123456' ) ;
INSERT INTO ` admin` VALUES ( 2 , 'xiaozhu' , '123' ) ;
DROP TABLE IF EXISTS ` emp` ;
CREATE TABLE ` emp` (
` id` int ( 11 ) NOT NULL AUTO_INCREMENT ,
` name` varchar ( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
` age` int ( 11 ) NULL DEFAULT NULL ,
` salary` double ( 10 , 2 ) NULL DEFAULT NULL ,
PRIMARY KEY ( ` id` ) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO ` emp` VALUES ( 1 , '小张1' , 23 , 23000.00 ) ;
INSERT INTO ` emp` VALUES ( 2 , '小李2' , 24 , 2400.00 ) ;
INSERT INTO ` emp` VALUES ( 3 , '小白' , 25 , 2500.00 ) ;
INSERT INTO ` emp` VALUES ( 4 , '小王' , 25 , 1500.00 ) ;
INSERT INTO ` emp` VALUES ( 5 , '小红红' , 24 , 1500.00 ) ;
INSERT INTO ` emp` VALUES ( 6 , '小四' , 25 , 1500.00 ) ;
SET FOREIGN_KEY_CHECKS = 1 ;
创建后端项目
pom.xml 文件中引入依赖坐标
<?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> com.baizhi</ groupId>
< artifactId> helloworld_back</ artifactId>
< version> 1.0-SNAPSHOT</ version>
< 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>
</ 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> com.alibaba</ groupId>
< artifactId> druid</ artifactId>
< version> 1.2.5</ version>
</ dependency>
< dependency>
< groupId> mysql</ groupId>
< artifactId> mysql-connector-java</ artifactId>
< version> 5.1.38</ version>
</ dependency>
< dependency>
< groupId> org.mybatis.spring.boot</ groupId>
< artifactId> mybatis-spring-boot-starter</ artifactId>
< version> 2.1.4</ version>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-data-redis</ artifactId>
</ dependency>
</ dependencies>
< build>
< plugins>
< plugin>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-maven-plugin</ artifactId>
</ plugin>
</ plugins>
</ build>
</ project>
application.properties
server. port= 8989
spring. datasource. type = com. alibaba. druid. pool. DruidDataSource
spring. datasource. driver- class- name= com. mysql. jdbc. Driver
spring. datasource. url= jdbc:mysql:
spring. datasource. username= root
spring. datasource. password= root
mybatis. type - aliases- package= com. baizhi. entity
mybatis. mapper- locations= classpath:com/ baizhi/ mapper/ * . xml
spring. redis. host= 127.0 .0 .1
spring. rabbitmq. host= 6379
logging. level . com. baizhi. dao= debug
实现用户登录、用户退出登录功能
com.baizhi.constants.RedisPrefix
(常量)
public interface RedisPrefix {
String TOKEN = "TOKEN_" ;
}
com.baizhi.controller.AdminController
(完成用户登录、退出登录功能)
@RestController
@CrossOrigin
public class AdminController {
private static final Logger log = LoggerFactory . getLogger ( AdminController . class ) ;
@Resource
private AdminService adminService;
@Autowired
private RedisTemplate redisTemplate;
@DeleteMapping ( "/token" )
public void token ( String token) {
redisTemplate. delete ( RedisPrefix . TOKEN + token) ;
}
@GetMapping ( "/token" )
public Admin admin ( String token) {
log. info ( "接收token信息:{} " , token) ;
return ( Admin ) redisTemplate. opsForValue ( ) . get ( RedisPrefix . TOKEN + token) ;
}
@PostMapping ( "login" )
public Map < String , Object > login ( @RequestBody Admin admin, HttpSession session) {
Map < String , Object > result = new HashMap < > ( ) ;
log. info ( "admin username:{} password:{}" , admin. getUsername ( ) , admin. getPassword ( ) ) ;
try {
Admin adminDB = adminService. login ( admin) ;
String token = session. getId ( ) ;
redisTemplate. opsForValue ( ) . set ( RedisPrefix . TOKEN + token, adminDB, 30 , TimeUnit . MINUTES) ;
result. put ( "success" , true ) ;
result. put ( "token" , token) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
result. put ( "success" , false ) ;
result. put ( "msg" , e. getMessage ( ) ) ;
}
return result;
}
@GetMapping ( "/admin" )
public Admin admin ( Integer id) {
return this . adminService. queryById ( id) ;
}
}
com.baizhi.service.AdminService
public interface AdminService {
Admin login ( Admin admin) ;
}
com.baizhi.service.impl.AdminServiceImpl
@Service ( "adminService" )
@Transactional
public class AdminServiceImpl implements AdminService {
@Resource
private AdminDao adminDao;
@Override
@Transactional ( propagation = Propagation . SUPPORTS)
public Admin login ( Admin admin) {
Admin adminDB = adminDao. findByUserName ( admin. getUsername ( ) ) ;
if ( adminDB == null ) {
throw new RuntimeException ( "用户名输入错误!!" ) ;
}
if ( ! adminDB. getPassword ( ) . equals ( admin. getPassword ( ) ) ) {
throw new RuntimeException ( "密码输入错误!!!" ) ;
}
return adminDB;
}
}
public interface AdminDao {
Admin findByUserName ( String username) ;
}
com.baizhi.mapper.AdminDao.xml
< select id = " findByUserName" parameterType = " string" resultType = " Admin" >
select id, username, password
from admin
where username = #{username}
</ select>
使用 Vue Cli 创建前端项目
helloworld\src\utils\request.js
import axios from "axios" ;
const instance = axios. create ( {
baseURL : 'http://localhost:8989' ,
timeout : 5000 ,
} )
instance. interceptors. request. use ( config => {
console. log ( "请求拦截器" )
return config;
} )
instance. interceptors. response. use ( response => {
console. log ( "响应拦截器" )
return response;
} ) , err => {
console. log ( "响应出现错误时进入的拦截器" )
}
export default instance;
helloworld\src\views\Index.vue
< template>
< div>
< h1> 欢迎进入员工管理系统首页 < span v- show= "isLogin" > 欢迎: { { admin. username } } < / span> < / h1>
< a href= "javascript:;" @click= "logout" v- show= "isLogin" > 退出登录< / a>
< router- link v- show= "!isLogin" : to= "{name:'Login'}" > 立即登录< / router- link>
< hr/ >
< a href= "#/index/emps" > 员工列表< / a>
< a href= "#/index/depts" > 部门列表< / a>
< a href= "#/index/orders" > 订单列表< / a>
< a href= "#/index/users" > 用户列表< / a>
< router- view> < / router- view>
< / div>
< / template>
< script>
import instance from "../utils/request" ;
export default {
name : "Index" ,
data ( ) {
return {
admin : { }
}
} ,
methods : {
logout ( ) {
let token = localStorage. getItem ( "token" ) ;
instance. delete ( "/token?token=" + token) . then ( res => {
this . admin = { } ;
} ) ;
}
} ,
computed : {
isLogin ( ) {
return this . admin. username;
} ,
} ,
created ( ) {
let token = localStorage. getItem ( "token" ) ;
instance. get ( "/token?token=" + token) . then ( res => {
this . admin = res. data;
} ) ;
}
}
< / script>
< style scoped>
< / style>
helloworld\src\views\Login.vue
< template>
< div>
< form>
用户名:< input type= "text" v- model= "admin.username" > < br/ >
密码:< input type= "text" v- model= "admin.password" > < br/ >
< input type= "button" value= "登录" @click= "login" >
< / form>
< / div>
< / template>
< script>
import instance from "../utils/request" ;
export default {
name : "Login" ,
data ( ) {
return {
admin : { }
}
} ,
methods : {
login ( ) {
instance. post ( "/login" , this . admin) . then ( res => {
const result = res. data;
if ( result. success) {
localStorage. setItem ( "token" , result. token) ;
this . $router. push ( { name : 'Index' } ) ;
} else {
alert ( result. msg) ;
}
} ) ;
}
}
}
< / script>
< style scoped>
< / style>
helloworld\src\router\index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue. use ( Router)
const originalPush = Router . prototype. push;
Router . prototype. push = function push ( location ) {
return originalPush . call ( this , location) . catch ( err => err)
} ;
export default new Router ( {
routes : [
{
path : '/' ,
redirect : '/index'
} ,
{
path : '/login' ,
name : 'Login' ,
component : ( ) => import ( '../views/Login' )
} ,
{
path : '/index' ,
name : 'Index' ,
component : ( ) => import ( '../views/Index' ) ,
children : [
{
path : 'emps' ,
name : 'Emps' ,
component : ( ) => import ( '../views/emp/Index' )
} ,
{
path : 'depts' ,
name : 'Depts' ,
component : ( ) => import ( '../views/dept/Index' )
} ,
{
path : 'orders' ,
name : 'Orders' ,
component : ( ) => import ( '../views/order/Index' )
} ,
{
path : 'users' ,
name : 'Users' ,
component : ( ) => import ( '../views/user/Index' )
}
]
} ,
{
path : '*' ,
component : ( ) => import ( '../views/404' )
}
]
} )
helloworld\src\views\404.vue
< template>
< div>
< h2> 404 Not Found 当前页面走丢了!!!点我立即回到
< router- link : to= "{name:'Index'}" > 主页< / router- link>
< / h2>
< / div>
< / template>
< script>
export default {
name : "404"
}
< / script>
< style scoped>
< / style>
实现员工列表(增删改查)功能
com.baizhi.controller.EmpController
@RestController
@CrossOrigin
public class EmpController {
@Resource
private EmpService empService;
@GetMapping ( "/emp" )
public Emp emp ( Integer id) {
return this . empService. queryById ( id) ;
}
@GetMapping ( "/emps" )
public List < Emp > emps ( ) {
return empService. queryAllByLimit ( 0 , Integer . MAX_VALUE) ;
}
@PostMapping ( "/emp" )
public void add ( @RequestBody Emp emp) {
if ( StringUtils . isEmpty ( emp. getId ( ) ) ) {
empService. insert ( emp) ;
} else {
empService. update ( emp) ;
}
}
@DeleteMapping ( "/emp/{id}" )
public void delete ( @PathVariable ( "id" ) Integer id) {
empService. deleteById ( id) ;
}
@GetMapping ( "/emp/{id}" )
public Emp getById ( @PathVariable ( "id" ) Integer id) {
return this . empService. queryById ( id) ;
}
}
helloworld/src/views/emp/Index.vue
< template>
< div>
< h2> 员工列表页面< / h2>
< button @click= "addRow" > 添加员工信息< / button>
< table border= "1" width= "100%" style= "text-align: center" >
< tr>
< th> 编号< / th>
< th> 姓名< / th>
< th> 年龄< / th>
< th> 工资< / th>
< th> 操作< / th>
< / tr>
< tr v- for = "(emp,index) in emps" : key= "emp.id" >
< td v- text= "emp.id" > < / td>
< td v- text= "emp.name" > < / td>
< td v- text= "emp.age" > < / td>
< td v- text= "emp.salary" > < / td>
< td> < a href= "javascript:;" @click= "detailRow(emp.id)" > 修改< / a> < a href= "javascript:;" @click= "delRow(emp.id)" > 删除< / a> < / td>
< / tr>
< / table>
< br/ >
< form>
< div v- show= "emp.id" >
编号:< input type= "text" readonly v- model= "emp.id" > < br/ >
< / div>
姓名:< input type= "text" v- model= "emp.name" > < br/ >
年龄:< input type= "text" v- model= "emp.age" > < br/ >
工资:< input type= "text" v- model= "emp.salary" > < br/ >
< input type= "button" value= "保存|修改" @click= "saveOrUpdate(emp.id)" >
< / form>
< / div>
< / template>
< script>
import instance from "../../utils/request" ;
export default {
name : "Index" ,
data ( ) {
return {
emps : [ ] ,
emp : { }
}
} ,
methods : {
findAll ( ) {
instance. get ( "/emps" ) . then ( res => {
console. log ( res. data)
this . emps = res. data
} )
} ,
addRow ( ) {
this . emp = { }
} ,
detailRow ( id ) {
instance. get ( "/emp/" + id) . then ( res => {
this . emp = res. data;
} )
} ,
saveOrUpdate ( ) {
if ( ! this . emp. name) {
alert ( "请输入员工姓名" ) ;
return false ;
}
if ( ! this . emp. age) {
alert ( "请输入员工年龄" ) ;
return false ;
}
if ( ! this . emp. salary) {
alert ( "请输入员工工资" ) ;
return false ;
}
var _this = this ;
instance. post ( "/emp/" , this . emp) . then ( res => {
this . emp = { } ;
this . findAll ( ) ;
} ) . catch ( err => {
console. log ( err)
} )
} ,
delRow ( id ) {
if ( window. confirm ( "您确定要删除吗?" ) ) {
instance. delete ( "/emp/" + id) . then ( res => {
this . findAll ( ) ;
} )
}
}
} ,
created ( ) {
this . findAll ( ) ;
} ,
}
< / script>
< style scoped>
< / style>
vue cli 公共组件的提取
将 helloworld/src/views/Index.vue
中的<div>
包裹的内容提取出来,然后在Index.vue
中使用组件