JavaWeb框架-Hibernate-3-不厌其烦的CURD!

话说:

各位读者,中午好呀。有前面2篇Hibernate的博客作铺垫,今天这篇横空出世自然顺理成章啦。

目标:Hibernate实现CURD和分页。
整体思路和之前一样,只是换一个工具啦。

目录


一、整体布局
二、结果展示

三、几大板块
1、pom.xml
2、model层
3、resources
4、dao层
5、util工具层
6、servlet层
7、Web页面

四、总结


开发工具:IDEA(2017.2.5)

一、整体布局

这里写图片描述

二、结果展示

这里写图片描述

如果是第一页: 首页 上一页 就不在显示,避免后台做无效的查询;同理末页也如此处理。

这里写图片描述

第二页,就全部显示。

这里写图片描述
最后一页效果图

三、几大板块

1、pom.xml

这个作用是实现MySQL数据库的连接、实体类映射、HQL相关配置(如打印SQL语句等)、导各种包(eg:JSTL)

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.hmc.hibernate</groupId>
  <artifactId>Hibernate_News</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Hibernate_News Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <!--换一个高级一点的版本-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>


  <!--Hibernate core-->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.2.12.Final</version>
    </dependency>

    <!--Mysql驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.38</version>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>RELEASE</version>
    </dependency>

    <!--jstl包-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

  </dependencies>
  <build>
    <finalName>Hibernate_News</finalName>
  </build>
</project>

2、model层

News——新闻的实体类

package com.hmc.hibernate_news.model;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * User:Meice
 * 2017/10/28
 */
@Entity
@Table(name = "t_news")
public class News {
    private int id;
    private String  title;
    private String author;
    private String pic;
    public News() {}
    public News(int id,String title,String author,String pic) {
        this.id = id;
        this.title = title;
        this.author = author;
        this.pic = pic;

    }

    public News(String title,String author,String pic) {
        this.title = title;
        this.author= author;
        this.pic = pic;
    }

    public News(String title,String author) {
        this.title = title;
        this.author = author;
    }
    public News(int id,String title,String author) {
        this.id = id;
        this.title = title;
        this.author = author;
    }

    @Id
    @GenericGenerator(name = "myid",strategy = "native")
    @GeneratedValue(generator = "myid")
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }

    @Override
    public String toString() {
        return "News{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", pic='" + pic + '\'' +
                '}';
    }
}

Pager——分页的实体类

package com.hmc.hibernate_news.model;
import java.util.List;

/**
 * User:Meice
 * 2017/10/28
 */

public class Pager<E> {
    private int totalPage;//总页数
    private int pageIndex=2;    //当前页
    private int count;//总记录数
    private int pageSize=15;//显示条目
    private int offset;//分页偏移量
    private int start;
    private int end;
    private List<E> datas;//记录数据
    public Pager() {}

    public Pager(int totalPage, int pageIndex, int pageSize, int offset, List<E> datas) {
        this.totalPage = totalPage;
        this.pageIndex = pageIndex;
        this.pageSize = pageSize;
        this.offset = offset;
        this.datas = datas;
    }

    public Pager(int pageIndex, int pageSize, int offset, List<E> datas) {
        this.pageIndex = pageIndex;
        this.pageSize = pageSize;
        this.offset = offset;
        this.datas = datas;
    }

    public Pager(int totalPage, int pageIndex, int count, int pageSize, int offset, int start, int end, List<E> datas) {
        this.totalPage = totalPage;
        this.pageIndex = pageIndex;
        this.count = count;
        this.pageSize = pageSize;
        this.offset = offset;
        this.start = start;
        this.end = end;
        this.datas = datas;
    }

    public int getTotalPage() {
    //我们在为属性设置值的时候,这里需要在get()方法中控制,后面类似
        totalPage = (int)Math.ceil((double)(count)/pageSize);
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getPageIndex() {
        return pageIndex;
    }

    public void setPageIndex(int pageIndex) {
        this.pageIndex = pageIndex;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getOffset() {
    //这里表明,Servlet中要注意给属性赋值的顺序
        offset = (pageIndex-1)*pageSize;
        return offset;
    }

    public void setOffset(int offset) {
        this.offset = offset;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }

    public List<E> getDatas() {
        return datas;
    }

    public void setDatas(List<E> datas) {
        this.datas = datas;
    }

}

整个分页用Pager封装起来,好处不言而喻。页面显示的时候,直接.属性即可。

3、resources

hibernate.cfg.xml
在实体类加注解的时候,不要忘了在配置文件里面配置mapping

<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  -->
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!--配置MySQL数据库连接-->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/news_db</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">119913</property>

        <!--配置自动生成表-->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!--配置打印SQL语句-->
        <property name="hibernate.show_sql">true</property>

        <!--配置实体映射-->
        <mapping class="com.hmc.hibernate_news.model.News"></mapping>

    </session-factory>
</hibernate-configuration>

4、dao层

HibernateNewsDao
在这里面实现HibernateAPI,对比之前的JDBC的BaseDao,简直简单得爽翻天!

package com.hmc.hibernate_news.dao;
import com.hmc.hibernate_news.model.News;
import com.hmc.hibernate_news.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.jupiter.api.Test;

import java.util.List;

/**
 * User:Meice
 * 2017/10/28
 */
public class HibernateNewsDao {
    Session session = null;

    /**
     * 查
     * 查询所有
     */

    @Test
    public List<News> list() {
        try {
            session = HibernateUtil.getSession();
          List<News> list =  session.createQuery("from News")
                    .list();
            return  list;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }finally {
            HibernateUtil.closeSession(session);
        }

    }

    /**
     * 查
     * 查询单个对象
     */
    @Test
    public News listOne(int id) {
        try {
            session = HibernateUtil.getSession();
        News news =(News)session.createQuery("from News where id = :id")
                    .setParameter("id",id)
                    .uniqueResult();
        return  news;
        } catch (Exception e) {
            e.printStackTrace();
            return  null;
        }finally {
            HibernateUtil.closeSession(session);
        }
    }



    /**
     * 增、改
     * 增改删操作一定要开启事务和提交事务,这是与查最大的区别
     */

    public void add(News news) {
        try {
            session = HibernateUtil.getSession();
            session.beginTransaction();
            session.saveOrUpdate(news);
            session.getTransaction().commit();
            System.out.println("我是增、改方法....");
        } catch (Exception e) {
           session.getTransaction().rollback();
        }finally{
            HibernateUtil.closeSession(session);
        }
    }


    /**
     * 删除
     * 删除新闻
     */

    public void del(int id) {
        try {
            session = HibernateUtil.getSession();
            News news = new News();
            news.setId(id);
            session.beginTransaction();
            session.delete(news);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            HibernateUtil.closeSession(session);
        }

    }


    /**
     * 分页
     *
     */
    @Test
    public List<News> showPage(int offset,int pageSize) {
        try {
            session = HibernateUtil.getSession();
         List<News>  list = session.createQuery("from News")
                     .setFirstResult(offset)
                    .setMaxResults(pageSize)
                    .list();
            System.out.println(list);
         return  list;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }finally{
            HibernateUtil.closeSession(session);
        }
    }


    /**
     * 总条目数
     *
     */
    @Test
    public int count() {
        try {
            session = HibernateUtil.getSession();
            //再次提醒以下:count(*)返回的是Long类型
        Long countInt =(Long)session.createQuery("select count(id) from News")
                    .uniqueResult();
            System.out.println("我是总条目数:"+countInt);
            //lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
        int count =countInt.intValue();
        return count;


        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }finally{
            HibernateUtil.closeSession(session);
        }

    }

    public static void main(String[] args) {
        HibernateNewsDao hnd = new HibernateNewsDao();
    hnd.add(new News("666","888"));
       // System.out.println(news);

    }

}

5、util工具层

HibernateUtil——这个作用是获取session

package com.hmc.hibernate_news.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

/**
 * User:Meice
 * 2017/10/28
 */
public class HibernateUtil {
    private  static  SessionFactory sessionFactory = null;
    //A SessionFactory is set up once for an application!所以定义为静态语句块
    static{
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure()
                .build();
        try {
             sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        } catch (Exception e) {
            // The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory
            // so destroy it manually.
            //我们要掌控异常,所以一旦出现异常,手动关闭
            StandardServiceRegistryBuilder.destroy(registry);
        }
    }

    //定义获取session的方法getSession()
    public static Session getSession() {
         Session session =   sessionFactory.openSession();
         return  session;
    }

    //定义关闭session的方法closeSession()
    public static void closeSession(Session session) {
        session.close();
    }

}

StringConvertInt——作用:Sting类型的Id转换为整型

package com.hmc.hibernate_news.util;

/**
 * User:Meice
 * 2017/10/28
 */
public class StringConvertInt {
    public static int getVal(String strId) {
        if(strId != null && !"".equals(strId)) {
            int id = Integer.parseInt(strId);
            return id;
        }else {
            return 0;
        }
    }
}

6、servlet层

BaseServlet
作用:和之前一样,实现把多个Servlet写在一个Servlet里面,核心是Method的invoke()方法

package com.hmc.hibernate_news.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * User:Meice
 * 2017/10/28
 */
public class BaseServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        //接受参数
       String op =  req.getParameter("op");
       if(op != null && !"".equals(op)) {
           try {
               Method method = this.getClass().getDeclaredMethod(op,HttpServletRequest.class,HttpServletResponse.class);
               method.invoke(this,req,resp);
           } catch (NoSuchMethodException e) {
               e.printStackTrace();
           } catch (IllegalAccessException e) {
               e.printStackTrace();
           } catch (InvocationTargetException e) {
               e.printStackTrace();
           }
       }else {
           System.out.println("参数缺失...");
       }
    }
}

NewsServlet
处理参数、调用dao层方法及页面跳转

package com.hmc.hibernate_news.servlet;
import com.hmc.hibernate_news.dao.HibernateNewsDao;
import com.hmc.hibernate_news.model.News;
import com.hmc.hibernate_news.model.Pager;
import com.hmc.hibernate_news.util.StringConvertInt;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * User:Meice
 * 2017/10/28
 */
@WebServlet(urlPatterns = "/news.do")
public class NewsServlet extends BaseServlet {
    HibernateNewsDao hnd = new HibernateNewsDao();

    /**
     * 查
     * 显示新闻列表
     */
    public void list(HttpServletRequest req, HttpServletResponse resp) {
       //调用方法
      List<News> list =  hnd.list();
        System.out.println("进来了");
       // System.out.println(list);
      //设置参数
        req.setAttribute("list",list);
        //页面跳转
        try {
            req.getRequestDispatcher("index.jsp").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 增
     * 发布新闻
     */
    public void add(HttpServletRequest req, HttpServletResponse resp) {
        //接收参数
     String title =(String)req.getParameter("title");
     String author = (String)req.getParameter("author");
        System.out.println("title  " + title);
        System.out.println("author   " + author);
     News news = new News(title,author);
     //调用方法
     hnd.add(news);
     //页面跳转
        try {
            req.getRequestDispatcher("news.do?op=listPage").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    /**
     * 改
     * 修改新闻
     */
    //显示单个新闻
    public void listOne(HttpServletRequest req,HttpServletResponse resp) {
        //接收参数
        String strId = req.getParameter("id");
        int id = StringConvertInt.getVal(strId);
        //调用方法
      News news =  hnd.listOne(id);
      //设置参数
        req.setAttribute("news",news);
        //页面跳转
        try {
            req.getRequestDispatcher("newsUpdate.jsp").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //执行修改操作
    public void  change(HttpServletRequest req, HttpServletResponse resp) {
        //接收参数
       String strId = req.getParameter("id");
       int id = StringConvertInt.getVal(strId);
       String title = req.getParameter("title");
       String author = req.getParameter("author");
       News news = new News(id,title,author);
        //调用方法
        hnd.add(news);
        //页面跳转
        try {
            req.getRequestDispatcher("news.do?op=listPage").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    /**
     * 删
     *
     */
    public void  del(HttpServletRequest req,HttpServletResponse resp) {
        //接收参数
        String strId = req.getParameter("id");
        int id = StringConvertInt.getVal(strId);
        //调用方法
        hnd.del(id);
        //页面跳转
        try {
            req.getRequestDispatcher("news.do?op=listPage").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 分页显示新闻
     */
    public void listPage(HttpServletRequest req,HttpServletResponse resp) {
       //接受参数
      String strPageIndex =  req.getParameter("pageIndex");
      int pageIndex = StringConvertInt.getVal(strPageIndex);


        //调用方法
       Pager<News> pg= new Pager<News>();
       //根据页面传递的当前页来设置
        pageIndex = pageIndex==0?1:pageIndex;
        pg.setPageIndex(pageIndex);

        //因为pageIndex会影响到count,所以需要在设置之后在调用方法
        List<News> listPage =   hnd.showPage(pg.getOffset(),pg.getPageSize());
        pg.setDatas(listPage);

        //调用总记录数方法
         int count = hnd.count();
         pg.setCount(count);

        //设置参数
        req.setAttribute("datas",pg.getDatas());
        req.setAttribute("pager",pg);
        req.setAttribute("totalPage",pg.getTotalPage());


        //页面跳转
        try {
            req.getRequestDispatcher("newsPage.jsp").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}

**7、Web页面
界面和之前一样。唯一需要注意的是isELIgnored=”false”


newsPage.jsp——新闻显示页面
newsAdd.jsp——发布新闻界面
newsUpdate.jsp——修改新闻界面


newsPage.jsp——新闻显示页面

<%--
  User: Meice
  Date: 2017/10/29
  Time: 0:26
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
    <h2 align="center">Meice的新闻分页显示</h2>
    <title>新闻分页</title>
</head>
<body>
<a href="newsAdd.jsp">发布新闻</a>
    <table border="1" align="center" width="80%">
        <thead>
            <tr>
                <th>编号</th>
                <th>标题</th>
                <th>作者</th>
                <th>图片</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>

            <c:forEach var="news" items="${datas}">
                <tr>
                    <td>${news.id}</td>
                    <td>${news.title}</td>
                    <td>${news.author}</td>
                    <td>${news.pic}</td>
                    <td>
                        <a href="news.do?op=listOne&id=${news.id}">修改</a>
                        <a href="news.do?op=del&id=${news.id}" onclick="return confirm('真的忍心删除么?')">删除</a>
                    </td>
                </tr>
            </c:forEach>
            <tr>
                <td colspan="5" align="center">

                    <c:if test="${pager.pageIndex>1}">
                        <a href="news.do?op=listPage&pageIndex=1">首页</a>
                        <a href="news.do?op=listPage&pageIndex=${pager.pageIndex-1}">上一页</a>
                    </c:if>
                    <c:forEach var="x" begin="${pager.pageIndex}" end="${pager.pageIndex+4}" >
                        <c:if test="${pager.pageIndex<pager.totalPage}">
                            <a href="news.do?op=listPage&pageIndex=${x}">${x}</a>
                        </c:if>

                    </c:forEach>


                    <c:if test="${pager.pageIndex<pager.totalPage}">
                        <a href="news.do?op=listPage&pageIndex=${pager.pageIndex+1}">下一页</a>
                        <a href="news.do?op=listPage&pageIndex=${pager.totalPage}">末页</a>
                    </c:if>


                </td>
            </tr>
        </tbody>
    </table>
</body>
</html>

newsAdd.jsp——发布新闻界面

<%--
  User: Meice
  Date: 2017/10/28
  Time: 21:32
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>发布新闻</title>
</head>
<body>
    <form action="news.do" method="post">
        <input type="hidden" name="op" value="add">
        <table>
            <tr>
                <td>标题</td>
                <td><input type="text" name="title"></td>
            </tr>
            <tr>
                <td>作者</td>
                <td><input type="text" name="author"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="发布"></td>
            </tr>
        </table>
    </form>
</body>
</html>

newsUpdate.jsp——修改新闻界面

<%--
  User: Meice
  Date: 2017/10/28
  Time: 23:23
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>修改新闻</title>
</head>
<body>
    <form action="news.do?op=change" method="post">
        <table>
            <tr>
                <td>编号</td>
                <td><input type="text" name="id" value="${news.id}" readonly="readonly"></td>
            </tr>
            <tr>
                <td>标题</td>
                <td><input type="text" name="title" value="${news.title}"></td>
            </tr>
            <tr>
                <td>作者</td>
                <td><input type="text" name="author" value="${news.author}"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="修改"></td>
            </tr>
        </table>

    </form>

</body>
</html>

四、总结**


22:50 2017/10/28
1、EL表达式在Hibernate的Maven项目里的页面中,默认没有此属性,且默认关闭EL。即isELIgnored = “false”,只有开启EL,即isELIgnored=”true”,EL表达式才会生效。

2、在写BaseServlet的时候,Method.invoke()方法调用,传递参数有误,应该传递Method.invoke(当前类,request,resposne)即Method.invoke(this.req,resp);在写NewsServlet中的方法时候,开始方法忘记写参数:HttpServletRequeset req,HttpServletResponse resp;在Servlet中,request,response是至关重要的两个参数。所以BaseServlet、NewsServlet的核心就是这2个参数。

3、在表单接收参数的时候,竟然把接收参数写成了:
String author = (String) req.getAttribute(“author”);??
很无语,查了半天……
表单接收参数,要用req.getParameter好不好!
如果是自己传递的值,setAttribute()
自己接收的话,用getAttribute()
不知道怎么滴,今天总是犯一些低级错误,奇怪的是,之前怎么没有遇到过呢?

4、confirm的用法

<a href="news.do?op=del&id=${news.id}" onclick="confirm('真的忍心删除我麽?')">删除</a>

注意:这里的confirm如果没有return,不论确定还是取消,都会删除!所以,正确的写法是这样的:

    <a href="news.do?op=del&id=${news.id}" onclick=" return confirm('真的忍心删除我麽?')">删除</a>

5、比较奇怪的是,一旦方法有返回值,在Hibernate API中就不好测试,怎么测试都没有结果。无法打印输出。

6、包装类要转化为基本类型,用自带的方法.intValue();
int count =countInt.intValue();

7、分页这次简化了下,简化地方在于分页安装固定步长显示;文件上传功能这次暂不实现。


好了!开午饭!

内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值