springmvc和mybatis——京淘电商项目

springmvc和mybatis——京淘电商项目

一.技术路线

开发工具:IDEA、HBuilder
技术框架:springmvc、mybatis
数据库:mysql8
前端框架:vue

二.项目分析

在这里插入图片描述

1.主站用户注册

在这里插入图片描述

2.前端主站

在这里插入图片描述

3.后台管理

在这里插入图片描述

三.创建项目

1.创建项目com.tedu.project_jingtao
创建spingboot项目
 选择module->spring Initializr->选择Java版本和设置项目名称->添加依赖(web,mybatis,mysql)->finish
2.逆向工程生成xml和pojo类
eclipse中import项目generator,
修改根目录下的GeneratorConfig.xml中的 2,3,4的包名为com.tedu.project_jingtao,
修改5为对应的数据库表名
3.创建controller,mapper,service,pojo包
4.拷贝mapper.xml和接口

在这里插入图片描述

5.创建application.yml(resources文件夹下)
server:
  port: 12345

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    #      有的mysql如5.0 下面必须改成com.mysql.jdbc.Driver
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
    username: root
    password: 123456

mybatis:
  mapperLocations: classpath:com.tedu.project_jingtao.mapper/*.xml

logging:
  path: ./logs
  level:
    com.tedu.project_jingtao.mapper: debug
6.添加扫描
@SpringBootApplication
@MapperScan("com.tedu.project_jingtao.mapper")
//告诉mybatis框架给mapper包中的接口创建代理对象
public class ProjectJingtaoApplication {

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

四.后台服务

1.用户模块UserController
package com.tedu.project_jingtao.controller;

@RestController
@RequestMapping("/user")
@CrossOrigin// 允许跨域请求
public class UserController {
    @Autowired
    //从spring容器中获取UserMapper的对象
    private UserMapper userMapper;
//    完成注册
    @RequestMapping("/register")
    public String register(User user){
        /*查询User表用户名是否存在
        select * from user where username=admin
         使用逆向工程生成的UserExample生成where
         UserExample中有个内部类Criteria ,在pojo包中,or()方法获取设置查询条件的对象
        */
        //UserExample有个内部类Criteria
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.or();
        //设置查询条件
        criteria.andPasswordEqualTo(user.getPassword());
        criteria.andUsernameEqualTo(user.getUsername());
//执行查询----selectByExample()返回的是一个集合,因为查询条件有like等条件
        List<User> users = userMapper.selectByExample(userExample);
        //判断集合中是否有数据
        // 必须先判断集合不为null,才能调用size(),即当集合为[]时,if条件成立
        if(users!=null&&users.size()==0){
//            查询size()为0,说明可以注册,需要将用户数据保存到数据库
            int rows = userMapper.insert(user);
            if(rows>=1){
                return "注册成功";
            }else {
                return "注册失败";
            }
        }
        return "用户名太受欢迎了,换一个吧";

    }
//完成用户登录
    @RequestMapping("/login")
    public User login(User user){
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.or();
        criteria.andUsernameEqualTo(user.getUsername());
        criteria.andPasswordEqualTo(user.getPassword());
        List<User> users = userMapper.selectByExample(userExample);
        if(users!=null&&users.size()>0){
            //返回用户信息
            User u = users.get(0);
            //密码不能发给浏览器,把密码设置成null,只是把映射的对象的密码置为空返回,并没有改变数据库中的值
            u.setPassword("");
            return u;
        }
        return null;
    }
}
2.管理员模块AdminController
package com.tedu.project_jingtao.controller;

@RestController
@RequestMapping("/admin")
public class AdminController {
    @Autowired
//    处理管理员登录
    private TbAdminMapper tbAdminMapper;
//    http://localhost:12345/admin/login?adminName=aa&adminPassword=aa
    @RequestMapping("/login")
    @CrossOrigin// 允许跨域请求
    public TbAdmin login(TbAdmin tbAdmin){
        TbAdminExample tbAdminExample = new TbAdminExample();
        TbAdminExample.Criteria criteria = tbAdminExample.or();
        criteria.andAdminNameEqualTo(tbAdmin.getAdminName());
        criteria.andAdminPasswordEqualTo(tbAdmin.getAdminPassword());
        List<TbAdmin> tbAdmins = tbAdminMapper.selectByExample(tbAdminExample);
        if(tbAdmins!=null&&tbAdmins.size()>=1){
//            返回管理员信息
            TbAdmin admin = tbAdmins.get(0);
            admin.setAdminPassword("");
            return admin;
        }
        return null;
    }
}
3.商品模块ItemController
package com.tedu.project_jingtao.controller;

@RestMapping("/item")
@RestController
@CrossOrigin
public class ItemController {
    @Autowired
    private ItemMapper itemMapper;
    //根据分类id查询商品
    @RequestMapping("/findByCategoryId")
    public List<Item> findByCategoryId(Integer categoryId){
        //select * from Item where category_id=1
        ItemExample itemExample = new ItemExample();
        ItemExample.Criteria criteria = itemExample.or();
        criteria.andCategoryIdEqualTo(categoryId);
        List<Item> items = itemMapper.selectByExample(itemExample);
        return items;
    }
    //根据商品id查询商品----主键查询得到单条数据
    @RequestMapping("/findByItemId")
    public Item findById(Integer itemId){
      return itemMapper.selectByPrimaryKey(itemId);
    }
    //  添加商品
    @RequestMapping("/insertItem")
    public String insertItem(Item item){
        int rows = itemMapper.insert(item);
        if(rows>=1){
            return "添加成功";
        }
        return "添加失败";

    }
    //  查询所有商品
    @RequestMapping("/findAllItems")
    public List<Item> findAllItems(){
        return itemMapper.selectByExample(null);//null表示不设置查询条件,即查询所有记录
    }
    //   根据itemId删除商品
    @RequestMapping("/deleteByItemId")
    public String deleteById(Integer itemId){
        int rows = itemMapper.deleteByPrimaryKey(itemId);
        if(rows>=1){
            return "删除成功";
        }
        return "删除失败";

    }
    //   根据主键修改商品
    @RequestMapping("update")
    public String update(Item item){
//  注意:是通过主键修改,update item set itemName=?,itemPrice=? and itemDesc=? where itemId=?
        int rows = itemMapper.updateByPrimaryKey(item);//该方法参数是Item
        if(rows>=1){
            return "修改成功";
        }
        return "修改失败";
    }
4.分类模块CategoryController
package com.tedu.project_jingtao.controller;

@RestController
@RequestMapping("/category")
public class CategoryController {
    @Autowired
    private CategoryMapper categoryMapper;
    @RequestMapping("/findAllCategory")
    @CrossOrigin
    public List<Category> findAllCategory(){
        return categoryMapper.selectByExample(null);//不生成where,null表示查询所有
    }
}

五.前端显示

准备工作:vue.js,axios.min.js
创建const.js文件,添加全局变量let serverHost="http://localhost:12345"
1.project_jingtao_web项目(用户访问)
(1)主页index.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title></title>
  <!-- 引入js文件 -->
  <script src="vue.js" type="text/javascript"></script>
  <script src="axios.min.js" type="text/javascript"></script>
  <script src="const.js" type="application/javascript"></script>
 </head>
 <body>
  <div id="app">
   <a href="register.html">注册</a>
   <a href="login.html">登录</a>
   <!-- 显示分类信息 -->
   <table>
    <!-- v-for循环如果加在tr标签,会自动换行,如果加在td标签不换行 -->
    <tr >
     <!-- 点击分类显示该分类下的商品信息 -->
     <td  @click="findItemByCategoryId(category.categoryId)" v-for="category in categoryList">{{category.categoryName}}</td>
    </tr>
   </table>
   <table>
    <tr v-for="item in itemList">
    <td>
     <!-- 绑定地址'detail.html?itemId='字符串,item.itemId变量 -->
     <!-- v-bind用于给标签动态绑定属性,点击item,跳转到item的详情页 -->
     <a v-bind:href="'detail.html?itemId='+item.itemId">
     <img v-bind:src="item.itemImage" />
     {{item.itemName}}<p></p>
     {{item.itemPrice}}<p></p>
     </a>
    </td>
    </tr>
   </table>
  </div>
 </body>
 <script>
  var vue=new Vue({
   el:"#app",//挂载点
   data:{
    categoryList:[],
    itemList:[]
   },
   methods:{
    selectAllCategory(){
     let serverUrl=serverHost+"/category/findAllCategory";
     // 联网
     axios.get(serverUrl)
     .then(function(res){
      // res是服务端返回的结果
      this.vue.categoryList=res.data;
     })
    },
    findItemByCategoryId(categoryId){
     let serverUrl=serverHost+"/item/findByCategoryId?categoryId="+categoryId;
        axios.get(serverUrl)
     .then(function(res){
      this.vue.itemList=res.data; 
     })
    }
   },

   // 页面加载完成自动调用查询所有分类
   mounted(){
    this.selectAllCategory();
    this.findItemByCategoryId(1);//显示初始页面
   }
  })
  
 </script>
</html>
(2)item详情页detail.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title></title>
  <!-- 引入js文件 -->
  <script src="vue.js" type="text/javascript"></script>
  <script src="axios.min.js" type="text/javascript"></script>
  <script src="const.js" type="application/javascript"></script>
 </head>
 <body>
  <div id="app">
   <!-- 加v-bind说明该标签的属性值由vue处理 -->
   <img v-bind:src="item.itemImage" />
   {{item.itemName}}<p></p>
   {{item.itemPrice}}<p></p>
   {{item.itemDesc}}<p></p>
   商品评论
  </div>
 </body>
 <script>
  var vue=new Vue({
   el:"#app",
   data:{
    item:null
   },
   mounted(){
    //网页加载完后,vue框架自动调用mounted;
    //detail.html?itemId=1  
    var search=location.search;//?itemId=1 
    search=search.substr(1);//itemId=1 截取字符串
    var arr=search.split("=");//array[0]=itemId  array[1]=1
    var itemId=arr[1];
    console.log(itemId);
    var serverUrl=serverHost+"/item/findByItemId?itemId="+itemId;
    axios.get(serverUrl)
    .then(function(res){
     this.vue.item=res.data;//联网函数必须加vue才能修改data中的变量
    })
    .catch()    
   }
  })
 </script>
</html>
(3)用户注册页register.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title></title>
  <script type="text/javascript" src="vue.js"></script>
  <script type="text/javascript"  src="axios.min.js"></script>
  <script src="const.js" type="text/javascript" ></script>
 </head>
 <body>
  <div id="app">
   <!--  v-model用于数据的双向绑定,即input框输入的数据可以到vue -->
   name:<input v-model="username" /><br>
   password:<input v-model="password" /><br>
   confirmPassword:<input v-model="confirmPassword"/><br>
   <button @click="register">注册</button>
  </div>
 </body>
 <script>
  var vue=new Vue({
   el:"#app",
   data:{
    username:"请在这里输入用户名",
    password:"请输入密码",
    confirmPassword:"请再次确认密码"
   },
   methods:{
    register(){
     if(name=""||this.password!=this.confirmPassword){
      alert("用户名不能为空或两次密码不一致");
      return;
     }
     var serverUrl=serverHost+"/user/register?username="+this.username
     +"&password="+this.password;
     axios.get(serverUrl)
     .then(function(res){
      alert(res.data);
     })
     .catch()     
    }
   }
   
  })
 </script>
</html>
(4)用户登录页login.html
 <body>
  <div id="app">
   用户名:<input v-model="username"  />
   密码:<input v-model="password" type="password" />
   <button type="button" @click="login">登录</button>
  </div>
 </body>
 <script type="text/javascript">
  var vue=new Vue({
   el:"#app",
   data:{
    username:"请输入用户名",
    password:"请输入密码",
   },
   methods:{
    login:function(){
     debugger;
     var serverUrl=serverHost+"/user/login?username="+this.username+"&password="+this.password;
     axios.get(serverUrl)
     .then(function(res){
      debugger;
      var result=res.data;
      console.log(result)
     })
     .catch()
    }
   }
  })
  
 </script>
2.project_jingtao_admin项目(管理员访问)
(1)管理员登录页面login.html
 <body>
  <div id="app">
   <h1>管理员登录</h1>
   <input v-model="adminName"  />
   <input v-model="adminPassword" type="password" />
   <button type="button" @click="login">登录</button>
  </div>
 </body>
 <script type="text/javascript">
  var vue=new Vue({
   el:"#app",
   data:{
    adminName:"请输入用户名",
    adminPassword:"请输入密码",
   },
   methods:{
    login:function(){
     var serverUrl=serverHost+"/admin/login?adminName="+this.adminName+"&adminPassword="+this.adminPassword;
     axios.get(serverUrl)
     .then(function(res){
      var result=res.data;
      if(result!=""){
       // 管理员登录成功后跳到后台商品管理页面---相当于重定向
       location.href="item.html";
      }else{
       alert("登录失败")
      }   
     })
     .catch()
    }
   }
  })
 </script>
(2)商品管理页面item.html
 <body>
  <a href="item.html">商品管理</a>
  <a href="#">订单管理</a>
  <div id="app">
   <!-- v-model双向绑定,下拉框的值是绑定id -->
   <select v-model="categoryId">
    <option v-for="category in categoryList" v-bind:value="category.categoryId">
     {{category.categoryName}}
    </option>
   </select>
   商品名称:<input v-model="itemName" />
   商品价格:<input v-model="itemPrice" />
   商品描述:<input v-model="itemDesc" />
   商品图片:<input v-model="itemImage" />
   <button @click="insert">添加</button>
   
   <table>
    <tr>
     <td>商品编号</td>
     <td>分类编号</td>
     <td>商品名称</td>
     <td>价格</td>
     <td>描述</td>
     <td>图片</td>
     <td>删除</td>
     <td>修改</td>
    </tr>
    <tr v-for="item in itemList">
        <td>{{item.itemId}}</td>
     <td>{{item.categoryId}}</td>
     <td>{{item.itemName}}</td>
     <td>{{item.itemPrice}}</td>
     <td>{{item.itemDesc}}</td>
     <td>{{item.itemImage}}</td>
     <td @click="remove(item.itemId)">删除</td>
     <!-- 更新商品进行页面跳转 -->
     <td><a v-bind:href="'update.html?itemId='+item.itemId">修改</a></td>
    </tr>
   </table>
  </div>
 </body>
 <script>
  var vue=new Vue({
   el:"#app",
   data:{
    itemList:[],
    categoryList:[],
    categoryId:null,
    itemName:null,
    itemPrice:null,
    itemDesc:null,
    itemImage:null
   },
   methods:{
    selectItemList:function(){
     var url=serverHost+"/item/findAllItems"
     axios.get(url)
     .then(function(res){
      var result=res.data;
      this.vue.itemList=result;
     })
     .catch()
    },
    remove(itemId){
     // 执行删除操作时弹出确认框
     var con=window.confirm("您确定要删除吗?")
     if(con){
      var url=serverHost+"/item/deleteByItemId?itemId="+itemId;
      axios.get(url)
      .then(function(res){
       debugger;
       alert(res.data);
       this.vue.selectItemList();
      })
      .catch()
     }
    },
    // 添加商品时,需要categoryId值且不能修改,所以查询category后提供给用户选择
    selectCategoty(){
     var serverUrl=serverHost+"/category/findAllCategory";
     axios.get(serverUrl)
     .then(function(res){
      this.vue.categoryList=res.data;
     })
     .catch();
    },
    insert(){
     var serverUrl=serverHost+"/item/insertItem?categoryId="+this.categoryId
     +"&itemName="+this.itemName
     +"&itemPrice="+this.itemPrice
     +"&itemDesc="+this.itemDesc
     +"&itemImage="+this.itemImage;
     axios.get(serverUrl)
     .then(function(res){
      debugger;
      var result=res.data;
      alert(result)
      this.vue.selectItemList();
     })
     .catch()
    },
   },
   mounted(){
    this.selectCategoty();
    this.selectItemList();
   }
  })
 </script>
(3)修改商品页面update.html

在这里插入图片描述

<body>
  <div id="app">
  商品分类:<select v-model="categoryId">
    <option v-for="category in categoryList" v-bind:value="category.categoryId">
    {{category.categoryName}}</option>
      </select><br>
  名称:<input v-model="itemName" /><br>
  价格:<input v-model="itemPrice" /><br>
  描述:<input v-model="itemDesc" /><br>
  图片:<input v-model="itemImage" />
  <button @click="update">修改</button>
  </div>
 </body>
 <script>
  var vue=new Vue({
   el:"#app",
   data:{
    categoryList:[],
    // 修改时需要的属性
    itemName:null,
    itemId:null,
    categoryId:null,
    itemPrice:null,
    itemDesc:null,
    itemImage:null
   },
   methods:{
    //查出分类列表供下拉框选择
    selectCategoty(){
     var serverUrl=serverHost+"/category/findAllCategory";
     axios.get(serverUrl)
     .then(function(res){
      this.vue.categoryList=res.data;
      console.log(res.data)
     })
     .catch();
    },
    // 通过请求网址在mounted()可以拿到itemId,进入修改页面时,应当把需要修改的item的数据显示到页面上
    selectItemById(itemId){
     var url=serverHost+"/item/findByItemId?itemId="+itemId;
     axios.get(url)
     .then(function(res){
      debugger;
      var item=res.data;
      this.vue.categoryId=item.categoryId;
      this.vue.itemId=item.itemId;
      this.vue.itemName=item.itemName;
      this.vue.itemPrice=item.itemPrice;
      this.vue.itemDesc=item.itemDesc;
      this.vue.itemImage=item.itemImage;
     })
     .catch()
    },
    update(){
     var url=serverHost+"/item/update?itemId="+this.itemId
      +"&itemName="+this.itemName
      +"&itemPrice="+this.itemPrice
      +"&itemDesc="+this.itemDesc
      +"&itemImage="+this.itemImage
      +"&categoryId="+this.categoryId;
      axios.get(url)
      .then(function(res){
       alert(res.data)
       location.href="item.html";
      })
      .catch()
     }  
    },
    mounted(){
     var search=location.search;
     search=search.substr(1);
     var arr=search.split("=");
     var itemId=arr[1];
     //注意需要
     this.selectItemById(itemId);
     this.selectCategoty();//下拉框没有数据可能是没有调用该方法
    }
   })
 </script>
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
springmvc是一种基于Spring框架的MVC(Model View Controller)开发模式的Web开发框架。它能够帮助开发者更好地管理请求和响应,让开发过程更加简洁和灵活。MyBatis是一个优秀的持久层框架,可以与Spring相结合进行数据库操作。它能够通过注解或XML配置文件实现数据库的增删改查操作,使开发者能够高效地操作数据库。电商项目是一种在线购物平台,用户可以浏览商品信息、下单购买、查看订单等。Java商城源码是这种电商项目的实现代码,通过使用SpringMVCMyBatis,能够快速搭建一个完整的电商网站。 SSM框架是指Spring+SpringMVC+MyBatis的组合,是一种常用的JavaWeb开发框架。Spring是一个轻量级的开源框架,提供了很多实用的功能,包括IOC(控制反转)和AOP(面向切面编程)等。SpringMVC是基于SpringMVC框架,可以实现请求的分发和处理。MyBatis是一个持久层框架,可以与SpringMVC结合使用,完成数据库的操作。Maven是一种软件项目管理工具,可以自动下载和配置项目所需的第三方库和工具。 对于这个电商项目Java商城源码,使用SSM框架和Maven进行开发是一个不错的选择。首先,可以使用Maven来管理项目所需的依赖库,避免手动下载和配置的繁琐过程。其次,使用Spring来提供IOC容器和AOP功能,可以简化开发过程,并且使代码更加易于维护。然后,使用SpringMVC来处理请求和响应,实现网站的跳转和业务逻辑的处理。最后,使用MyBatis来完成与数据库的交互,实现商品信息的增删改查等功能。 综上所述,使用SSM框架和Maven进行开发的电商项目Java商城源码,能够快速搭建一个完整的电商网站,实现商品的展示、购买和订单的管理等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值