【狂神说项目练习】SMBMS项目的搭建

项目如何搭建:考虑是否使用Maven,依赖,jar
项目结构图

项目搭建准备工作

1、搭建一个MavenWeb项目

2、配置Tomcat

3、测试项目是否能够运行

4、导入JAR包

jsp,servlet,mysql驱动,jstl,standard

5、创建项目包结构
项目包基本结构

6、编写实体类

ORM映射:表-类映射

7、编写基础公共类

1、数据库配置文件 db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms?serverTimezone=UTC&&useUnicode=true&&characterEncoding=utf8&&useSSL=false
user=root
password=123456

2、编写数据库的公共类

//操作数据库的公共类

public class BaseDao {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;
    //静态代码块 类加载的时候就初始化了
    static {
        Properties properties = new Properties();
        //通过类加载器读取对应的资源
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        driver = properties.getProperty("driver");
        url = properties.getProperty("url");
        username = properties.getProperty("username");
        password = properties.getProperty("password");
    }
    //获取数据库连接
    public static Connection getConnection(){
        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }
    //编写查询公共类
    public static ResultSet execute(Connection connection, String sql,Object[] params,ResultSet resultSet,PreparedStatement ps) throws SQLException {
        ps = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            //setObject占位符从1开始,但是数组是从0开始的
            ps.setObject(i + 1,params[i]);
        }
        resultSet = ps.executeQuery();
        return resultSet;
    }
    //编写CRUD公共方法
    public static int execute(Connection connection, String sql,Object[] params,PreparedStatement ps) throws SQLException {
        ps = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            //setObject占位符从1开始,但是数组是从0开始的
            ps.setObject(i + 1,params[i]);
        }
        int updateRows = ps.executeUpdate();
        return updateRows;
    }
    //关闭链接 释放资源
    public static boolean release(Connection connection,PreparedStatement ps,ResultSet resultSet){
        boolean flag = true;
        if (resultSet != null){
            try {
                resultSet.close();
                //GC回收
                resultSet = null;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
        if (ps != null){
            try {
                ps.close();
                //GC回收
                ps = null;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
        if (connection != null){
            try {
                connection.close();
                //GC回收
                connection = null;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
    }
}

3、编写字符编码过滤器

<!--字符编码过滤器-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>com.sea.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

8、 导入静态资源

狂神说前端资源分享

9、登录功能实现

1、编写前端页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>系统登录 - 超市订单管理系统</title>
    <link type="text/css" rel="stylesheet" href="css/style.css" />
    <script type="text/javascript">
        /* if(top.location!=self.location){
              top.location=self.location;
         } */
    </script>
</head>
<body class="login_bg">

<%
    Object attribute = request.getAttribute("error");
%>

<section class="loginBox">
    <header class="loginHeader">
        <h1>超市订单管理系统</h1>
    </header>
    <section class="loginCont">
        <form class="loginForm" action="/smbms/login.do"  name="actionForm" id="actionForm"  method="post" >
            <div class="info"><%=attribute%></div>
            <div class="inputbox">
                <label for="userCode">用户名:</label>
                <input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/>
            </div>
            <div class="inputbox">
                <label for="userPassword">密码:</label>
                <input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required/>
            </div>
            <div class="subBtn">

                <input type="submit" value="登录"/>
                <input type="reset" value="重置"/>
            </div>
        </form>
    </section>
</section>
</body>
</html>

2、设置首页(web.xml)

<welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
</welcome-file-list>

3、编写Dao层用户登录接口和实现类

package com.sea.dao.user;

import com.sea.pojo.User;
import java.sql.Connection;
import java.sql.SQLException;

public interface UserDao {
    //得到登录的用户
    public User getloginUser(Connection connection, String userCode) throws SQLException;
}

package com.sea.dao.user;

import com.sea.dao.BaseDao;
import com.sea.pojo.User;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserDaoImpl implements UserDao{

    public User getloginUser(Connection connection, String userCode) throws SQLException {
        PreparedStatement pstm = null;
        ResultSet rs = null;
        User user = null;

        if (connection != null){
            String sql = "select * from smbms_user where userCode=?";
            Object[] params = {userCode};
            rs = BaseDao.execute(connection, pstm, rs, sql, params);
            if (rs.next()){
                user = new User();
                user.setId(rs.getInt("id"));
                user.setUserCode(rs.getString("userCode"));
                user.setUserName(rs.getString("userName"));
                user.setUserPassword(rs.getString("userPassword"));
                user.setGender(rs.getInt("gender"));
                user.setBirthday(rs.getDate("birthday"));
                user.setPhone(rs.getString("phone"));
                user.setAddress(rs.getString("address"));
                user.setUserRole(rs.getInt("userRole"));
                user.setCreateBy(rs.getInt("createBy"));
                user.setCreationDate(rs.getDate("createDate"));
                user.setModifyBy(rs.getInt("modifyBy"));
                user.setModifyDate(rs.getDate("modifyDate"));
            }
            BaseDao.release(null,pstm,rs);
        }
        return user;
    }
}

4、编写业务层

1、编写业务层接口

public interface UserService {
    //用户登录
    public User login(String userCode,String userPassword);
}

2、编写业务层接口实现类

public class UserServiceImpl implements UserService{
    //业务层都会调dao层 所以我们要引用dao层
    private UserDao userDao;

    public UserServiceImpl() {
        userDao = new UserDaoImpl();
    }

    public User login(String userCode, String userPassword) {
        Connection connection = null;
        User user = null;
        try {
            connection = BaseDao.getConnection();
            //通过业务层调用对应的具体的数据库操作
            user = userDao.getloginUser(connection,userCode);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            BaseDao.release(connection,null,null);
        }
        return user;
    }
    @Test
    public void Test(){
        UserServiceImpl userService = new UserServiceImpl();
        User admin = userService.login("admin","123456");
        System.out.println(admin.getUserPassword());
    }
}

5、编写Servlet

//处理登录请求
//Servlet:控制层调用业务层代码
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //获取用户名和密码
        String userCode = req.getParameter("userCode");
        String userPassword = req.getParameter("userPassword");
        //和数据库中密码对比 调用业务层
        UserServiceImpl userService = new UserServiceImpl();
        User user = userService.login(userCode, userPassword);//已经把登录的人查出来了
        if (user != null){//查到了 可以登录
            //将用户的信息放到Session中
            req.getSession().setAttribute(Constants.USER_SESSION,user);
            //页面重定向
            resp.sendRedirect("/jsp/frame.jsp");
        }else{//没查到 无法登陆
            //转发回登录页面 顺带提示用户名或密码错误
            req.setAttribute("error","用户名或密码错误");
            req.getRequestDispatcher("login.jsp").forward(req,resp);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

6、测试访问,确保以上功能成功

5、登录功能优化

1、移除Session,返回登录页面

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //移除用户Session
        req.getSession().removeAttribute(Constants.USER_SESSION);
        //返回登录页面
        resp.sendRedirect(req.getContextPath()+"/login.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

2、配置Servlet

<servlet>
    <servlet-name>LogoutServlet</servlet-name>
    <servlet-class>com.sea.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LogoutServlet</servlet-name>
    <url-pattern>/jsp/logout.do</url-pattern>
</servlet-mapping>

6、登录拦截优化

1、编写过滤器

public class SysFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        //过滤器从Session中获取用户
        User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);

        if(user == null){//user已经被移除或注销或者未登录
            response.sendRedirect("/error.jsp");
        }else{
            chain.doFilter(req,resp);
        }
    }

2、配置过滤器(目标是jsp目录下的文件)

<!--权限过滤器-->
<filter>
    <filter-name>SysFilter</filter-name>
    <filter-class>com.sea.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SysFilter</filter-name>
    <url-pattern>/jsp/*</url-pattern>
</filter-mapping>

3、测试

7、修改用户密码

1、编写接口

public User getloginUser(Connection connection, String userCode) throws SQLException;

2、编写实现类

PreparedStatement pstm = null;
int execute = 0;
if (connection != null){
    String sql = "update smbms_user set userPassword = ? where id = ?";
    Object params[] = {password,id};
    execute = BaseDao.execute(connection, pstm, sql, params);
    BaseDao.release(connection, pstm, null);
    return execute;
}

3、编写业务层代码

1、接口
public Boolean updatePwd(int id, String password);
2、实现类
public Boolean updatePwd(int id, String password){
    Connection connection = null;
    Boolean flag = false;

    //修改密码
    try {
        connection = BaseDao.getConnection();
        if (userDao.updatePwd(connection, id, password) > 0){
            flag = true;
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        BaseDao.release(connection, null, null);
    }
    return flag;
}

8、实现Servlet复用

将业务层方法实现从Servlet提取出来,通过判断传入的method调用

//实现Servlet复用
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if (method != null &&method.equals("savepwd")){
            this.updatePwd(req,resp);
        }else if(method != null &&method.equals("pwdmodify")){
            this.pwdModify(req,resp);
        }
    }
    //修改密码
    public void updatePwd(HttpServletRequest req, HttpServletResponse resp){
        //从Session获取用户ID
        Object user = req.getSession().getAttribute(Constants.USER_SESSION);
        String newpassword = req.getParameter("newpassword");

        Boolean flag = false;

        if (user != null && !StringUtils.isNullOrEmpty(newpassword)){
            UserService userService = new UserServiceImpl();

            flag = userService.updatePwd(((User)user).getId(),newpassword);

            if (flag){
                req.setAttribute("message","修改密码成功,请重新登录。");
                //修改密码后 清除Session 返回登录页面
                req.getSession().removeAttribute(Constants.USER_SESSION);
            }else{
                req.setAttribute("message","密码修改失败");
            }
        }else{
            req.setAttribute("message","新密码格式错误");
        }
        try {
            req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Ajax验证旧密码实现

    //验证旧密码 旧密码存在Session中
    public void pwdModify(HttpServletRequest req, HttpServletResponse resp){
        //从Session里获取id
        Object user = req.getSession().getAttribute(Constants.USER_SESSION);
        String oldpassword = req.getParameter("oldpassword");

        //万能的map
        Map<String, String> resultMap = new HashMap<String, String>();

        //如果Session失效 Session过期
        if (user == null){
            resultMap.put("result","sessionerror");
        }else if(StringUtils.isNullOrEmpty(oldpassword)){//输入的旧密码为空
            resultMap.put("result","error");
        }else{
            //获取用户旧密码
            String userPassword = ((User) user).getUserPassword();
            if (oldpassword.equals(userPassword)){
                resultMap.put("result","true");
            }else{
                resultMap.put("result","false");
            }

            try {
                resp.setContentType("application/json");
                PrintWriter writer = resp.getWriter();/*JSONArray 阿里巴巴的Json工具类,转换格式
                resultMap={"result","sessionerror","result","error"}
                Json格式:{key:value}
                */
                writer.write(JSONArray.toJSONString(resultMap));
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

9、用户管理实现

1、获取用户数量

1、userDao
//查询用户总数
public int getUserCount(Connection connection, String username, int userRole) throws SQLException;

//根据用户名或者角色查询用户总数
public int getUserCount(Connection connection, String username, int userRole) throws SQLException {
    PreparedStatement pstm = null;
    ResultSet rs = null;
    int count = 0;

    if (connection != null){
        StringBuffer sql = new StringBuffer();
        sql.append("select count(1) as count from smbms_user u,smbms_role r where u.userRole = r.id ");
        ArrayList<Object> list = new ArrayList<Object>();//用来存放我们的参数

        if (!StringUtils.isNullOrEmpty(username)){
            sql.append("and u.userName like ? ");
            list.add("%" + username + "%");//index:0
        }
        if (userRole > 0){
            sql.append("and u.userRole like ?");
            list.add("%" + userRole + "%");//index:1
        }
        //list转换为数组
        Object[] params = list.toArray();
        //输出完整的sql语句
        System.out.println("UserDaoImpl->getUserCount"+sql.toString());
        rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);

        if (rs.next()){
            count = rs.getInt("count");//从结果集中获取最终数量
        }
        BaseDao.release(null, pstm, rs);
    }

    return count;
}
2、service
//查询记录数
public int getUserCount(String username, int userRole);

public int getUserCount(String username, int userRole) {
    Connection connection = null;
    int count = 0;

    try {
        connection = BaseDao.getConnection();
        count = userDao.getUserCount(connection, username, userRole);
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        BaseDao.release(connection, null, null);
    }
    return count;
}

2、获取用户列表

1、userDao

//获取用户列表 通过条件查询 userList

public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws SQLException;

public List<User> getUserList(Connection connection, String username, int userRole, int currentPageNo, int pageSize) throws SQLException {
    PreparedStatement pstm = null;
    ResultSet rs = null;
    List<User> userList = new ArrayList<User>();

    if (connection != null){
        StringBuffer sql = new StringBuffer("");
        sql.append("select u.*, r.roleName as userRoleName from smbms_user u, smbms_role r where u.userRole = r.id ");
        List<Object> list = new ArrayList<Object>();

        if (StringUtils.isNullOrEmpty(username)){
            sql.append("and u.username like ? ");
            list.add("%"+ username +"%");
        }

        if (userRole > 0){
            sql.append("and u.userRole = ? ");
            list.add("%"+ userRole+ "%");
        }

        sql.append("order by creationDate DESC limit ?,?");
        currentPageNo = (currentPageNo - 1) * pageSize;

        list.add(currentPageNo);
        list.add(pageSize);

        Object[] params = list.toArray();
        System.out.println("sql --> " + sql.toString());

        BaseDao.execute(connection, pstm, rs, sql.toString(), params);
        BaseDao.release(null, pstm, rs);
    }
    return userList;
}

2、service

public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int PageSize);

public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int PageSize) {
    Connection connection = null;
    List<User> userList = null;

    try {
        connection = BaseDao.getConnection();
        userList = userDao.getUserList(connection, queryUserName, queryUserRole, currentPageNo, PageSize);
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        BaseDao.release(connection, null, null);
    }
    return userList;
}

3、获取角色操作

为了我们职责统一,可以把角色操作单独放在一个包中,与pojo对应

1、roledao
//获取角色列表
public List<Role> getRoleList(Connection connection) throws SQLException;

public List<Role> getRoleList(Connection connection) throws SQLException {
    PreparedStatement pstm = null;
    ResultSet rs = null;
    ArrayList<Role> roleList = new ArrayList<Role>();

    if (connection != null){
        String sql = "select * from smbms_role";
        Object[] params = {};

        rs = BaseDao.execute(connection, pstm, rs, sql, params);
        while (rs.next()){
            Role _role = new Role();
            _role.setId(rs.getInt("id"));
            _role.setRoleCode(rs.getString("roleCode"));
            _role.setRoleName(rs.getString("roleName"));
            roleList.add(_role);
        }
        BaseDao.release(null, pstm, rs);
    }
    return roleList;
}
2、service
public List<Role> getRoleList();

//引入dao
private RoleDao roleDao;
public RoleServiceImpl() {
    roleDao = new RoleDaoImpl();
}

public List<Role> getRoleList() {
    Connection connection = null;
    List<Role> roleList = null;
    try {
        connection = BaseDao.getConnection();
        roleList = roleDao.getRoleList(connection);
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        BaseDao.release(connection, null, null);
    }
    return roleList;
}

4、用户显示的servlet

    1、获取前端数据(查询)
    2、判断请求是否需要执行,看参数的值判断
    3、为了实现分页,需要计算出当前页面和总页面,页面大小
    4、用户列表展示
    5、返回前端
public void query(HttpServletRequest req, HttpServletResponse resp){

    //获取前端数据
    String queryUserName = req.getParameter("queryname");
    String temp = req.getParameter("queryUserRole");//临时变量
    String pageIndex = req.getParameter("pageIndex");
    int queryUserRole = 0;

    //获取用户列表
    UserServiceImpl userService = new UserServiceImpl();
    List<User> userList = null;

    //第一次访问页面一定是第一页,页面大小固定
    int pageSize = 5;//可以把这个变量配置到配置文件中方便后期修改
    int currentPageNo = 1;

    if (queryUserName == null){
        queryUserName = "";
    }
    if (temp != null && !temp.equals("")){
        queryUserRole = Integer.parseInt(temp);//给查询赋值 0 1 2 3
    }
    if (pageIndex != null){
        currentPageNo = Integer.parseInt(pageIndex);
    }

    //获取用户总数(分页 上一页 下一页的情况)
    int totalCount = userService.getUserCount(queryUserName, queryUserRole);
    PageSupport pageSupport = new PageSupport();

    pageSupport.setCurrentPageNo(currentPageNo);
    pageSupport.setPageSize(pageSize);
    pageSupport.setTotalCount(totalCount);

    int totalPageCount = pageSupport.getTotalPageCount();

    //控制首页和尾页
    //如果页面小于1 则显示第一页
    if (currentPageNo < 1){
        currentPageNo = 1;
    }else if (currentPageNo > totalPageCount){//当页面大于最后一页
        currentPageNo = totalPageCount;
    }

    userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize);
    req.setAttribute("userList",userList);

    RoleServiceImpl roleService = new RoleServiceImpl();
    List<Role> roleList = roleService.getRoleList();
    req.setAttribute("roleList", roleList);

    req.setAttribute("totalCount", totalCount);
    req.setAttribute("currentPageNo", currentPageNo);
    req.setAttribute("totalPageCount", totalPageCount);
    req.setAttribute("queryUserName", queryUserName);
    req.setAttribute("queryUserRole", queryUserRole);

    System.out.println(userList.toString());
    System.out.println(roleList.toString());
    System.out.println(queryUserName);
    System.out.println(queryUserRole);
    //返回前端
    try {
        req.getRequestDispatcher("userlist.jsp").forward(req, resp);
    } catch (ServletException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

5、新增用户

1、dao
//添加用户
public int add(Connection connection, User user) throws SQLException;

public int add(Connection connection, User user) throws SQLException {
    PreparedStatement pstm = null;
    int updateRows = 0;
    if (connection != null){
        String sql = "insert into smbms_user(userCode,userName,userPassword," +
                "gender,birthday,phone,address,userRole,createdBy,creationDate)" +
                "values(?,?,?,?,?,?,?,?)";
        Object[] params = {user.getUserCode(),user.getUserName(),user.getUserPassword(),
                            user.getGender(),user.getBirthday(),user.getPhone(),
                            user.getAddress(),user.getUserRole(),user.getCreateBy(),
                            user.getCreationDate()};
        updateRows = BaseDao.execute(connection, pstm, sql, params);
        BaseDao.release(null, pstm, null);
    }
    return updateRows;
}
2、service
//增加用户
public Boolean add(User user) throws SQLException;

public Boolean add(User user){
    Connection connection = null;
    Boolean flag = false;
    try {
        int updateRows = 0;
        connection = BaseDao.getConnection();
        connection.setAutoCommit(true);//开启jdbc事务管理
        updateRows = userDao.add(connection, user);

        connection.commit();
        if (updateRows > 0){
            flag = true;
            System.out.println("add success");
        }else{
            System.out.println("add falied");
        }

    } catch (SQLException e) {
        e.printStackTrace();
        try {
            System.out.println("rollback------");
            connection.rollback();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }finally {
        BaseDao.release(connection, null, null);
    }
    return null;
}
3、servlet
//新增用户
public void add(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    String userCode = req.getParameter("userCode");
    String userName = req.getParameter("userName");
    String userPassword = req.getParameter("userPassword");
    String gender = req.getParameter("gender");
    String birthday = req.getParameter("birthday");
    String phone = req.getParameter("phone");
    String address = req.getParameter("address");
    String userRole = req.getParameter("userRole");


    User user = new User();
    user.setUserCode(userCode);
    user.setUserName(userName);
    user.setUserPassword(userPassword);
    user.setGender(Integer.valueOf(gender));
    try {
        user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
    } catch (ParseException e) {
        e.printStackTrace();
    }
    user.setPhone(phone);
    user.setAddress(address);
    user.setUserRole(Integer.valueOf(userRole));
    user.setCreateBy(((User)req.getSession().getAttribute(Constants.USER_SESSION)).getId());
    user.setCreationDate(new Date());


    UserServiceImpl userService = new UserServiceImpl();
    if (userService.add(user)){
        resp.sendRedirect(req.getContextPath() + "/jsp/user.do?method=query");
    }else{
        req.getRequestDispatcher("useradd.jsp").forward(req, resp);
    }
}

总结

狂神在Javaweb阶段就做到这,剩下的我们可以自己补充。像我属于学完Javaweb相关知识后,打算学会了SSM框架整合和SpringBoot再回来将项目好好完善。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值