영보의 SystemOut.log

[Web] JSTL , CSS 이용하여 레시피 그리드 목록 출력-(1) 본문

Web

[Web] JSTL , CSS 이용하여 레시피 그리드 목록 출력-(1)

영보로그 2020. 10. 7. 17:43
반응형

 

www.10000recipe.com/

 

만개의레시피

 

www.10000recipe.com

만개의 레시피 사이트에서 데이터를 긁어와서 

JSTL과 CSS, XML, Java로 레시피 그리드를 만들어 보겠습니다.

MV 구조로 만든 프로그램 입니다.

 

 

 

 

사용한 라이브러리 입니다

MyBatis, xml등에 필요한 라이브러리입니다.

 

제가 한 환경설정 입니다.

 

 

 

 

# ChefVO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.sist.dao;
 
public class ChefVO {
    private String poster;
    private String chef;
    private String mem_cont1;
    private String mem_cont2;
    private String mem_cont3;
    private String mem_cont7;
    private int recipeCount;
    public String getPoster() {
        return poster;
    }
    public void setPoster(String poster) {
        this.poster = poster;
    }
    public String getChef() {
        return chef;
    }
    public void setChef(String chef) {
        this.chef = chef;
    }
    public String getMem_cont1() {
        return mem_cont1;
    }
    public void setMem_cont1(String mem_cont1) {
        this.mem_cont1 = mem_cont1;
    }
    public String getMem_cont2() {
        return mem_cont2;
    }
    public void setMem_cont2(String mem_cont2) {
        this.mem_cont2 = mem_cont2;
    }
    public String getMem_cont3() {
        return mem_cont3;
    }
    public void setMem_cont3(String mem_cont3) {
        this.mem_cont3 = mem_cont3;
    }
    public String getMem_cont7() {
        return mem_cont7;
    }
    public void setMem_cont7(String mem_cont7) {
        this.mem_cont7 = mem_cont7;
    }
    public int getRecipeCount() {
        return recipeCount;
    }
    public void setRecipeCount(int recipeCount) {
        this.recipeCount = recipeCount;
    }
}
cs

 

 

 

# RecipeVO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.sist.dao;
 
public class RecipeVO {
    private int no;
    private String title;
    private String poster;
    private String chef;
    private String link;
    public int getNo() {
        return no;
    }
    public void setNo(int no) {
        this.no = no;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getPoster() {
        return poster;
    }
    public void setPoster(String poster) {
        this.poster = poster;
    }
    public String getChef() {
        return chef;
    }
    public void setChef(String chef) {
        this.chef = chef;
    }
    public String getLink() {
        return link;
    }
    public void setLink(String link) {
        this.link = link;
    }
}
cs

 

 

 

# Config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
   "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <!-- 오라클을 연결하기 위한 환경설정 : 한개만 사용  -->
  <!-- properties 파일 읽기 -->
  <!-- MyBatis,Spring : 기본 디폴트 폴더가 src -->
  <properties resource="db.properties"/>
  <typeAliases>
    <!-- VO를 등록 -->
    <typeAlias type="com.sist.dao.RecipeVO" alias="RecipeVO"/>
    <typeAlias type="com.sist.dao.ChefVO" alias="ChefVO"/>
    <!-- 
                      오라클에서 가지고 오는 데이터를 받아서 저장 
            while(rs.next())
            {
                DataBoardVO vo=new DataBoardVO(); // 셋팅
                vo.setNo(rs.getInt(1));
                ==
                ==
                ==
            }
     -->
  </typeAliases>
  <!-- 오라클 연결하는 부분 : getConnection() -->
  <environments default="development"><!-- 개발 환경을 만든다 -->
    <environment id="development">
      <!-- Commit,Rollback => Transection -->
      <!-- 
                    트랜잭션 처리 방법
                    자동처리 : 일반적으로 많이 사용 => JDBC
                    수동처리 : 프로그래머가 처리 => MANAGED
                    
           COMMIT : 정상처리 => 저장을 요청
           ROLLABCK : SQL문장이 틀렸다 => 실행하지 않는다 : UNDO (ctrl+z)
       -->
       <transactionManager type="JDBC"/>
      <!-- 오라클 정보를 모아서 MyBatis 라이브러리에 전송 : DataSource -->
       <dataSource type="POOLED">
          <!-- 
               UNPOOLED : 요청(SQL문장 실행)할때 오라클 연결 , 결과값을 가지고 오면 오라클 연결 해제
                          => 연결하는 시간이 많이 소모(연결이 지연될 수 도 있다)
               POOLED : DBCP (미리 Connection을 연결하고 요청시마다 연결된 Connection을 넘겨준다
                              사용후에는 반환=> 다시 재사용이 가능)
                          => 연결하는 소모되지 않는다 
                          => Connection의 생성 갯수를 제어 할 수 있다
                          => 일반적으로 웹프로그램에서는 기본으로 사용
           -->
           <!-- 오라클 연결을 위한 기본정보를 마이바티스로 전송 -->
           <!-- 
                    db.properties
                    driver=oracle.jdbc.driver.OracleDriver
                    url=jdbc:oracle:thin:@211.238.142.181:1521:XE
                    username=hr
                    password=happy
            -->
           <property name="driver" value="${driver}"/>
           <property name="url" value="${url}"/>
           <property name="username" value="${username}"/>
           <property name="password" value="${password}"/>
           <!-- 
                 public class PooledDataSource
                 {
                     private String driver;
                     private String url;
                     private String username;
                     private String password;
                 }
                 
                 public class MyBatisDAO
                 {
                      private DataSource dataSource;
                      public MyBatisDAO()
                      {
                          Class.forName(dataSource.getDriver()); ==> 필요한 데이터 => XML로 설정 
                      }
                      public void getConnection()
                      {
                         conn=DriverManager.getConnection(dataSource.getUrl(),
                             dataSource.getUsername(),dataSource.getPassword())
                      }
                 }
            -->
       </dataSource>
    </environment>
  </environments>
  <!-- SQL문장을 전송 : SQL문장 어디 있는지 확인 : mapper를 등록  -->
  <!-- XML은 문서 저장 : 저장내용이 많아지면 파싱(XML저장되어 있는 데이터를 읽어 간다) 속도가 저하된다:분산  -->
  <!-- XML만 가지고 코딩하는 프레임워크 : XML이 길어진다=>속도의 문제 (스트럿츠) : 스프링 -->
  <!-- 
      MyBatis => XML없이도 사용이 가능 
                ===== Annotation  @
   -->
  <mappers>
    <mapper resource="com/sist/dao/recipe-mapper.xml"/>
    <!-- MovieVO , MovieDAO  -->
  </mappers>
</configuration>
cs

 

 

# db.properties

1
2
3
4
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@211.238.142.195:1521:XE
username=hr
password=happy
cs

 

 

 

# RecipeDAO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package com.sist.dao;
import java.io.*;
import java.util.*;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class RecipeDAO {
    // XML을 파싱
    private static SqlSessionFactory ssf;
    static {
        try {
            // XML을 읽기 시작
            Reader reader=Resources.getResourceAsReader("Config.xml");
            ssf=new SqlSessionFactoryBuilder().build(reader);
        }catch(Exception ex) {
            ex.printStackTrace();
        }
    }
    // 기능 처리 ==> jstl + el ==> 망고플레이트 ==> 지도
    // 1. 레시피 목록
    public static List<RecipeVO> recipeListData(Map map){
        List<RecipeVO> list=new ArrayList<RecipeVO>();
        SqlSession session=null;
        try {
            // 연결
            session=ssf.openSession();
            // 데이터 처리
            list=session.selectList("recipeListData",map);
        }catch(Exception ex) {
            ex.printStackTrace();
        }
        finally {
            if(session!=null)
                session.close();
        }
        return list;
    }
    // 총 페이지 구하기
    public static int recipeTotalPage() {
        int total=0;
        SqlSession session=null;
        try {
            // 연결
            session=ssf.openSession();
            // 데이터 처리
            total=session.selectOne("recipeTotalPage");
        }catch(Exception ex) {
            ex.printStackTrace();
        }finally {
            if(session!=null)
                session.close();
        }
        return total;
    }
    // 2. chef 목록
    public static List<ChefVO> chefListData(Map map){
        List<ChefVO> list=new ArrayList<ChefVO>();
        SqlSession session=null;
        try {
            // 연결
            session=ssf.openSession();
            // 데이터 처리
            list=session.selectList("chefListData",map);
        }catch(Exception ex) {
            ex.printStackTrace();
        }
        finally {
            if(session!=null)
                session.close();
        }
        return list;
    }
    // 총 페이지 구하기
    public static int chefTotalPage() {
        int total=0;
        SqlSession session=null;
        try {
            // 연결
            session=ssf.openSession();
            // 데이터 처리
            total=session.selectOne("chefTotalPage");
        }catch(Exception ex) {
            ex.printStackTrace();
        }finally {
            if(session!=null)
                session.close();
        }
        return total;
    }
    // 3. chef => 레시피
    public static List<RecipeVO> chefRecipeData(String chef){
        List<RecipeVO> list=new ArrayList<RecipeVO>();
        SqlSession session=null;
        try {
            // 연결
            session=ssf.openSession();
            // 데이터 처리
            list=session.selectList("chefRecipeData",chef);
        }catch(Exception ex) {
            ex.printStackTrace();
        }
        finally {
            if(session!=null)
                session.close();
        }
        return list;
    }
    public static List<ChefVO> chefRecipeCount(){
        List<ChefVO> list=new ArrayList<ChefVO>();
        SqlSession session=null;
        try {
            // 연결
            session=ssf.openSession();
            // 데이터 처리
            list=session.selectList("chefRecipeCount");
            for(ChefVO vo:list) {
                String s=vo.getMem_cont1().replace(","" ");
                vo.setRecipeCount(Integer.parseInt(s));
            }
        }catch(Exception ex) {
            ex.printStackTrace();
        }
        finally {
            if(session!=null)
                session.close();
        }
        return list;
    }
}
cs

 

 

 

# RecipeModel.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package com.sist.model;
import com.sist.dao.*;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
public class RecipeModel {
    public void recipeListData(HttpServletRequest request) {
        // request => 사용자의 요청 정보, 필요한 데이터를 첨부해서 사용(setAttribute())
        // 사용자가 요청한 페이지를 받는다
        String page=request.getParameter("page");
        if(page==null)
            page="1";
        // 데이터 읽기
        int curpage=Integer.parseInt(page); // 현재 보고 있는 페이지
        Map map=new HashMap();
        int rowSize=20;
        int start=(rowSize*curpage)-(rowSize-1);
        int end=rowSize*curpage;
        
        // map에 묶어서 전송 ==> mybatis가 읽어서 처리
        map.put("start",start);
        map.put("end",end);
        List<RecipeVO> list=RecipeDAO.recipeListData(map);
        for(RecipeVO vo:list){
            String str=vo.getTitle();
            if(str.length()>15) {
                str=str.substring(0,15);
                str+="...";
            }
            vo.setTitle(str);
        }
        // 총페이지
        int totalpage=RecipeDAO.recipeTotalPage();
        
        // JSP로 받은 결과값을 전송
        request.setAttribute("list", list);
        request.setAttribute("curpage", curpage);
        request.setAttribute("totalpage", totalpage);
    }
    
    public void chefListData(HttpServletRequest request) {
        // 사용자 요청정보 받기 => page
        String page=request.getParameter("page");
        if(page==null)
            page="1";
        // 현재 페이지
        int curpage=Integer.parseInt(page);
        // 현재 페이지 출력할 데이터 읽기
        Map map=new HashMap();
        int rowSize=50;
        int start=(rowSize*curpage)-(rowSize-1);
        int end=rowSize*curpage;
        
        map.put("start", start);
        map.put("end", end);
        List<ChefVO> list=RecipeDAO.chefListData(map); //시작위치, 마지막 위치
        // 총 페이지
        int totalpage=RecipeDAO.chefTotalPage();
        // curpage, totalpage, list => JSP
        
        request.setAttribute("list", list);
        request.setAttribute("curpage", curpage);
        request.setAttribute("totalpage", totalpage);
        
        List<ChefVO> cList=RecipeDAO.chefRecipeCount();
        request.setAttribute("cList", cList);
    }
    // chef => 레시피 목록 출력
    public void chefRecipeData(HttpServletRequest request) {
        // 사용자가 요청한 => chef명을 읽어 온다
        String chef_name=request.getParameter("chef_name");
        List<RecipeVO> list=RecipeDAO.chefRecipeData(chef_name);
        // JSP로 전송 => list에 있는 내용만 출력
        request.setAttribute("list", list);
    }
}
cs

 

 

 

# recipe-mapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sist.dao.recipe-mapper">
   <!-- 레시피를 나눠서 처리 : 인라인 뷰  -->
   <select id="recipeListData" resultType="RecipeVO" parameterType="hashmap">
       SELECT no, title, chef, poster, num
       FROM (SELECT no,title,chef,poster,rownum as num
       FROM (SELECT no, title,chef,poster
       FROM recipe ORDER BY no ASC))
       WHERE num BETWEEN #{start} AND #{end}
   </select>
   <select id="recipeTotalPage" resultType="int">
       SELECT CEIL(COUNT(*)/20.0) FROM recipe
   </select>
   <!-- 검색 -->
   <!-- chef 목록 출력 -->
   <select id="chefListData" resultType="ChefVO" parameterType="hashmap">
       SELECT chef,poster,mem_cont1,mem_cont2,mem_cont3,mem_cont7,num
       FROM (SELECT chef,poster,mem_cont1,mem_cont2,mem_cont3,mem_cont7,rownum as num
       FROM (SELECT chef,poster,mem_cont1,mem_cont2,mem_cont3,mem_cont7
       FROM chef))
       WHERE num BETWEEN #{start} AND #{end}
   </select>
   <!-- chef 총 페이지 -->
   <select id="chefTotalPage" resultType="int">
    SELECT CEIL(COUNT(*)/50.0) FROM chef
   </select>
   
   <!-- chef => 레시피찾기 -->
   <select id="chefRecipeData" resultType="RecipeVO" parameterType="string">
       SELECT no, title, poster, chef, rownum
       FROM recipe
       WHERE chef=#{chef} AND rownum&lt;=32
   </select>
   
   <select id="chefRecipeCount" resultType="ChefVO">
    SELECT chef,mem_cont1,rownum
    FROM chef
    WHERE rownum&lt;=10
   </select>
</mapper>
cs

 

 

 

 

# 출력 화면

반응형