JAVA - employment case ② (WEB comprehensive case)

Keywords: Java Front-end Web Development Database Back-end

target

Objective 1: be able to name three common paradigms of database design

Goal 2: be able to use PD tools for table structure design

Objective 3: complete the business development of discipline module

Objective 4: complete the business development of the directory module

Objective 5: complete the business development of the topic module

Goal 6: be able to say three elements of file upload foreground

Objective 7: be able to complete the business development of the topic option module

1. Database design

1.1 database design paradigm

What is database design paradigm?

Paradigm: normative form, applied to the standardization of various industries

There are five paradigms in database design, but they are commonly used: the first paradigm (1NF), the second paradigm (2NF) and the third paradigm (3NF)

First normal form (1NF): for the columns in the data table, the columns must be atomic and cannot be split

If the data table is designed in this way, the native place column is not atomic, because the data can be split again. Without splitting, the user's state and county information or county and city information cannot be obtained. After splitting, it is as follows:

The second normal form (2NF): the data table should have a unique primary key. There are no multiple primary keys, so that each row of data is unique

In the table shown in the figure, no field (column) can uniquely determine a piece of data. To uniquely determine a piece of data, two or more fields are required, which violates the second paradigm. The data table does not have a unique primary key, but there are multiple primary keys.

So how to solve it? Add a unique primary key column to the table: id

The third normal form (3NF): it does not rely on non primary key fields and deeper dependencies, so that each field is independent of the primary key field (independence)

What is dependency: dependency means that in A table, the value B of A field can be determined by the value A of another field. We call field B dependent on field A or field A determines field B

In the table structure shown in the figure: total column = unit price X quantity. Of course, you need to rely on the commodity number to query the commodity unit price

In a word, the total column depends on the non primary key fields in the table and the deeper dependence of non primary key fields, which indicates that the data in the total column is redundant, because we can get the total data through calculation without storing it in the table.

Anti three paradigms: allow a small amount of data redundancy and improve the speed of query

1.2 database design tools

PowerDesigner, referred to as PD for short, is a powerful modeling software that provides powerful metadata management functions. It can help users build a comprehensive view of key information and create various types of models, including conceptual data model, physical data model, object-oriented model, etc. at the same time, it integrates multiple functions of data management, BI, data integration and data integration.

2. Rapid development of subject modules

Let's carry out the rapid development of subject modules:

(1) Create discipline entity: com.xxx.domain.store.Course

public class Course {
    private String id;
    private String name;
    private String remark;
    private String state;
    private Date createTime;

    // getter/setter omitted
}

(2) Create Dao interface: com.xxx.dao.store.CourseDao

public interface CourseDao {
    int save(Course course);

    int delete(Course course);

    int update(Course course);

    Course findById(String id);

    List<Course> findAll();
}

(3) Find the dao layer resource file \ CourseDao.xml from today's course materials and copy it to the project src/main/resources/com/xxx/dao/store /

Of course, all mapping configuration files in this directory can be copied to this directory, so there is no need to copy them for subsequent business.

(4) Create business layer interface: com.xxx.service.store.CourseService

public interface CourseService {
    /**
     * add to
     * @param course
     * @return
     */
    void save(Course course);

    /**
     * delete
     * @param course
     * @return
     */
    void delete(Course course);

    /**
     * modify
     * @param course
     * @return
     */
    void update(Course course);

    /**
     * Query single
     * @param id Query criteria (id)
     * @return Query results, single object
     */
    Course findById(String id);

    /**
     * Query all data
     * @return List object of all data
     */
    List<Course> findAll();

    /**
     * Paging query data
     * @param page Page number
     * @param size Total data displayed per page
     * @return
     */
    PageInfo findAll(int page, int size);
}

(5) Create a business layer implementation class: com.xxx.service.store.impl.CourseServiceImpl

public class CourseServiceImpl implements CourseService {
    @Override
    public void save(Course course) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class);
            //id is obtained using the generation policy of UUID
            String id = UUID.randomUUID().toString();
            course.setId(id);
            //3. Call Dao layer operation
            courseDao.save(course);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        }catch (Exception e){
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void delete(Course course) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class);
            //3. Call Dao layer operation
            courseDao.delete(course);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        }catch (Exception e){
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void update(Course course) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class);
            //3. Call Dao layer operation
            courseDao.update(course);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        }catch (Exception e){
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public Course findById(String id) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class);
            //3. Call Dao layer operation
            return courseDao.findById(id);
        }catch (Exception e){
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<Course> findAll() {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class);
            //3. Call Dao layer operation
            return courseDao.findAll();
        }catch (Exception e){
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public PageInfo findAll(int page, int size) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class);
            //3. Call Dao layer operation
            PageHelper.startPage(page,size);
            List<Course> all = courseDao.findAll();
            PageInfo pageInfo = new PageInfo(all);
            return pageInfo;
        }catch (Exception e){
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

(6) Create servlet: com.xxx.web.controller.store.CourseServlet

// uri:/store/course?operation=list
@WebServlet("/store/course")
public class CourseServlet extends BaseServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String operation = request.getParameter("operation");
        if("list".equals(operation)){
            this.list(request,response);
        }else if("toAdd".equals(operation)){
            this.toAdd(request,response);
        }else if("save".equals(operation)){
            this.save(request, response);
        }else if("toEdit".equals(operation)){
            this.toEdit(request,response);
        }else if("edit".equals(operation)){
            this.edit(request,response);
        }else if("delete".equals(operation)){
            this.delete(request,response);
        }
    }

    private void list(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //Go to the list page
        //get data
        int page = 1;
        int size = 5;
        if(StringUtils.isNotBlank(request.getParameter("page"))){
            page = Integer.parseInt(request.getParameter("page"));
        }
        if(StringUtils.isNotBlank(request.getParameter("size"))){
            size = Integer.parseInt(request.getParameter("size"));
        }
        PageInfo all = courseService.findAll(page, size);
        //Save the data to the specified location
        request.setAttribute("page",all);
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/course/list.jsp").forward(request,response);
    }

    private void toAdd(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/course/add.jsp").forward(request,response);
    }

    private void save(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //The data is obtained and encapsulated into an object
        Course course = BeanUtil.fillBean(request,Course.class,"yyyy-MM-dd");
        //Call the business layer interface save
        courseService.save(course);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/course?operation=list");
    }

    private void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Query the data findById to modify
        String id = request.getParameter("id");
        Course course = courseService.findById(id);
        //Load the data into the specified area for the page to obtain
        request.setAttribute("course",course);
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/course/update.jsp").forward(request,response);
    }

    private void edit(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //The data is obtained and encapsulated into an object
        Course course = BeanUtil.fillBean(request,Course.class,"yyyy-MM-dd");
        //Call the business layer interface save
        courseService.update(course);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/course?operation=list");
    }

    private void delete(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //The data is obtained and encapsulated into an object
        Course course = BeanUtil.fillBean(request,Course.class);
        //Call the business layer interface save
        courseService.delete(course);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/course?operation=list");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }
}

(7) Modify BaseServlet and add CourseService

public class BaseServlet extends HttpServlet {
    protected CompanyService companyService;
    protected DeptService deptService;
    protected UserService userService;
    protected CourseService courseService;

    @Override
    public void init() throws ServletException {
        companyService = new CompanyServiceImpl();
        deptService = new DeptServiceImpl();
        userService = new UserServiceImpl();
        courseService = new CourseServiceImpl();
    }
}

(8) Create / WEB-INF/pages/store/course directory, then find all pages under module page \ course from today's course materials and copy them to the directory just created

(9) Modify the saving method of the business layer and add the saving of the creation time

@Override
public void save(Course course) {
    SqlSession sqlSession = null;
    try{
        //1. Get SqlSession
        sqlSession = MapperFactory.getSqlSession();
        //2. Get Dao
        CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class);
        //id is obtained using the generation policy of UUID
        String id = UUID.randomUUID().toString();
        course.setId(id);

        //Add creation time
        course.setCreateTime(new Date());

        //3. Call Dao layer operation
        courseDao.save(course);
        //4. Submission of services
        TransactionUtil.commit(sqlSession);
    }catch (Exception e){
        TransactionUtil.rollback(sqlSession);
        throw new RuntimeException(e);
        //Log
    }finally {
        try {
            TransactionUtil.close(sqlSession);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

(10) When modifying, our creation time is not allowed to be modified. Therefore, we update the dao layer to remove the modification of the creation time, find the update in the persistent layer mapping configuration file CourseDao.xml corresponding to CourseDao, and remove the creation time

<!--Configure full field update when the provided data is null When, the database data is updated to null-->
<update id="update" parameterType="com.xxx.domain.store.Course">
    update st_course
    set name = #{name,jdbcType=VARCHAR},
    remark = #{remark,jdbcType=VARCHAR},
    state = #{state,jdbcType=VARCHAR}
    where id = #{id,jdbcType=VARCHAR}
</update>

(11) Solve the problem of site character coding. Find the web layer resource file \ CharacterEncodingFilter.java from today's course materials

Then create a package com.xxx.web.filters, and then copy the file to the package

(12) Start the project for testing

3. Directory module

(1) Create directory entity: com.xxx.domain.store.Catalog

public class Catalog {
    private String id;
    private String name;
    private String remark;
    private String state;
    private Date createTime;
    private String courseId;

    private Course course;

	// getter/setter omitted
}

(2) Create Dao interface: com.xxx.dao.store.CatalogDao

public interface CatalogDao {
    int save(Catalog catalog);

    int delete(Catalog catalog);

    int update(Catalog catalog);

    Catalog findById(String id);

    List<Catalog> findAll();
}

(3) Copy dao mapping configuration file: completed earlier

(4) Create business layer interface: com.xxx.service.store.CatalogService

public interface CatalogService {
    /**
     * add to
     * @param catalog
     * @return
     */
    void save(Catalog catalog);

    /**
     * delete
     * @param catalog
     * @return
     */
    void delete(Catalog catalog);

    /**
     * modify
     * @param catalog
     * @return
     */
    void update(Catalog catalog);

    /**
     * Query single
     * @param id Query criteria (id)
     * @return Query results, single object
     */
    Catalog findById(String id);

    /**
     * Query all data
     * @return List object of all data
     */
    List<Catalog> findAll();

    /**
     * Paging query data
     * @param page Page number
     * @param size Total data displayed per page
     * @return
     */
    PageInfo findAll(int page, int size);
}

(5) Create a business layer implementation class: com.xxx.service.store.impl.CatalogServiceImpl

public class CatalogServiceImpl implements CatalogService {
    @Override
    public void save(Catalog catalog) {
        SqlSession sqlSession = null;
        try {
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
            //id is obtained using the generation policy of UUID
            String id = UUID.randomUUID().toString();
            catalog.setId(id);

            //3. Call Dao layer operation
            catalogDao.save(catalog);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        } catch (Exception e) {
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        } finally {
            try {
                TransactionUtil.close(sqlSession);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void delete(Catalog catalog) {
        SqlSession sqlSession = null;
        try {
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
            //3. Call Dao layer operation
            catalogDao.delete(catalog);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        } catch (Exception e) {
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        } finally {
            try {
                TransactionUtil.close(sqlSession);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void update(Catalog catalog) {
        SqlSession sqlSession = null;
        try {
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
            //3. Call Dao layer operation
            catalogDao.update(catalog);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        } catch (Exception e) {
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        } finally {
            try {
                TransactionUtil.close(sqlSession);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public Catalog findById(String id) {
        SqlSession sqlSession = null;
        try {
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
            //3. Call Dao layer operation
            return catalogDao.findById(id);
        } catch (Exception e) {
            throw new RuntimeException(e);
            //Log
        } finally {
            try {
                TransactionUtil.close(sqlSession);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<Catalog> findAll() {
        SqlSession sqlSession = null;
        try {
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
            //3. Call Dao layer operation
            return catalogDao.findAll();
        } catch (Exception e) {
            throw new RuntimeException(e);
            //Log
        } finally {
            try {
                TransactionUtil.close(sqlSession);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public PageInfo findAll(int page, int size) {
        SqlSession sqlSession = null;
        try {
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
            //3. Call Dao layer operation
            PageHelper.startPage(page, size);
            List<Catalog> all = catalogDao.findAll();
            PageInfo pageInfo = new PageInfo(all);
            return pageInfo;
        } catch (Exception e) {
            throw new RuntimeException(e);
            //Log
        } finally {
            try {
                TransactionUtil.close(sqlSession);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

(6) Create servlet: com.xxx.web.controller.store.CatalogServlet

// uri:/store/catalog?operation=list
@WebServlet("/store/catalog")
public class CatalogServlet extends BaseServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String operation = request.getParameter("operation");
        if("list".equals(operation)){
            this.list(request,response);
        }else if("toAdd".equals(operation)){
            this.toAdd(request,response);
        }else if("save".equals(operation)){
            this.save(request, response);
        }else if("toEdit".equals(operation)){
            this.toEdit(request,response);
        }else if("edit".equals(operation)){
            this.edit(request,response);
        }else if("delete".equals(operation)){
            this.delete(request,response);
        }
    }

    private void list(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //Go to the list page
        //get data
        int page = 1;
        int size = 5;
        if(StringUtils.isNotBlank(request.getParameter("page"))){
            page = Integer.parseInt(request.getParameter("page"));
        }
        if(StringUtils.isNotBlank(request.getParameter("size"))){
            size = Integer.parseInt(request.getParameter("size"));
        }
        PageInfo all = catalogService.findAll(page, size);
        //Save the data to the specified location
        request.setAttribute("page",all);
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/catalog/list.jsp").forward(request,response);
    }

    private void toAdd(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/catalog/add.jsp").forward(request,response);
    }

    private void save(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //The data is obtained and encapsulated into an object
        Catalog catalog = BeanUtil.fillBean(request,Catalog.class,"yyyy-MM-dd");
        //Call the business layer interface save
        catalogService.save(catalog);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/catalog?operation=list");
    }

    private void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Query the data findById to modify
        String id = request.getParameter("id");
        Catalog catalog = catalogService.findById(id);
        //Load the data into the specified area for the page to obtain
        request.setAttribute("catalog",catalog);

        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/catalog/update.jsp").forward(request,response);
    }

    private void edit(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //The data is obtained and encapsulated into an object
        Catalog catalog = BeanUtil.fillBean(request,Catalog.class,"yyyy-MM-dd");
        //Call the business layer interface save
        catalogService.update(catalog);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/catalog?operation=list");
    }

    private void delete(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //The data is obtained and encapsulated into an object
        Catalog catalog = BeanUtil.fillBean(request,Catalog.class);
        //Call the business layer interface save
        catalogService.delete(catalog);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/catalog?operation=list");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }
}

(7) Modify BaseServlet and add CatalogService

public class BaseServlet extends HttpServlet {
    protected CompanyService companyService;
    protected DeptService deptService;
    protected UserService userService;
    protected CourseService courseService;
    protected CatalogService catalogService;

    @Override
    public void init() throws ServletException {
        companyService = new CompanyServiceImpl();
        deptService = new DeptServiceImpl();
        userService = new UserServiceImpl();
        courseService = new CourseServiceImpl();
        catalogService = new CatalogServiceImpl();
    }
}

(8) Create a page storage directory / WEB-INF/pages/store/catalog, and then find all pages under module page \ catalog from today's course materials to this directory

(9) Modify the servlet code, find the toAdd method, and query all subject data before adding the page

private void toAdd(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    //Load discipline information
    List<Course> all = courseService.findAll();
    request.setAttribute("courseList",all);
    //Jump page
    request.getRequestDispatcher("/WEB-INF/pages/store/catalog/add.jsp").forward(request,response);
}

(10) When saving the directory, save the creation time, modify the save method of the business layer, and add the save of the creation time

@Override
public void save(Catalog catalog) {
    SqlSession sqlSession = null;
    try {
        //1. Get SqlSession
        sqlSession = MapperFactory.getSqlSession();
        //2. Get Dao
        CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
        //id is obtained using the generation policy of UUID
        String id = UUID.randomUUID().toString();
        catalog.setId(id);
        catalog.setCreateTime(new Date());
        //3. Call Dao layer operation
        catalogDao.save(catalog);
        //4. Submission of services
        TransactionUtil.commit(sqlSession);
    } catch (Exception e) {
        TransactionUtil.rollback(sqlSession);
        throw new RuntimeException(e);
        //Log
    } finally {
        try {
            TransactionUtil.close(sqlSession);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

(11) Modify the servlet code, find the toEdit method, and query all subject information before going to the edit page,

private void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //Query the data findById to modify
    String id = request.getParameter("id");
    Catalog catalog = catalogService.findById(id);
    //Load the data into the specified area for the page to obtain
    request.setAttribute("catalog",catalog);

    //Load discipline information
    List<Course> all = courseService.findAll();
    request.setAttribute("courseList",all);

    //Jump page
    request.getRequestDispatcher("/WEB-INF/pages/store/catalog/update.jsp").forward(request,response);
}

(12) Start the project and test it

4. Topic module

4.1 rapid development of topic module

(1) Create topic entity: com.xxx.domain.store.Question

public class Question {
    private String id;			//Title ID

    private String companyId;	//Affiliated enterprise
    private String catalogId;	//Title directory ID

    private String remark;		//Topic introduction

    private String subject;     //stem

    private String analysis;	//Topic analysis

    private String type;       	//Topic type 1: single choice, 2: multiple choice, 3: short answer
    private String difficulty; 	//Degree of difficulty: 1 extremely easy 2 easy 3 ordinary 4 difficult 5 extremely difficult

    private String isClassic; 	//Classic interview question 0: No 1: Yes
    private String state;   	//Topic status 0: unavailable 1: available (only approved topics can be set)

    private String reviewStatus;//Approval status - 1 failed approval 0 in approval 1 passed approval
    private Date createTime;
    
    private Company company;
    private Catalog catalog;
    
	// getter/setter omitted
}

(2) Create Dao interface: com.xxx.dao.store.QuestionDao

public interface QuestionDao {

    int save(Question question);

    int delete(Question question);

    int update(Question question);

    Question findById(String id);

    List<Question> findAll();
}

(3) Add the mapping configuration file of the topic dao, which has been operated before, omitted

(4) Create business layer interface: com.xxx.service.store.QuestionService

public interface QuestionService {
    /**
     * add to
     * @param question
     * @return
     */
    void save(Question question);

    /**
     * delete
     * @param question
     * @return
     */
    void delete(Question question);

    /**
     * modify
     * @param question
     * @return
     */
    void update(Question question);

    /**
     * Query single
     * @param id Query criteria (id)
     * @return Query results, single object
     */
    Question findById(String id);

    /**
     * Query all data
     * @return List object of all data
     */
    List<Question> findAll();

    /**
     * Paging query data
     * @param page Page number
     * @param size Total data displayed per page
     * @return
     */
    PageInfo findAll(int page, int size);
}

(5) Create a business layer implementation class: com.xxx.service.store.impl.QuestionServiceImpl

public class QuestionServiceImpl implements QuestionService {
    @Override
    public void save(Question question) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);
            //id is obtained using the generation policy of UUID
            String id = UUID.randomUUID().toString();
            question.setId(id);

            //3. Call Dao layer operation
            questionDao.save(question);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        }catch (Exception e){
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void delete(Question question) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);
            //3. Call Dao layer operation
            questionDao.delete(question);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        }catch (Exception e){
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void update(Question question) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);
            //3. Call Dao layer operation
            questionDao.update(question);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        }catch (Exception e){
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public Question findById(String id) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);
            //3. Call Dao layer operation
            return questionDao.findById(id);
        }catch (Exception e){
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<Question> findAll() {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);
            //3. Call Dao layer operation
            return questionDao.findAll();
        }catch (Exception e){
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public PageInfo findAll(int page, int size) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);
            //3. Call Dao layer operation
            PageHelper.startPage(page,size);
            List<Question> all = questionDao.findAll();
            PageInfo pageInfo = new PageInfo(all);
            return pageInfo;
        }catch (Exception e){
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

(6) Create servlet: com.xxx.web.controller.store.QuestionServlet

// uri:/store/question?operation=list
@WebServlet("/store/question")
public class QuestionServlet extends BaseServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String operation = request.getParameter("operation");
        if("list".equals(operation)){
            this.list(request,response);
        }else if("toAdd".equals(operation)){
            this.toAdd(request,response);
        }else if("save".equals(operation)){
            this.save(request, response);
        }else if("toEdit".equals(operation)){
            this.toEdit(request,response);
        }else if("edit".equals(operation)){
            this.edit(request,response);
        }else if("delete".equals(operation)){
            this.delete(request,response);
        }
    }

    private void list(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //Go to the list page
        //get data
        int page = 1;
        int size = 5;
        if(StringUtils.isNotBlank(request.getParameter("page"))){
            page = Integer.parseInt(request.getParameter("page"));
        }
        if(StringUtils.isNotBlank(request.getParameter("size"))){
            size = Integer.parseInt(request.getParameter("size"));
        }
        PageInfo all = questionService.findAll(page, size);
        //Save the data to the specified location
        request.setAttribute("page",all);
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/question/list.jsp").forward(request,response);
    }

    private void toAdd(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/question/add.jsp").forward(request,response);
    }

    private void save(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //The data is obtained and encapsulated into an object
        Question question = BeanUtil.fillBean(request,Question.class,"yyyy-MM-dd");
        //Call the business layer interface save
        questionService.save(question);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/question?operation=list");
    }

    private void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Query the data findById to modify
        String id = request.getParameter("id");
        Question question = questionService.findById(id);
        //Load the data into the specified area for the page to obtain
        request.setAttribute("question",question);
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/question/update.jsp").forward(request,response);
    }

    private void edit(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //The data is obtained and encapsulated into an object
        Question question = BeanUtil.fillBean(request,Question.class,"yyyy-MM-dd");
        //Call the business layer interface save
        questionService.update(question);
        //Jump back to page list
        //list(request,response);
        response.sendRedirect(request.getContextPath()+"/store/question?operation=list");
    }

    private void delete(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //The data is obtained and encapsulated into an object
        Question question = BeanUtil.fillBean(request,Question.class);
        //Call the business layer interface save
        questionService.delete(question);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/question?operation=list");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }
}

(7) Modify BaserServlet and add QuestionService

public class BaseServlet extends HttpServlet {
    protected CompanyService companyService;
    protected DeptService deptService;
    protected UserService userService;
    protected CourseService courseService;
    protected CatalogService catalogService;
    protected QuestionService questionService;

    @Override
    public void init() throws ServletException {
        companyService = new CompanyServiceImpl();
        deptService = new DeptServiceImpl();
        userService = new UserServiceImpl();
        courseService = new CourseServiceImpl();
        catalogService = new CatalogServiceImpl();
        questionService = new QuestionServiceImpl();
    }
}

(8) Create a page storage directory, / WEB-INF/pages/store/question, find the module page \ question from today's course materials, and copy all the following pages to this directory

(9) Modify the servlet, find the toAdd method, and query the enterprise and directory data before adding the page

private void toAdd(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    List<Company> companyList = companyService.findAll();
    List<Catalog> catalogList = catalogService.findAll();
    request.setAttribute("companyList",companyList);
    request.setAttribute("catalogList",catalogList);

    //Jump page
    request.getRequestDispatcher("/WEB-INF/pages/store/question/add.jsp").forward(request,response);
}

Find the toEdit method to query the enterprise and directory data before modifying the page

private void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //Query the data findById to modify
    String id = request.getParameter("id");
    Question question = questionService.findById(id);
    //Load the data into the specified area for the page to obtain
    request.setAttribute("question",question);

    List<Company> companyList = companyService.findAll();
    List<Catalog> catalogList = catalogService.findAll();
    request.setAttribute("companyList",companyList);
    request.setAttribute("catalogList",catalogList);

    //Jump page
    request.getRequestDispatcher("/WEB-INF/pages/store/question/update.jsp").forward(request,response);
}

(10) Modify the business layer code and find the method to add data. You need to add data of approval status and creation time

@Override
public void save(Question question) {
    SqlSession sqlSession = null;
    try{
        //1. Get SqlSession
        sqlSession = MapperFactory.getSqlSession();
        //2. Get Dao
        QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);
        //id is obtained using the generation policy of UUID
        String id = UUID.randomUUID().toString();
        question.setId(id);

        //Set the default approval status of the newly created topic to Unapproved (0)
        question.setReviewStatus("0");
        question.setCreateTime(new Date());

        //3. Call Dao layer operation
        questionDao.save(question);
        //4. Submission of services
        TransactionUtil.commit(sqlSession);
    }catch (Exception e){
        TransactionUtil.rollback(sqlSession);
        throw new RuntimeException(e);
        //Log
    }finally {
        try {
            TransactionUtil.close(sqlSession);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

(11) Modify the sorting when querying all data, and modify the corresponding dao mapping configuration file QuestionDao.xml

<!--Configure all queries with conditions-->
<select id="findAll" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from st_question
    order by create_time desc
</select>

(12) During data modification, some data cannot be modified. We can control it in the persistence layer mapping configuration file

<!--Configure full field update when the provided data is null When, the database data is updated to null-->
<update id="update" parameterType="com.xxx.domain.store.Question">
    update
    st_question
    set
    company_id = #{companyId,jdbcType=VARCHAR},
    catalog_id = #{catalogId,jdbcType=VARCHAR},
    remark = #{remark,jdbcType=VARCHAR},
    subject = #{subject,jdbcType=VARCHAR},
    analysis = #{analysis,jdbcType=VARCHAR},
    difficulty = #{difficulty,jdbcType=VARCHAR},
    is_classic = #{isClassic,jdbcType=VARCHAR},
    state = #{state,jdbcType=VARCHAR}
    where
    id = #{id,jdbcType=VARCHAR}
</update>

4.2 basic demonstration of file upload

The file upload function needs the cooperation of foreground function and background function

Front desk: three elements of file upload

  • The page provides form elements for file upload

  • The value of the form enctype attribute is multipart / form data

  • The form submission method must be POST, and the get method cannot submit a large amount of data

Background: there are many technologies that can be used. Here we use the Commons fileUpload component provided by apache to complete the last file operation. The background operation steps are as follows

  • Confirm whether the requested operation supports file upload
  • Create a disk factory object to save the file uploaded from the page to disk
  • Get the server file upload core object
  • Read data
  • Operate the file form read into the data and write the content to the specified location

Let's start the demonstration of file upload:

(1) Find the file download \ testFileUpload.jsp file upload page from today's course materials and add it to the project / WEB-INF/pages/store/question directory

(2) Add a new button on the list.jsp page under the question directory, and click this button to jump to the file upload page

<button type="button" class="btn btn-default" title="Test file upload" onclick='location.href="${ctx}/store/question?operation=toTestUpload"'><i class="fa fa-file-o"></i> Test file upload</button>

(3) Add the toTestUpload method in the QuestionServlet to jump to the file upload page

@WebServlet("/store/question")
public class QuestionServlet extends BaseServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String operation = request.getParameter("operation");
        if("list".equals(operation)){
            this.list(request,response);
        }else if("toAdd".equals(operation)){
            this.toAdd(request,response);
        }else if("save".equals(operation)){
            this.save(request, response);
        }else if("toEdit".equals(operation)){
            this.toEdit(request,response);
        }else if("edit".equals(operation)){
            this.edit(request,response);
        }else if("delete".equals(operation)){
            this.delete(request,response);
        }else if("toTestUpload".equals(operation)){
            this.toTestUpload(request,response);
        }else if("testUpload".equals(operation)){
            try {
                this.testUpload(request,response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    private void toTestUpload(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/pages/store/question/testFileUpload.jsp").forward(request,response);
    }

    private void testUpload(HttpServletRequest request,HttpServletResponse response) throws Exception {
      
    }
}   

(4) Background code for file upload

private void testUpload(HttpServletRequest request,HttpServletResponse response) throws Exception {
    //1. Confirm whether the operation supports file upload, enctype = "multipart / form data"
    if(ServletFileUpload.isMultipartContent(request)){
        //2. Create a disk factory object
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //3.Servlet file upload core object
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        //4. Read data from request
        List<FileItem> fileItems = fileUpload.parseRequest(request);

        for(FileItem item : fileItems){
            //5. Is the current form a file form
            if(!item.isFormField()){
                //6. Write the content to the specified location from the place where the file is temporarily stored
                item.write(new File(this.getServletContext().getRealPath("upload"),item.getName()));
            }
        }
    }
}

You need to create an upload directory under the webapp directory of the project to store the uploaded files

(5) Start test

4.3 add file upload when adding topics

(1) Add the attributes of the picture to the title entity

public class Question {
	// Other attributes are omitted
    private String picture;
    
    public String getPicture() {
        return picture;
    }
    public void setPicture(String picture) {
        this.picture = picture;
    }
}    

(2) Add the configuration of the picture field in the corresponding dao mapping configuration file. In the resultMap, query the sql fragment, save and update several locations, and add the mapping configuration. There is no need to change the picture name when updating, so the update of the picture name is removed

<!--Configure the correspondence between entity class attributes and columns in database tables-->
<resultMap id="BaseResultMap" type="com.xxx.domain.store.Question">
    <id column="id" jdbcType="VARCHAR" property="id"/>
    <result column="company_id" jdbcType="VARCHAR" property="companyId"/>
    <result column="catalog_id" jdbcType="VARCHAR" property="catalogId"/>
    <result column="remark" jdbcType="VARCHAR" property="remark"/>
    <result column="subject" jdbcType="VARCHAR" property="subject"/>
    <result column="analysis" jdbcType="VARCHAR" property="analysis"/>
    <result column="type" jdbcType="VARCHAR" property="type"/>
    <result column="difficulty" jdbcType="VARCHAR" property="difficulty"/>
    <result column="is_classic" jdbcType="VARCHAR" property="isClassic"/>
    <result column="state" jdbcType="VARCHAR" property="state"/>
    <result column="review_status" jdbcType="VARCHAR" property="reviewStatus"/>
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
    <result column="picture" jdbcType="VARCHAR" property="picture"/>
    <association
                 property="company"
                 column="company_id"
                 javaType="com.xxx.domain.store.Course"
                 select="com.xxx.dao.store.CompanyDao.findById"/>
    <association
                 property="catalog"
                 column="catalog_id"
                 javaType="com.xxx.domain.store.Course"
                 select="com.xxx.dao.store.CatalogDao.findById"
                 />
</resultMap>
<!--Configure public column names for queries SQL sentence-->
<sql id="Base_Column_List">
    id, catalog_id, company_id, remark,subject,analysis,type, difficulty, is_classic,
    state, review_status, create_time, picture
</sql>
<!--Configure full field insertion. When a field has no value, it will be inserted null-->
<insert id="save" parameterType="com.xxx.domain.store.Question">
    insert into st_question(id, company_id, catalog_id, remark, subject, analysis, type,
    difficulty, is_classic, state, review_status, create_time ,picture )
    values (#{id,jdbcType=VARCHAR}, #{companyId,jdbcType=VARCHAR}, #{catalogId,jdbcType=VARCHAR},
    #{remark,jdbcType=VARCHAR}, #{subject,jdbcType=VARCHAR}, #{analysis,jdbcType=VARCHAR},
    #{type,jdbcType=VARCHAR}, #{difficulty,jdbcType=VARCHAR}, #{isClassic,jdbcType=VARCHAR},
    #{state,jdbcType=VARCHAR}, #{reviewStatus,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP},
    #{picture,jdbcType=VARCHAR} )
</insert>
<!--Configure full field update when the provided data is null When, the database data is updated to null-->
<update id="update" parameterType="com.xxx.domain.store.Question">
    update
    st_question
    set
    company_id = #{companyId,jdbcType=VARCHAR},
    catalog_id = #{catalogId,jdbcType=VARCHAR},
    remark = #{remark,jdbcType=VARCHAR},
    subject = #{subject,jdbcType=VARCHAR},
    analysis = #{analysis,jdbcType=VARCHAR},
    difficulty = #{difficulty,jdbcType=VARCHAR},
    is_classic = #{isClassic,jdbcType=VARCHAR},
    state = #{state,jdbcType=VARCHAR}
    where
    id = #{id,jdbcType=VARCHAR}
</update>

(3) Add the form item of image upload in the add page add.jsp of the question module

<form id="editForm" action="${ctx}/store/question?operation=save" method="post" enctype="multipart/form-data">
    <!--Other elements are omitted-->
    
    <div class="col-md-2 title">Title Stem picture</div><!--Put it behind the question stem-->
    <div class="col-md-10 data ">
        <input type="file" class="form-control" placeholder="Title Stem picture" name="picture">
    </div> 
</form>

(4) Modify the save method of saving topics in the servlet. The first thing to change is the way to receive data. We should receive it in the form of file upload

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String operation = request.getParameter("operation");
    if("list".equals(operation)){
        this.list(request,response);
    }else if("toAdd".equals(operation)){
        this.toAdd(request,response);
    }else if("save".equals(operation)){
        try {
            this.save(request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }else if("toEdit".equals(operation)){
        this.toEdit(request,response);
    }else if("edit".equals(operation)){
        this.edit(request,response);
    }else if("delete".equals(operation)){
        this.delete(request,response);
    }else if("toTestUpload".equals(operation)){
        this.toTestUpload(request,response);
    }else if("testUpload".equals(operation)){
        try {
            this.testUpload(request,response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

private void save(HttpServletRequest request,HttpServletResponse response) throws Exception {
    //1. Confirm whether the operation supports file upload, enctype = "multipart / form data"
    if(ServletFileUpload.isMultipartContent(request)){
        //2. Create a disk factory object
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //3.Servlet file upload core object
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        //4. Read data from request
        List<FileItem> fileItems = fileUpload.parseRequest(request);
        // --Handle the common data submitted from the form
        //The data is obtained and encapsulated into an object
        Question question = BeanUtil.fillBean(fileItems,Question.class);
        //Call the business layer interface save
        questionService.save(question);

        // --Process the file data submitted from the form
        for(FileItem item : fileItems){
            //5. Is the current form a file form
            if(!item.isFormField()){
                //6. Write the content to the specified location from the place where the file is temporarily stored
                item.write(new File(this.getServletContext().getRealPath("upload"),item.getName()));
            }
        }
    }
    //Jump back to page list
    response.sendRedirect(request.getContextPath()+"/store/question?operation=list");
}

4.4 problem of duplicate name in file upload

(1) Add the display of the picture name in the list.jsp page of the question module

<!--Data list-->
<table id="dataList" class="table table-bordered table-striped table-hover dataTable">
    <thead>
        <tr>
            <th class="" style="padding-right:0px;">
                <input type="checkbox" name="selid" onclick="checkAll('id',this)">
            </th>
            <th class="sorting">picture</th>
            <th class="sorting">enterprise</th>
            <th class="sorting">category</th>
            <th class="sorting">subject</th>
            <th class="sorting">type</th>
            <th class="sorting">difficulty</th>
            <th class="sorting">Classic interview questions</th>
            <th class="sorting">state</th>
            <th class="sorting">findings of audit</th>
            <th class="text-center">operation</th>
        </tr>
    </thead>
    <tbody>
        <c:forEach items="${page.list}" var="o" varStatus="status">
            <tr class="odd" onmouseover="this.className='highlight'" onmouseout="this.className='odd'" >
                <td><input type="checkbox" name="id" value="${o.id}"/></td>
                <td>${o.picture}</td>
                <td>${o.company.name}</td>
                <td>${o.catalog.name}</td>
                <td>${o.subject}</td>
                <td>
                    <c:choose>
                        <c:when test="${o.type eq '1'}">Single choice</c:when>
                        <c:when test="${o.type eq '2'}">Multiple choice</c:when>
                        <c:when test="${o.type eq '3'}">Brief answer</c:when>
                    </c:choose>
                </td>
                <td>
                    <c:forEach begin="1" end="${o.difficulty}">
                        ★
                    </c:forEach>
                </td>
                <td>${o.isClassic eq "1" ? "Classic questions":"General questions"}</td>
                <td>${o.state eq "1" ? "<font color='green'>Enable</font>" : "<font color='red'>Disable</font>"}</td>
                <td>
                    <c:choose>
                        <c:when test="${o.reviewStatus eq '1'}"><font color="green">Approved</font></c:when>
                        <c:when test="${o.reviewStatus eq '0'}">Under review</c:when>
                        <c:when test="${o.reviewStatus eq '-1'}"><font color="red">Audit failed</font></c:when>
                    </c:choose>
                </td>
                <th class="text-center">
                    <button type="button" class="btn bg-olive btn-xs" onclick='location.href="${ctx}/store/question?operation=toEdit&id=${o.id}"'>edit</button>
                    <button type="button" class="btn bg-olive btn-xs" onclick='location.href="${ctx}/store/question?operation=toExamine&id=${o.id}"'>to examine</button>
                </th>
            </tr>
        </c:forEach>
    </tbody>
</table>

Common problems in file upload: file name duplication

(1) Modify the saving method of the business layer interface QuestionService, add the return value, and return the name of the picture

/**
     * add to
     * @param question
     * @return Saved picture name
     */
String save(Question question);

(2) Modify the implementation class, add the storage of the picture name and return the name of the picture. The picture name uses the id of the data

@Override
public String save(Question question) {
    SqlSession sqlSession = null;
    try{
        //1. Get SqlSession
        sqlSession = MapperFactory.getSqlSession();
        //2. Get Dao
        QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);
        //id is obtained using the generation policy of UUID
        String id = UUID.randomUUID().toString();
        question.setId(id);

        //Set the default approval status of the newly created topic to Unapproved (0)
        question.setReviewStatus("0");
        question.setCreateTime(new Date());
        //Set the currently stored picture name as the id value
        question.setPicture(id);

        //3. Call Dao layer operation
        questionDao.save(question);
        //4. Submission of services
        TransactionUtil.commit(sqlSession);
        return id;
    }catch (Exception e){
        TransactionUtil.rollback(sqlSession);
        throw new RuntimeException(e);
        //Log
    }finally {
        try {
            TransactionUtil.close(sqlSession);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

(3) Receive the picture name in the save method in the servlet

private void save(HttpServletRequest request,HttpServletResponse response) throws Exception {
    //1. Confirm whether the operation supports file upload, enctype = "multipart / form data"
    if(ServletFileUpload.isMultipartContent(request)){
        //2. Create a disk factory object
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //3.Servlet file upload core object
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        //4. Read data from request
        List<FileItem> fileItems = fileUpload.parseRequest(request);
        // --Handle the common data submitted from the form
        //The data is obtained and encapsulated into an object
        Question question = BeanUtil.fillBean(fileItems,Question.class);
        //Call the business layer interface save
        String picture = questionService.save(question);

        // --Process the file data submitted from the form
        for(FileItem item : fileItems){
            //5. Is the current form a file form
            if(!item.isFormField()){
                //6. Write the content to the specified location from the place where the file is temporarily stored
                item.write(new File(this.getServletContext().getRealPath("upload"),picture));
            }
        }
    }
    //Jump back to page list
    response.sendRedirect(request.getContextPath()+"/store/question?operation=list");
}

4.5 add file upload when modifying the title

The picture needs to be displayed before modification

(1) Add the picture display in the update.jsp page of the question module, add the form item of uploading the picture during modification, and modify the form accordingly

<form id="editForm" action="${ctx}/store/question?operation=edit" method="post" enctype="multipart/form-data">
		<!--Other omissions-->
   
            <div class="col-md-2 title">Title Stem picture</div>
            <div class="col-md-10 data ">
                <input type="file" class="form-control" placeholder="Title Stem picture" name="picture" value="${question.picture}">
            </div>

            <div class="col-md-2 title">Title Stem picture</div>
            <div class="col-md-10 data ">
                <img src="${ctx}/upload/${question.picture}"/>
            </div>        
</form>

(2) Modify the servlet in the background and find the edit method to modify it

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String operation = request.getParameter("operation");
    if("list".equals(operation)){
        this.list(request,response);
    }else if("toAdd".equals(operation)){
        this.toAdd(request,response);
    }else if("save".equals(operation)){
        try {
            this.save(request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }else if("toEdit".equals(operation)){
        this.toEdit(request,response);
    }else if("edit".equals(operation)){
        try {
            this.edit(request,response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }else if("delete".equals(operation)){
        this.delete(request,response);
    }else if("toTestUpload".equals(operation)){
        this.toTestUpload(request,response);
    }else if("testUpload".equals(operation)){
        try {
            this.testUpload(request,response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
private void edit(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //1. Confirm whether the operation supports file upload, enctype = "multipart / form data"
    if(ServletFileUpload.isMultipartContent(request)){
        //2. Create a disk factory object
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //3.Servlet file upload core object
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        //4. Read data from request
        List<FileItem> fileItems = fileUpload.parseRequest(request);
        // --Handle the common data submitted from the form
        //The data is obtained and encapsulated into an object
        Question question = BeanUtil.fillBean(fileItems,Question.class);
        //Call the business layer interface save
        questionService.update(question);

        // --Process the file data submitted from the form
        for(FileItem item : fileItems){
            //5. Is the current form a file form
            if(!item.isFormField()){
                //6. Write the content to the specified location from the place where the file is temporarily stored
                item.write(new File(this.getServletContext().getRealPath("upload"),question.getId()));
            }
        }
    }
    //Jump back to page list
    response.sendRedirect(request.getContextPath()+"/store/question?operation=list");
}

(3) When the update method of the business layer implementation class modifies the data, the picture name does not need to be modified. For this, we remove the changes to the picture during the update operation of the persistence layer. We change the corresponding mapping configuration file (this step has been completed before) as follows

<!--Configure full field update when the provided data is null When, the database data is updated to null-->
<update id="update" parameterType="com.xxx.domain.store.Question">
    update
    st_question
    set
    company_id = #{companyId,jdbcType=VARCHAR},
    catalog_id = #{catalogId,jdbcType=VARCHAR},
    remark = #{remark,jdbcType=VARCHAR},
    subject = #{subject,jdbcType=VARCHAR},
    analysis = #{analysis,jdbcType=VARCHAR},
    difficulty = #{difficulty,jdbcType=VARCHAR},
    is_classic = #{isClassic,jdbcType=VARCHAR},
    state = #{state,jdbcType=VARCHAR}
    where
    id = #{id,jdbcType=VARCHAR}
</update>

4.6 optional operation and display of compatible picture upload

Question:

If you do not choose to upload a picture when adding it, the picture will not be displayed on the page when modifying it, as shown in the following figure

Causes of problems:

Although no pictures are uploaded when adding, the data id is used as the name of the picture by default when we save the data, so we will look for the picture with this name when displaying it, but we haven't uploaded it, so we won't find it

Improvement method:

Make a judgment when adding a picture. If the picture is uploaded, save the name of the picture. If it is not uploaded, the name of the picture will not be saved

(1) In the add method of the servlet, to judge whether a file is currently uploaded, you can use a Boolean mark to indicate whether a file is uploaded. At the same time, when the business layer performs the save operation, you can pass the mark whether there is a picture

private void save(HttpServletRequest request,HttpServletResponse response) throws Exception {
    //1. Confirm whether the operation supports file upload, enctype = "multipart / form data"
    if(ServletFileUpload.isMultipartContent(request)){
        //2. Create a disk factory object
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //3.Servlet file upload core object
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        //4. Read data from request
        List<FileItem> fileItems = fileUpload.parseRequest(request);

        //Create a flag bit to mark the current time when there is an operation to upload files
        boolean flag = false;
        for(FileItem item :fileItems){
            if(StringUtils.isNotBlank(item.getName())){
                flag = true;
                break;
            }
        }

        // --Handle the common data submitted from the form
        //The data is obtained and encapsulated into an object
        Question question = BeanUtil.fillBean(fileItems,Question.class);
        //Call the business layer interface save
        String picture = questionService.save(question , flag);

        // --Process the file data submitted from the form
        for(FileItem item : fileItems){
            //5. Is the current form a file form
            if(!item.isFormField()){
                //6. Write the content to the specified location from the place where the file is temporarily stored
                item.write(new File(this.getServletContext().getRealPath("upload"),picture));
            }
        }
    }
    //Jump back to page list
    response.sendRedirect(request.getContextPath()+"/store/question?operation=list");
}

(2) Modify the business layer interface method save and add parameters

/**
     * add to
     * @param question
     * @param flag Is there an operation to upload files
     * @return Saved picture name
     */
String save(Question question,boolean flag);

(3) Modify the corresponding interface implementation class:

@Override
public String save(Question question,boolean flag) {
    SqlSession sqlSession = null;
    try{
        //1. Get SqlSession
        sqlSession = MapperFactory.getSqlSession();
        //2. Get Dao
        QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);
        //id is obtained using the generation policy of UUID
        String id = UUID.randomUUID().toString();
        question.setId(id);
        //Set the default approval status of the newly created topic to Unapproved (0)
        question.setReviewStatus("0");
        question.setCreateTime(new Date());
        //The file uploaded by the front end is detected. Record the file name, otherwise it will not be recorded
        if(flag) {
            //Set the currently stored picture name as the id value
            question.setPicture(id);
        }
        //3. Call Dao layer operation
        questionDao.save(question);
        //4. Submission of services
        TransactionUtil.commit(sqlSession);
        return id;
    }catch (Exception e){
        TransactionUtil.rollback(sqlSession);
        throw new RuntimeException(e);
        //Log
    }finally {
        try {
            TransactionUtil.close(sqlSession);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

(4) When modifying, if there is no picture, the picture will not be displayed. If there is picture information, we can use < C: if > to judge

<div class="col-md-2 title">Title Stem picture</div>
<div class="col-md-10 data ">
    <input type="file" class="form-control" placeholder="Title Stem picture" name="picture" value="${question.picture}">
</div>

<c:if test="${question.picture.length() > 0}">
    <div class="col-md-2 title">Title Stem picture</div>
    <div class="col-md-10 data ">
        <img src="${ctx}/upload/${question.picture}"/>
    </div>
</c:if>

(5) After the page is modified, we also need to make judgment when making real modification. If the picture is uploaded, we will modify it, otherwise we will not modify it.

Find the edit method of the servlet in the background and make the following modifications

private void edit(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //1. Confirm whether the operation supports file upload, enctype = "multipart / form data"
    if(ServletFileUpload.isMultipartContent(request)){
        //2. Create a disk factory object
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //3.Servlet file upload core object
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        //4. Read data from request
        List<FileItem> fileItems = fileUpload.parseRequest(request);
        //Create a flag bit to mark the current time when there is an operation to upload files
        boolean flag = false;
        for(FileItem item :fileItems){
            if(StringUtils.isNotBlank(item.getName())){
                flag = true;
                break;
            }
        }
        // --Handle the common data submitted from the form
        //The data is obtained and encapsulated into an object
        Question question = BeanUtil.fillBean(fileItems,Question.class);
        //Call the business layer interface save
        questionService.update(question , flag);
        // --Process the file data submitted from the form
        for(FileItem item : fileItems){
            //5. Is the current form a file form
            if(!item.isFormField()){
                //6. Write the content to the specified location from the place where the file is temporarily stored
                item.write(new File(this.getServletContext().getRealPath("upload"),question.getId()));
            }
        }
    }
    //Jump back to page list
    response.sendRedirect(request.getContextPath()+"/store/question?operation=list");
}

(6) Similarly, you need to modify the business layer interface and add the parameter whether to modify the picture on the update method

/**
     * modify
     * @param question
     * @param flag Is there an operation to upload files
     * @return
     */
void update(Question question,boolean flag);

(7) Modify the method in the business layer implementation class

@Override
public void update(Question question, boolean flag) {
    SqlSession sqlSession = null;
    try{
        //1. Get SqlSession
        sqlSession = MapperFactory.getSqlSession();
        //2. Get Dao
        QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class);

        //The file uploaded by the front end is detected. Record the file name, otherwise it will not be recorded
        if(flag) {
            //Set the currently stored picture name as the id value
            question.setPicture(question.getId());
        }

        //3. Call Dao layer operation
        questionDao.update(question);
        //4. Submission of services
        TransactionUtil.commit(sqlSession);
    }catch (Exception e){
        TransactionUtil.rollback(sqlSession);
        throw new RuntimeException(e);
        //Log
    }finally {
        try {
            TransactionUtil.close(sqlSession);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

(8) When the dao of the persistence layer really performs the update operation, we add the update to the image, and we can modify the corresponding mapping configuration file

<!--Configure full field update when the provided data is null When, the database data is updated to null-->
<update id="update" parameterType="com.xxx.domain.store.Question">
    update
    st_question
    set
    company_id = #{companyId,jdbcType=VARCHAR},
    catalog_id = #{catalogId,jdbcType=VARCHAR},
    remark = #{remark,jdbcType=VARCHAR},
    subject = #{subject,jdbcType=VARCHAR},
    analysis = #{analysis,jdbcType=VARCHAR},
    difficulty = #{difficulty,jdbcType=VARCHAR},
    is_classic = #{isClassic,jdbcType=VARCHAR},
    picture = #{picture,jdbcType=VARCHAR},
    state = #{state,jdbcType=VARCHAR}
    where
    id = #{id,jdbcType=VARCHAR}
</update>

5. Topic option module

5.1 list page making

(1) Create a topic option entity: com.xxx.domain.store.QuestionItem

public class QuestionItem {
    private String id;          	//ID
    private String questionId;  //Title ID
    private String content;     //Option content
    private String picture;      //Option picture
    private String isRight;    //Is the correct answer

    @Override
    public String toString() {
        return "QuestionItem{" +
                "id='" + id + '\'' +
                ", questionId='" + questionId + '\'' +
                ", content='" + content + '\'' +
                ", picture='" + picture + '\'' +
                ", isRight='" + isRight + '\'' +
                '}';
    }

	// getter/setter method omitted
}

(2) Create Dao interface: com.xxx.dao.store.QuestionItemDao

public interface QuestionItemDao {
 	int save(QuestionItem questionItem);

    int delete(QuestionItem questionItem);

    int update(QuestionItem questionItem);

    QuestionItem findById(String id);

    List<QuestionItem> findAll();
}

(3) Add the corresponding mapping profile, which has been imported before

(4) Create business layer interface: com.xxx.service.store.QuestionItemService

public interface QuestionItemService {

    /**
     * add to
     * @param questionItem
     * @return
     */
    void save(QuestionItem questionItem);

    /**
     * delete
     * @param questionItem
     * @return
     */
    void delete(QuestionItem questionItem);

    /**
     * modify
     * @param questionItem
     * @return
     */
    void update(QuestionItem questionItem);

    /**
     * Query single
     * @param id Query criteria (id)
     * @return Query results, single object
     */
    QuestionItem findById(String id);

    /**
     * Query all data
     * @return List object of all data
     */
    List<QuestionItem> findAll();

    /**
     * Paging query data
     * @param page Page number
     * @param size Total data displayed per page
     * @return
     */
    PageInfo findAll(int page, int size);
}

(5) Create a business layer implementation class: com.xxx.service.store.impl.QuestionItemServiceImpl

We copy and transform based on CompanyServiceImpl

public class QuestionItemServiceImpl implements QuestionItemService {
    @Override
    public void save(QuestionItem questionItem) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class);
            //id is obtained using the generation policy of UUID
            String id = UUID.randomUUID().toString();
            questionItem.setId(id);
            //3. Call Dao layer operation
            questionItemDao.save(questionItem);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        }catch (Exception e){
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void delete(QuestionItem questionItem) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class);
            //3. Call Dao layer operation
            questionItemDao.delete(questionItem);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        }catch (Exception e){
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void update(QuestionItem questionItem) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class);
            //3. Call Dao layer operation
            questionItemDao.update(questionItem);
            //4. Submission of services
            TransactionUtil.commit(sqlSession);
        }catch (Exception e){
            TransactionUtil.rollback(sqlSession);
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public QuestionItem findById(String id) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class);
            //3. Call Dao layer operation
            return questionItemDao.findById(id);
        }catch (Exception e){
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<QuestionItem> findAll() {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class);
            //3. Call Dao layer operation
            return questionItemDao.findAll();
        }catch (Exception e){
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public PageInfo findAll(int page, int size) {
        SqlSession sqlSession = null;
        try{
            //1. Get SqlSession
            sqlSession = MapperFactory.getSqlSession();
            //2. Get Dao
            QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class);
            //3. Call Dao layer operation
            PageHelper.startPage(page,size);
            List<QuestionItem> all = questionItemDao.findAll();
            PageInfo pageInfo = new PageInfo(all);
            return pageInfo;
        }catch (Exception e){
            throw new RuntimeException(e);
            //Log
        }finally {
            try {
                TransactionUtil.close(sqlSession);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

(6) Create servlet: com.xxx.web.controller.store.QuestionItemServlet

Modification based on CompanyServlet copy (after modification, some methods are actually useless. We don't need to modify them for the time being, and we will modify them level by level later)

@WebServlet("/store/questionItem")
public class QuestionItemServlet extends BaseServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String operation = request.getParameter("operation");
        if("list".equals(operation)){
            this.list(request,response);
        }else if("toAdd".equals(operation)){
            this.toAdd(request,response);
        }else if("save".equals(operation)){
            this.save(request, response);
        }else if("toEdit".equals(operation)){
            this.toEdit(request,response);
        }else if("edit".equals(operation)){
            this.edit(request,response);
        }else if("delete".equals(operation)){
            this.delete(request,response);
        }
    }

    private void list(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //Go to the list page
        //get data
        int page = 1;
        int size = 5;
        if(StringUtils.isNotBlank(request.getParameter("page"))){
            page = Integer.parseInt(request.getParameter("page"));
        }
        if(StringUtils.isNotBlank(request.getParameter("size"))){
            size = Integer.parseInt(request.getParameter("size"));
        }
        PageInfo all = questionItemService.findAll(page, size);
        //Save the data to the specified location
        request.setAttribute("page",all);
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp").forward(request,response);
    }

    private void toAdd(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/add.jsp").forward(request,response);
    }

    private void save(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        //The data is obtained and encapsulated into an object
        QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd");
        //Call the business layer interface save
        questionItemService.save(questionItem);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/questionItem?operation=list");
    }

    private void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Query the data findById to modify
        String id = request.getParameter("id");
        QuestionItem questionItem = questionItemService.findById(id);
        //Load the data into the specified area for the page to obtain
        request.setAttribute("questionItem",questionItem);
        //Jump page
        request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/update.jsp").forward(request,response);
    }

    private void edit(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //The data is obtained and encapsulated into an object
        QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd");
        //Call the business layer interface save
        questionItemService.update(questionItem);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/questionItem?operation=list");
    }

    private void delete(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //The data is obtained and encapsulated into an object
        QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class);
        //Call the business layer interface save
        questionItemService.delete(questionItem);
        //Jump back to page list
        response.sendRedirect(request.getContextPath()+"/store/questionItem?operation=list");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }

(7) Add QuestionItemService in BaseServlet

public class BaseServlet extends HttpServlet {
    protected CompanyService companyService;
    protected DeptService deptService;
    protected UserService userService;
    protected CourseService courseService;
    protected CatalogService catalogService;
    protected QuestionService questionService;
    protected QuestionItemService questionItemService;

    @Override
    public void init() throws ServletException {
        companyService = new CompanyServiceImpl();
        deptService = new DeptServiceImpl();
        userService = new UserServiceImpl();
        courseService = new CourseServiceImpl();
        catalogService = new CatalogServiceImpl();
        questionService = new QuestionServiceImpl();
        questionItemService = new QuestionItemServiceImpl();
    }
}

(8) Create a directory / WEB-INF/pages/store/questionItem for storing pages, and copy all pages from the module page \ questionItem in today's course materials to the newly created directory

(9) Add the entry of the topic option list page in the list.jsp page of the question module. Because the topic option is specific to a specific topic, add a button for configuring options in the operation of each list data

<button type="button" class="btn bg-olive btn-xs" onclick='location.href="${ctx}/store/questionItem?operation=list&questionId=${o.id}"'>configuration option</button>

At the same time, in the list.jsp page in the questionItem module, we need to delete some page elements, paging, new button and delete button, leaving only the refresh button

(10) Receive the id of the topic in the list method of the background servlet. The list we want to query should be the list of all options under the topic

private void list(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

    String questionId = request.getParameter("questionId");
    PageInfo all = questionItemService.findAll(questionId,1, 100);
    //Save the data to the specified location
    request.setAttribute("page",all);
    //Jump page
    request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp").forward(request,response);
}

(11) Modify the business layer interface method and add parameters. Note that it is the method with paging

/**
     * Paging query data
     * @param questionId id corresponding to the title
     * @param page Page number
     * @param size Total data displayed per page
     * @return
     */
PageInfo findAll(String questionId,int page, int size);

(12) Modify the corresponding method in the business layer implementation class

@Override
public PageInfo findAll(String questionId,int page, int size) {
    SqlSession sqlSession = null;
    try{
        //1. Get SqlSession
        sqlSession = MapperFactory.getSqlSession();
        //2. Get Dao
        QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class);
        //3. Call Dao layer operation
        PageHelper.startPage(page,size);
        List<QuestionItem> all = questionItemDao.findAll(questionId);
        PageInfo pageInfo = new PageInfo(all);
        return pageInfo;
    }catch (Exception e){
        throw new RuntimeException(e);
        //Log
    }finally {
        try {
            TransactionUtil.close(sqlSession);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

(13) Modify the persistence layer interface method findAll and add query parameters

/**
     * Query all options by topic id 
     * @param questionId
     * @return
     */
List<QuestionItem> findAll(String questionId);

(14) Modify dao mapping configuration file and add conditions

<!--Configure all queries with conditions-->
<select id="findAll" parameterType="java.lang.String" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from st_question_item
    where question_id = #{questionId,jdbcType=VARCHAR}
</select>

(15) For the original findAll method without any parameters in the business layer, we can remove and delete the parameter free findAll method in the interface and implementation class

(16) Start project test effect

5.2 add function production

(1) Remove some logic from the doGet method of the background servlet. The logical judgment of toAdd and the corresponding toAdd method need to be deleted, and then directly view the save method

(2) Finally, the save method needs to jump to the page. We let it directly call the list method, which is the last step to jump to the page

private void save(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    //The data is obtained and encapsulated into an object
    QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd");
    //Call the business layer interface save
    questionItemService.save(questionItem);
    //Jump back to page list
    list(request,response);
}

(3) Find the list.jsp page under the questionItem module, and add a hidden field in the < form id = "editform" > form to receive the ID of the topic

<input type="hidden" name="questionId" value="${questionId}">

At the same time, to ensure that this value can be obtained in the page, we need to store the value in the request field in the background list method jumping to the page, and modify the list method of the background servlet

private void list(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

    String questionId = request.getParameter("questionId");
    //When entering the list page, add the corresponding question id for the addition operation
    request.setAttribute("questionId",questionId);
    PageInfo all = questionItemService.findAll(questionId,1, 100);
    //Save the data to the specified location
    request.setAttribute("page",all);
    //Jump page
    request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp").forward(request,response);
}

(4) Start the project for testing

5.3 delete function creation

(1) to delete, the first thing to solve is to delete the completion of the backend page skipping problem. We need to modify the delete method of the background servlet and delete the list after the completion.

private void delete(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    //The data is obtained and encapsulated into an object
    QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class);
    //Call the business layer interface save
    questionItemService.delete(questionItem);
    //Jump back to page list
    list(request,response);
}

(2) The new problem is that after deletion, it jumps back to the list.jsp page, and other data is missing. The reason is that when the background servlet completes the deletion and calls the list method, it needs to obtain the id of the topic to query all the options under the topic. This place lacks the id of the topic, Therefore, the solution is to pass the topic id to the background when the page sends a deletion request, so we need to modify the js code for page deletion

<script type="text/javascript">
    function deleteById(id) {
    var questionId = '${questionId}';
    if(confirm("Are you sure you want to delete this record?")) {
        window.location.href="${ctx}/store/questionItem?operation=delete&questionId=${questionId}&id="+id;
    }
}
</script>

(3) Start the project and test it

5.4 modification function production

(1) Modify the toEdit method of the background servlet. After querying the data, the jump page still calls the list method to complete the jump

private void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //Query the data findById to modify
    String id = request.getParameter("id");
    QuestionItem questionItem = questionItemService.findById(id);
    //Load the data into the specified area for the page to obtain
    request.setAttribute("questionItem",questionItem);
    //Jump back to page list
    list(request,response);
}

(2) The problem is that after clicking Edit, jump to the page and all data cannot be displayed, including all previous option data. We need to solve the problem of displaying all previous option data first. The reason is very simple, or because the id of the problem is not passed to the background when clicking Edit, When jumping through the list method in the background, you cannot query the options under the topic without the id of the topic

Modify the Edit button on the questionItem/list.jsp page and add the parameter of topic id

<button type="button" class="btn bg-olive btn-xs" onclick='location.href="${ctx}/store/questionItem?operation=toEdit&questionId=${questionId}&id=${o.id}"'>edit</button>

(3) Then, to solve the problem that the edited data cannot be displayed after clicking Edit, you need to adjust the questionItem/list.jsp page form to add the display of data

<form id="editForm" action="${ctx}/store/questionItem?operation=saveOrUpdate" method="post">
    <input type="hidden" name="questionId" value="${questionId}">
    <input type="hidden" name="id" value="${questionItem.id}">
    <div class="row data-type" style="margin: 0px">

        <div class="col-md-2 title">Option content</div>
        <div class="col-md-4 data">
            <input type="text" class="form-control" placeholder="Option content" name="content" value="${questionItem.content}">
        </div>

        <div class="col-md-2 title">Option picture</div>
        <div class="col-md-4 data">
            <input type="file" class="form-control" placeholder="Please select" name="picture" >
        </div>

        <%--<div class="col-md-2 title">Is the correct answer</div>
                    <div class="col-md-4 data">
                        <select class="form-control" name="isRight">
                            <option value="">Please select</option>
                            <option value="1">right key</option>
                            <option value="0">Error options</option>
                        </select>
                    </div>--%>
        <div class="col-md-2 title">Is the correct answer</div>
        <div class="col-md-4 data">
            <select class="form-control" name="isRight">
                <option value="">Please select</option>
                <option value="1" ${questionItem.isRight eq "1" ? "selected" : ""}>right key</option>
                <option value="0" ${questionItem.isRight eq "0" ? "selected" : ""}>Error options</option>
            </select>
        </div>
    </div>
</form>

(4) After starting the test, a new problem is found. We want to submit the edited data, but the result turns into saving. What is the reason for the problem?

After analysis, it is found that the submission path of the form is always the saved path. How to solve it?

Pass the variable value of an operation type to the front end through the background. The front end uses the variable value in the action of the form. Through this variable, we can control whether to add or edit

Operate the variable value in the list and toEdit methods in the background

private void list2(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    String questionId = request.getParameter("questionId");
    //When entering the list page, add the corresponding question id for the addition operation
    request.setAttribute("questionId",questionId);
    //get data
    PageInfo all = questionItemService.findAll(questionId, 1, 100);
    //Save the data to the specified location
    request.setAttribute("page",all);

    if(request.getAttribute("operation") == null) {
        //Save the type of an operation and pass it to the front-end save
        request.setAttribute("operation", "save");
    }

    //Jump page
    request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp").forward(request,response);
}

private void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //Query the data findById to modify
    String id = request.getParameter("id");
    QuestionItem questionItem = questionItemService.findById(id);
    //Load the data into the specified area for the page to obtain
    request.setAttribute("questionItem",questionItem);

    //Save the type of an operation and pass it to the front-end save
    request.setAttribute("operation","edit");

    //Jump back to page list
    list(request,response);
}

Then you need to receive the value on the form action attribute of the page

<form id="editForm" action="${ctx}/store/questionItem?operation=${operation}" method="post">

(5) Start the project for testing

(6) After the test finds that the edited data is submitted for editing, the page jumps back to the page, and all the data on the page disappears again. Go back to the background servlet to check the edit method, and it is found that it is the problem of page Jump

private void edit(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    //The data is obtained and encapsulated into an object
    QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd");
    //Call the business layer interface save
    questionItemService.update(questionItem);
    //Jump back to page list
    list(request,response);
}

(7) After the problem of data display was solved, we found that the data was not really modified. Through analysis, we found that it was because the edited data was submitted for modification, but the id value of the problem option was not submitted. We need to receive the id value of the problem option in the form so that it can be submitted to the background during editing

<input type="hidden" name="id" value="${questionItem.id}">

(8) Start the project for testing

5.5 add modify function merge

(1) Back up questionItem/list.jsp, questionItem/list2.jsp

(2) Back up the background list and toedit methods, called List2 and toedit2 respectively, which are matched with the foreground list2.jsp,

(3) Encapsulate a saveOrUpdate method in the background servlet, and modify the doGet method at the same time

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String operation = request.getParameter("operation");
    if("list".equals(operation)){
        this.list(request,response);
    }else if("save".equals(operation)){
        this.save(request, response);
    }else if("toEdit".equals(operation)){
        this.toEdit(request,response);
    }else if("edit".equals(operation)){
        this.edit(request,response);
    }else if("delete".equals(operation)){
        this.delete(request,response);
    }else if("saveOrUpdate".equals(operation)){
        this.saveOrUpdate(request,response);
    }
}

private void saveOrUpdate(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    //The data is obtained and encapsulated into an object
    QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd");
    //If the page passes the id of the current data, it is a modified business; otherwise, it is an added business
    if(StringUtils.isNotBlank(questionItem.getId())){
        questionItemService.update(questionItem);
    }else {
        questionItemService.save(questionItem);
    }
    //Jump back to page list
    list(request,response);
}

(4) Modify the original list and toedit methods. There is no need to add the variables with operation ID before

private void list(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    String questionId = request.getParameter("questionId");
    //When entering the list page, add the corresponding question id for the addition operation
    request.setAttribute("questionId",questionId);
    //get data
    PageInfo all = questionItemService.findAll(questionId, 1, 100);
    //Save the data to the specified location
    request.setAttribute("page",all);

    //Jump page
    request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp").forward(request,response);
}

private void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //Query the data findById to modify
    String id = request.getParameter("id");
    QuestionItem questionItem = questionItemService.findById(id);
    //Load the data into the specified area for the page to obtain
    request.setAttribute("questionItem",questionItem);

    //Jump back to page list
    list(request,response);
}

(5) Modify the action attribute of the list.jsp page form

 <form id="editForm" action="${ctx}/store/questionItem?operation=saveOrUpdate" method="post">

(6) Start project test

5.6 delete function related problems and Solutions

After the title option function is completed, some functions of the title have problems, such as deleting the title and deleting the title data. What about the option data under the title? It has not been deleted at present,

Therefore, what we want to solve is: deleting the topic data is accompanied by deleting the option data under the topic

Solution

Solution 1: trigger

◆ note that the trigger is used to bind the business to the database, and the scheme shall be confirmed during system design

Solution 2: call the deletion function of the two modules respectively in the deletion operation of the business layer

◆ note: delete the primary user by id, and delete the secondary user by associated id

◆ pay attention to the order of deletion. Delete the slave first and then the master

Solution 3: stored procedure

◆ a complete set of data layer solutions without single function

Solution 4: rely on the cascade deletion function provided by the framework

Solution 5: regular maintenance / garbage data cleaning

Posted by AdamDowning on Sat, 04 Dec 2021 17:41:41 -0800