java中的三层结构

158 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情

摘要

在使用java开发的过程中,使用的开发模式是mvc模式那么这个模式在整个开发领域都是非常的有名的,不管是php还是python都是使用这样的开发模式。那么在java中是如何实现这样的模式的呢。

Dao层

会有接口包,和实现包。

接口包的代码如下:

 public List<Person> findByCourseList()

实现包的代码如下:


		@Override
    public List<Person> findByCourseList() {
        return null;
    }

查询操作

    @Override
    public List<Course> findByCourseList() {

        //链接数据库及查询操作
        QueryRunner queryRunner=new QueryRunner(DruidUtils.getDataSource());

        String sql="select id,course_name,sort_num,price,`status` \n" +
                "FROM course where is_del=?";

        try {
            /*
            * query方法,第一个参数是sql语句,第二个参数是sql语句查询出的结果集,以什么样的格式进行保存。第三个参数是 sql语句需要的参数。
            * */
            List<Course> courseList = queryRunner.query(sql, new BeanListHandler<Course>(Course.class), 0);
            return courseList;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return null;
        }


    }

条件查询

链接数据库的相关操作

service层

service 主要是用来获取dao的操作。最终还是返回数据。

    //获取课程列表信息
    @Override
    public List<Course> findByCourseList() {

      CourseDao courseDao =   new CourseDaoImpl();
      List<Course>  courseList= courseDao.findByCourseList();

        return courseList;
    }

servlet层

这一层就是输入接口的层。

存在一个实体类里边属性部分作为接口数据传输给前端。

public class CourseServlet extends BaseServlet {
    

    public void findByCourseList(HttpServletRequest request, HttpServletResponse response){

        CourseService courseService = new  CourseServiceImpl();
        List<Course> courseList=courseService.findByCourseList();

        //过滤器,过滤掉相关的属性或者是字段,其实是类的属性
        SimplePropertyPreFilter spFilter=new SimplePropertyPreFilter(Course.class,"id",
                "course_name","price","sort_name","status");


        //把数据输出给前端
        //返回给前端前,先解析成字符串类型
        String strCourseList=JSON.toJSONString(courseList,spFilter);

        try {
            response.getWriter().print(strCourseList);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

中文乱码处理问题

是一个过滤器处理的,尤其是修饰器 已经对所有根目录下的路径做了相关的处理。

package com.hmg.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//Filter 解决乱码
@WebFilter("/*")
public class EncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request= (HttpServletRequest) servletRequest;
        HttpServletResponse response= (HttpServletResponse)servletResponse;

        //解决请求乱码
        request.setCharacterEncoding("UTF-8");

        //解决响应乱码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        //放行
        filterChain.doFilter(request,response);
    }

    @Override
    public void destroy() {

    }


}

日期格式化对象

package com.hmg.utils;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateUtils {

    /**
     * 获取日期对象 格式化后的字符串
     * @return
     */
    public static String getDateFormart(){

        Date date = new Date();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String format = sdf.format(date);

        return format;
    }
}

UUID生成的代码

package com.hmg.utils;

import java.util.UUID;

/**
 * UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。
 *
 * UUID由以下几部分的组合:
 *  1.当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
 *  2.时钟序列。
 *  3.全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。
 *
 */
public class UUIDUtils {

    //获取唯一ID的 方法
    public static String getUUID() {

        return UUID.randomUUID().toString().replace("-", "");
    }

}

数据库druid链接方式

package com.hmg.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DruidUtils {

    //1.定义成员变量
    public static DataSource dataSource;

    //2.静态代码块
    static{
        try {
            //3.创建属性集对象
            Properties p = new Properties();

            //4.加载配置文件 Druid 连接池不能够主动加载配置文件 ,需要指定文件
            InputStream inputStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");

            //5. 使用Properties对象的 load方法 从字节流中读取配置信息
            p.load(inputStream);

            //6. 通过工厂类获取连接池对象
            dataSource = DruidDataSourceFactory.createDataSource(p);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接的方法
    public static Connection getConnection(){

        try {

            return dataSource.getConnection();

        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    //获取Druid连接池对象的方法
    public static DataSource getDataSource(){
        return dataSource;
    }


    //释放资源
    public static void close(Connection con, Statement statement){

        if(con != null && statement != null){
            try {
                statement.close();
                //归还连接
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    public static void close(Connection con, Statement statement, ResultSet resultSet){

        if(con != null && statement != null && resultSet != null){
            try {
                resultSet.close();
                statement.close();
                //归还连接
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

}

文件上传工具类的实现

代码如下:

package com.hmg.servlet;

import com.hmg.utils.UUIDUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@WebServlet("/upload")
public class FileUploadServlet extends HttpServlet {

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

        //1.创建磁盘文件工厂对象
        DiskFileItemFactory diskFileItemFactory=new DiskFileItemFactory();

        //2.创建文件核心类
        ServletFileUpload upload=new ServletFileUpload(diskFileItemFactory);
        //3.解析request  获取表单集合
        //3.1设置编码
        upload.setHeaderEncoding("utf-8");
        //3.2 判断是否是文件上传类型
        boolean multipartContent = upload.isMultipartContent(req);
        //3.3 存在表示是文件上传列表
        if(multipartContent){

            //获取表单集合
            try {

                List<FileItem> list= upload.parseRequest(req);

                if(list!=null){//表示是有表单数据

                    for (FileItem fileItem:list){

                        boolean formField = fileItem.isFormField();

                        if(formField){//表示为普通表单项
                            String fieldName = fileItem.getFieldName();
                            String fieldValue = fileItem.getString("utf-8");//用什么样的编码获取值
                            System.out.println(fieldName+"="+fieldValue);

                        }else{//表示为非普通表单项

                            //获取文件名 并且拼接新的文件名
                            String name = fileItem.getName();
                            String newName= UUIDUtils.getUUID()+"_"+name;
                            //输入流和输出流
                            InputStream in=fileItem.getInputStream();
                            //获取项目在当前服务器上的根目录地址,上传图片保存在项目文件下
                            String realPath = this.getServletContext().getRealPath("/");
                            //输出流
                            FileOutputStream fileOutputStream=new FileOutputStream(realPath+"/"+newName);
                            //将输入流输出到输出流里边
                            IOUtils.copy(in,fileOutputStream);
                        }
                    }
                }


            } catch (FileUploadException e) {
                e.printStackTrace();
            }


        }else{

        }
        //4.遍历 表单集合
        //5.分清楚是普通表单还是文件上传表单






    }

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

1对多的关系

这种关系是在实体类进行实现的。

课程表对章节表是 1对多的关系,所以在课程表里需要添加如下属性:

  //课程表对章节表是 1对多的关系 所以在课程表里是
  List<Course_Section> courseList=new ArrayList<>();

Course_Section:表示的是章节的实体类。

在章节表里是:

  //章节表里边需要引入课程表
  private Course course;

章节表 对 课时表 又是 1对多的关系,所以需要在章节表里边定义集合属性:

  //章节表对应课时表是 1多多的关系
  List<Course_Lesson> course_lessons=new ArrayList<>();

课时表 对 章节表是如下:

  //课时表  对  章节表
  private Course_Section course_section;

1对多的关系在代码里边展示

    @Override
    public List<Course_Section> findSectionAndLessonByCourseId(int courseId) {

        QueryRunner queryRunner=new QueryRunner(DruidUtils.getDataSource());

        String sql="SELECT\n" +
                "id,\n" +
                "course_id,\n" +
                "description,\n" +
                "section_name,\n" +
                "order_num,\n" +
                "`status`\n" +
                "from\n" +
                "course_section WHERE course_id=?";

        try {
            List<Course_Section> query
                    = queryRunner.query(sql, new BeanListHandler<Course_Section>(Course_Section.class), courseId);

            for (Course_Section course_section:query){
                List<Course_Lesson> course_lessonList= findLessonBySectionId(course_section.getId());
                //将课时数据封装在我们的章节数据中
                course_section.setCourse_lessons(course_lessonList);
            }

            return query;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return null;
        }


    }

    @Override
    public List<Course_Lesson> findLessonBySectionId(int sectionId) {

        QueryRunner queryRunner=new QueryRunner(DruidUtils.getDataSource());

        String sql="select\n" +
                "id,\n" +
                "course_id,\n" +
                "section_id,\n" +
                "theme,\n" +
                "duration,\n" +
                "is_free,\n" +
                "order_num,\n" +
                "`status`\n" +
                "from\n" +
                "course_lesson  WHERE section_id=?";


        try {
            List<Course_Lesson> query
                    = queryRunner.query(sql, new BeanListHandler<Course_Lesson>(Course_Lesson.class), sectionId);
            return query;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return null;
        }


    }
    
    

总结:

不仅仅只是java的mvc的模式,本篇文章还说明了mysql的一些相关的使用,包括1对1,1对多,多对多的关系。因为我们在使用mvc中的model层的时候,就会涉及到表之间的关系。