Search

PageHelper

PageHelper

PageHelper๋Š” MyBatis๋ฅผ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ํŽ˜์ด์ง• ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค.
์ด ๋„๊ตฌ๋Š” ๋ณต์žกํ•œ ํŽ˜์ด์ง• ๋กœ์ง์„ ๋‹จ์ˆœํ™”ํ•˜์—ฌ ๊ฐœ๋ฐœ์ž์˜ ์ƒ์‚ฐ์„ฑ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. PageHelper๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹œ์Šคํ…œ๊ณผ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค.

๋ฏธ๋ฆฌ๋ณด๊ธฐ

๊ฐœ์š”

โ€ข
PageHelper Gradle ์˜์กด์„ฑ
โ€ข
PageHelper Maven ์˜์กด์„ฑ
โ€ข
application.properties ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์ •
โ€ข
์˜ˆ์‹œ ์ฝ”๋“œ
โ—ฆ
board ํ…Œ์ด๋ธ” ์ƒ์„ฑ
โ—ฆ
Board ๋„๋ฉ”์ธ ๊ฐ์ฒด ์ƒ์„ฑ
โ—ฆ
BoardMapper.xml
โ—ฆ
BoardMapper.java
โ—ฆ
BoardService.java
โ—ฆ
BoardServiceImpl.java
โ—ฆ
BoardController.java
โ—ฆ
board/list.html

PageHelper Gradle ์˜์กด์„ฑ

build.gradle

implementation 'com.github.pagehelper:pagehelper-spring-boot-starter:2.1.0'
Java
๋ณต์‚ฌ
์œ„์˜ ์ฝ”๋“œ๋ฅผ build.gradle ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•˜์—ฌ PageHelper๋ฅผ ํ”„๋กœ์ ํŠธ์— ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„์ „ ๋ฒˆํ˜ธ๋Š” ์ตœ์‹  ๋ฒ„์ „์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ํ•ญ์ƒ ์ตœ์‹  ๋ฒ„์ „์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

PageHelper Maven ์˜์กด์„ฑ

pom.xml

<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency>
XML
๋ณต์‚ฌ

application.properties ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์ •

application.properties

# PageHelper ์„ค์ • pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql
Markdown
๋ณต์‚ฌ
์„ค์ • ํ‚ค
์„ค๋ช…
pagehelper.helperDialect=mysql
PageHelper๊ฐ€ ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” MySQL์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. - mysql, oracle, postgresql, ๋“ฑ
pagehelper.reasonable=true
ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ์™€ ํŽ˜์ด์ง€ ํฌ๊ธฐ์— ๋Œ€ํ•ด ํ•ฉ๋ฆฌ์ ์ธ ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
pagehelper.supportMethodsArguments=true
๋ฉ”์„œ๋“œ๋กœ ์ „๋‹ฌ๋œ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ์™€ ํŽ˜์ด์ง€ ํฌ๊ธฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
pagehelper.params=count=countSql
ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ฟผ๋ฆฌ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ์ด ๋ ˆ์ฝ”๋“œ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” SQL ์ฟผ๋ฆฌ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
1.
pagehelper.helperDialect=mysql:
โ€ข
PageHelper๊ฐ€ ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐฉ์–ธ(dialect)์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” MySQL์„ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. PageHelper๋Š” ์ด ์„ค์ •์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋งž๋Š” ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
โ€ข
์ฃผ์š” ์˜ต์…˜ ๊ฐ’
๊ฐ’
์„ค๋ช…
mysql
MySQL, MariaDB, Drizzle์šฉ
mariadb
MariaDB ์ „์šฉ
oracle
Oracle Database์šฉ
oracle9i
Oracle 9i ๋ฐ ์ด์ „ ๋ฒ„์ „์šฉ
sqlserver
SQL Server 2012 ์ด์ƒ
sqlserver2012
SQL Server 2012 ์ด์ƒ(ํŠนํ™” SQL)
db2
IBM DB2์šฉ
h2
H2 Database์šฉ
postgresql
PostgreSQL์šฉ
sqlite
SQLite์šฉ
informix
Informix์šฉ
clickhouse
ClickHouse์šฉ
hsqldb
HSQLDB(HyperSQL Database)์šฉ
phoenix
Apache Phoenix์šฉ
sybase
Sybase์šฉ
derby
Apache Derby์šฉ
dm
DM(Database Management)์šฉ
xcloud
XCloud์šฉ
2.
pagehelper.reasonable=true:
โ€ข
์ด ์„ค์ •์ดย true๋กœ ์„ค์ •๋˜๋ฉด, ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ์™€ ํŽ˜์ด์ง€ ํฌ๊ธฐ์— ๋Œ€ํ•ด ํ•ฉ๋ฆฌ์ ์ธ ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ๊ฐ€ 0 ์ดํ•˜์ด๊ฑฐ๋‚˜ ๋„ˆ๋ฌด ํฐ ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ 1๋กœ ์„ค์ •๋˜๊ณ , ํŽ˜์ด์ง€ ํฌ๊ธฐ๊ฐ€ 0 ์ดํ•˜์ด๊ฑฐ๋‚˜ ๋„ˆ๋ฌด ํฐ ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
3.
pagehelper.supportMethodsArguments=true:
โ€ข
์ด ์„ค์ •์ดย true๋กœ ์„ค์ •๋˜๋ฉด, PageHelper๋Š” ๋ฉ”์„œ๋“œ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ์™€ ํŽ˜์ด์ง€ ํฌ๊ธฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์„œ๋“œ์—์„œ ์ง์ ‘ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ์™€ ํŽ˜์ด์ง€ ํฌ๊ธฐ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
4.
pagehelper.params=count=countSql:
โ€ข
์ด ์„ค์ •์€ ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ฟผ๋ฆฌ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š”ย countย ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผย countSql๋กœ ์„ค์ •ํ•˜์—ฌ, PageHelper๊ฐ€ ์ด ๋ ˆ์ฝ”๋“œ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ์‚ฌ์šฉํ•  SQL ์ฟผ๋ฆฌ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ

โ€ข
board ํ…Œ์ด๋ธ” ์ƒ์„ฑ
โ€ข
Board ๋„๋ฉ”์ธ ๊ฐ์ฒด ์ƒ์„ฑ
โ€ข
BoardMapper.xml
โ€ข
BoardMapper.java
โ€ข
BoardService.java
โ€ข
BoardServiceImpl.java
โ€ข
BoardController.java
โ€ข
board/list.html

board ํ…Œ์ด๋ธ” ์ƒ์„ฑ

DROP TABLE IF EXISTS `board`; CREATE TABLE `board` ( `no` int NOT NULL AUTO_INCREMENT, `id` varchar(255) NOT NULL, `title` varchar(100) NOT NULL, `writer` varchar(100) NOT NULL, `content` text, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`no`) ) COMMENT='๊ฒŒ์‹œํŒ';
SQL
๋ณต์‚ฌ

Board ๋„๋ฉ”์ธ ๊ฐ์ฒด ์ƒ์„ฑ

/** * Board * - ๊ฒŒ์‹œ๊ธ€ ์ •๋ณด */ @Data public class Board { private int no; private String id; private String title; private String writer; private String content; private Date createdAt; private Date updatedAt; }
Java
๋ณต์‚ฌ

BoardMapper.xml

<?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"> <!-- namespace="๋งคํผ ์ธํ„ฐํŽ˜์ด์Šค ๊ฒฝ๋กœ" --> <mapper namespace="com.aloha.pagehelper.mapper.BoardMapper"> <!-- ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก --> <!-- <ํƒœ๊ทธ id="๋ฉ”์†Œ๋“œ๋ช…"></ํƒœ๊ทธ> --> <!-- <select id="๋ฉ”์†Œ๋“œ๋ช…" resultType="ํŒจํ‚ค์ง€๋ช….๊ฐ์ฒด๋ช…" ></select> resultType : ์กฐํšŒ ๊ฒฐ๊ณผ๋ฅผ ๋งคํ•‘ํ•  ๊ฐ์ฒด ์ •๋ณด --> <!-- <select id="list" resultType="com.aloha.pagehelper.domain.Board"> --> <select id="list" resultType="Board"> SELECT * FROM board ORDER BY created_at DESC </select> <!-- ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ --> <!-- SQL ์— ์ง€์ •ํ•  ํŒŒ๋ผ๋ฏธํ„ฐ : #{๋ณ€์ˆ˜๋ช…} * ๋„˜์–ด์˜ค๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 1๊ฐœ์ด๋ฉด, ๋ณ€์ˆ˜๋ช…์ด ์ผ์น˜ํ•˜์ง€ ์•Š์•„๋„ ๋งคํ•‘ * ๊ฐ์ฒด โžก ๊ฐ์ฒด์˜ ๋ณ€์ˆ˜๋ช…๊ณผ ์ผ์น˜ํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ๋ช…์œผ๋กœ ์ž‘์„ฑ --> <select id="select" resultType="Board"> SELECT * FROM board WHERE no = #{no} </select> <!-- ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก --> <insert id="insert"> INSERT INTO board( title, writer, content ) VALUES ( #{title}, #{writer}, #{content} ) </insert> <!-- ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • --> <update id="update"> UPDATE board SET title = #{title} ,writer = #{writer} ,content = #{content} WHERE no = #{no} </update> <!-- ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ --> <delete id="delete"> DELETE FROM board WHERE no = #{no} </delete> </mapper>
XML
๋ณต์‚ฌ

BoardMapper.java

@Mapper public interface BoardMapper { // ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก public List<Board> list() throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ public Board select(int no) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก public int insert(Board board) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • public int update(Board board) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ public int delete(int no) throws Exception; }
Java
๋ณต์‚ฌ

BoardService.java

public interface BoardService { // โญ ๊ฒŒ์‹œ๊ธ€ ํŽ˜์ด์ง• ๋ชฉ๋ก public PageInfo<Board> list(int page, int size) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก public List<Board> list() throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ public Board select(int no) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก public int insert(Board board) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • public int update(Board board) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ public int delete(int no) throws Exception; }
Java
๋ณต์‚ฌ

BoardServiceImpl.java

@Service // ์„œ๋น„์Šค ์—ญํ• ์˜ ์Šคํ”„๋ง ๋นˆ public class BoardServiceImpl implements BoardService { @Autowired private BoardMapper boardMapper; /** * โญ ๊ฒŒ์‹œ๊ธ€ ํŽ˜์ด์ง• ๋ชฉ๋ก ์กฐํšŒ */ @Override public PageInfo<Board> list(int page, int size) throws Exception { // โญ PageHelper.startPage(ํ˜„์žฌ ํŽ˜์ด์ง€, ํŽ˜์ด์ง€๋‹น ๊ฒŒ์‹œ๊ธ€ ์ˆ˜); PageHelper.startPage(page, size); List<Board> boardList = boardMapper.list(); // โญ PageInfo<Board>( ๋ฆฌ์ŠคํŠธ, ๋…ธ์ถœ ํŽ˜์ด์ง€ ๊ฐœ์ˆ˜ ); PageInfo<Board> pageInfo = new PageInfo<Board>(boardList, 10); return pageInfo; } /** * ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ */ @Override public List<Board> list() throws Exception { // TODO : boardMapper ๋กœ list() ํ˜ธ์ถœ /* * โžก List<Board> boardList ๋กœ ๋ฐ›์•„์˜ด * โžก return boardList */ List<Board> boardList = boardMapper.list(); return boardList; } /** * ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ * - no ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๊ฒŒ์‹œ๊ธ€ ๋ฒˆํ˜ธ๋ฅผ ์ „๋‹ฌ๋ฐ›์•„์„œ * ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กฐํšŒ ์š”์ฒญ */ @Override public Board select(int no) throws Exception { // TODO : boardMapper ๋กœ select(no) ํ˜ธ์ถœ /* * โžก Board board ๋กœ ๋ฐ›์•„์˜ด * โžก return board */ Board board = boardMapper.select(no); return board; } /** * ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก */ @Override public int insert(Board board) throws Exception { // TODO : boardMapper ๋กœ insert(Board) ํ˜ธ์ถœ /* * โžก int result ๋กœ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ–‰(๊ฐœ์ˆ˜) ๋ฐ›์•„์˜ด * โžก return result */ int result = boardMapper.insert(board); return result; } /** * ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • */ @Override public int update(Board board) throws Exception { // TODO : boardMapper ๋กœ update(Board) ํ˜ธ์ถœ /* * โžก int result ๋กœ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ–‰(๊ฐœ์ˆ˜) ๋ฐ›์•„์˜ด * โžก return result */ int result = boardMapper.update(board); return result; } /** * ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ */ @Override public int delete(int no) throws Exception { // TODO : boardMapper ๋กœ delete(no) ํ˜ธ์ถœ /* * โžก int result ๋กœ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ–‰(๊ฐœ์ˆ˜) ๋ฐ›์•„์˜ด * โžก return result */ int result = boardMapper.delete(no); return result; } }
Java
๋ณต์‚ฌ

BoardController.java

/** * /board ๊ฒฝ๋กœ๋กœ ์š”์ฒญ ์™”์„ ๋•Œ ์ฒ˜๋ฆฌ * [GET] - /board/list : ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ํ™”๋ฉด * [GET] - /board/read : ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ ํ™”๋ฉด * [GET] - /board/insert : ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ํ™”๋ฉด * [POST] - /board/insert : ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ์ฒ˜๋ฆฌ * [GET] - /board/update : ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ํ™”๋ฉด * [POST] - /board/update : ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ์ฒ˜๋ฆฌ * [POST] - /board/delete : ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ ์ฒ˜๋ฆฌ */ @Slf4j // ๋กœ๊ทธ ์–ด๋…ธํ…Œ์ด์…˜ @Controller // ์ปจํŠธ๋กค๋Ÿฌ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก @RequestMapping("/board") // ํด๋ ˆ์Šค ๋ ˆ๋ฒจ ์š”์ฒญ ๊ฒฝ๋กœ ๋งคํ•‘ // - /board/~ ๊ฒฝ๋กœ์˜ ์š”์ฒญ์€ ์ด ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ฒ˜๋ฆฌ public class BoardController { // โญ๋ฐ์ดํ„ฐ ์š”์ฒญ๊ณผ ํ™”๋ฉด ์ถœ๋ ฅ // Controller --> Service (๋ฐ์ดํ„ฐ ์š”์ฒญ) // Controller <-- Service (๋ฐ์ดํ„ฐ ์ „๋‹ฌ) // Controller --> Model (๋ชจ๋ธ ๋“ฑ๋ก) // View <-- Model (๋ฐ์ดํ„ฐ ์ถœ๋ ฅ) @Autowired // ์˜์กด์„ฑ ์ž๋™ ์ฃผ์ž… private BoardService boardService; // @Service๋ฅผ --Impl ์— ๋“ฑ๋ก /** * ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ ํ™”๋ฉด * @return * @throws Exception */ @GetMapping("/list") public String list(Model model ,@RequestParam(name = "page", required = false, defaultValue = "1") Integer page ,@RequestParam(name = "size", required = false, defaultValue = "10") Integer size) throws Exception { // ๋ฐ์ดํ„ฐ ์š”์ฒญ PageInfo<Board> pageInfo = boardService.list(page, size); Pagination pagination = new Pagination(); pagination.setPage(page); pagination.setSize(size); pagination.setTotal( pageInfo.getTotal() ); // ๋ชจ๋ธ ๋“ฑ๋ก model.addAttribute("pageInfo", pageInfo); model.addAttribute("pagination", pagination); // ๋ทฐ ํŽ˜์ด์ง€ ์ง€์ • return "/board/list"; // resources/templates/board/list.html } /** * ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ ํ™”๋ฉด * - /board/read?no=๐Ÿ’Ž * @param no * @return * @throws Exception */ // @RequestParam("ํŒŒ๋ผ๋ฏธํ„ฐ๋ช…") // - ์Šคํ”„๋ง ๋ถ€ํŠธ 3.2๋ฒ„์ „ ์ดํ•˜, ์ƒ๋žตํ•ด๋„ ์ž๋™ ๋งคํ•‘๋œ๋‹ค. // - ์Šคํ”„๋ง ๋ถ€ํŠธ 3.2๋ฒ„์ „ ์ด์ƒ, ํ•„์ˆ˜๋กœ ๋ช…์‹œํ•ด์•ผ ๋งคํ•‘๋œ๋‹ค. @GetMapping("/read") public String read(@RequestParam("no") int no, Model model) throws Exception { // ๋ฐ์ดํ„ฐ ์š”์ฒญ Board board = boardService.select(no); // ๋ชจ๋ธ ๋“ฑ๋ก model.addAttribute("board", board); // ๋ทฐํŽ˜์ด์ง€ ์ง€์ • return "/board/read"; } /** * ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ํ™”๋ฉด * @return */ @GetMapping("/insert") public String insert() { return "/board/insert"; } /** * ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ์ฒ˜๋ฆฌ * @param board * @return * @throws Exception */ @PostMapping("/insert") public String insertPro(Board board) throws Exception { // ๋ฐ์ดํ„ฐ ์š”์ฒญ int result = boardService.insert(board); // ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ // โญ• ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์„ฑ๊ณต if( result > 0 ) { return "redirect:/board/list"; } // โŒ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹คํŒจ return "redirect:/board/insert?error"; } /** * ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ํ™”๋ฉด * @param no * @param model * @return * @throws Exception */ @GetMapping("/update") public String update(@RequestParam("no") int no, Model model) throws Exception { Board board = boardService.select(no); model.addAttribute("board", board); return "/board/update"; } /** * ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ์ฒ˜๋ฆฌ * @param board * @return * @throws Exception */ @PostMapping("/update") public String updatePro(Board board) throws Exception { int result = boardService.update(board); if( result > 0 ) { return "redirect:/board/list"; } int no = board.getNo(); return "redirect:/board/update?no="+ no + "&error"; } /** * ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ ์ฒ˜๋ฆฌ * @param no * @return * @throws Exception */ @PostMapping("/delete") public String delete(@RequestParam("no") int no) throws Exception { int result = boardService.delete(no); if( result > 0 ) { return "redirect:/board/list"; } return "redirect:/board/update?no=" + no + "&error"; } }
Java
๋ณต์‚ฌ

board/list.html

โ€ข
๋ชฉ๋ก
โ€ข
ํŽ˜์ด์ง€๋„ค์ด์…˜
โ€ข
์ „์ฒด์ฝ”๋“œ list.html

๋ชฉ๋ก

<h1>๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก</h1> <a href="/board/insert">๊ธ€์“ฐ๊ธฐ</a> <table border="1"> <tr> <th width="50">๋ฒˆํ˜ธ</th> <th width="300">์ œ๋ชฉ</th> <th width="100">์ž‘์„ฑ์ž</th> <th width="200">๋“ฑ๋ก์ผ์ž</th> <th width="200">์ˆ˜์ •์ผ์ž</th> </tr> <th:block th:each="board : ${pageInfo.list}"> <tr> <td align="center" th:text="${board.no}"></td> <td> <!-- th:???="|๋ฌธ์ž์—ด+${ํ‘œํ˜„์‹}|" --> <a th:href="|/board/read?no=${board.no}|" th:text="${board.title}"></a> </td> <td align="center" th:text="${board.writer}"></td> <!-- ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ์ฒด.๋ฉ”์†Œ๋“œ() #dates.format( ๋‚ ์งœ๊ฐ์ฒด๋ช…, '๋‚ ์งœํฌ๋งท' ) - #dates.format( board.regDate, 'yyyy-MM-dd HH:mm:ss' ) --> <td align="center"> <span th:text="${ #dates.format( board.createdAt, 'yyyy-MM-dd HH:mm:ss' ) }"></span> </td> <td align="center"> <span th:text="${ #dates.format( board.updatedAt, 'yyyy-MM-dd HH:mm:ss' ) }"></span> </td> </tr> </th:block> </table>
HTML
๋ณต์‚ฌ

ํŽ˜์ด์ง€๋„ค์ด์…˜

ํŽ˜์ด์ง€๋„ค์ด์…˜์€ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€๋กœ ๋‚˜๋ˆ„์–ด ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋ฒ•์œผ๋กœ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๊ณ  ์„œ๋ฒ„ ๋ถ€ํ•˜๋ฅผ ์ค„์ด๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค.
โ€ข
์œ ๋™์ ์ธ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ ์ถœ๋ ฅ (pagehelper)
โ€ข
10(count)๊ฐœ์”ฉ ๋Š์–ด์„œ ๊ณ ์ • ์ถœ๋ ฅ (pagination ์ง์ ‘๊ตฌํ˜„)
โ—ฆ
1~10, 11~20, โ€ฆ

์œ ๋™์ ์ธ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ ์ถœ๋ ฅ (pagehelper)

<!-- ํŽ˜์ด์ง€๋„ค์ด์…˜ --> <!-- โšก ์œ ๋™์ ์ธ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ ์ถœ๋ ฅ (pagehelper) --> <th:block th:if="${pageInfo.pages > 0}"> <div class="pagination flex justify-content-center"> <ul style="display: flex; list-style-type: none; gap: 10px;"> <li th:if="${pageInfo.pageNum > 1}"> <a th:href="@{/board/list(page=1, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="currentColor" transform="scale(-1, 1)"> <path d="M224 239L29.66 44.66c-9.37-9.37-24.57-9.37-33.94 0L-26.34 67c-9.37 9.37-9.37 24.57 0 33.94L128.97 256-26.34 410.05c-9.37 9.37-9.37 24.57 0 33.94l22.34 22.34c9.37 9.37 24.57 9.37 33.94 0L224 273c9.37-9.37 9.37-24.57 0-33.94zM448 273L253.66 467.34c-9.37 9.37-24.57 9.37-33.94 0L197.34 445c-9.37-9.37-9.37-24.57 0-33.94L352.97 256 197.34 100.95c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L448 239c9.37 9.37 9.37 24.57 0 33.94z"/> </svg> </a> </li> <li th:if="${pageInfo.hasPreviousPage}"> <a th:href="@{/board/list(page=${pageInfo.prePage}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" width="16" height="16" fill="currentColor"><path d="M34.52 239l194.34-194.34c9.37-9.37 24.57-9.37 33.94 0l22.34 22.34c9.37 9.37 9.37 24.57 0 33.94L128.97 256l156.17 156.17c9.37 9.37 9.37 24.57 0 33.94l-22.34 22.34c-9.37 9.37-24.57 9.37-33.94 0L34.52 273c-9.37-9.37-9.37-24.57 0-33.94z"/></svg> </a> </li> <li th:each="i : ${#numbers.sequence(pageInfo.navigateFirstPage, pageInfo.navigateLastPage)}"> <a th:href="@{/board/list(page=${i}, size=${pageInfo.pageSize})}" th:text="${i}" class="page" th:classappend="${pageInfo.pageNum == i} ? 'active' : ''"></a> </li> <li th:if="${pageInfo.hasNextPage}"> <a th:href="@{/board/list(page=${pageInfo.nextPage}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" width="16" height="16" fill="currentColor"><path d="M285.48 273l-194.34 194.34c-9.37 9.37-24.57 9.37-33.94 0l-22.34-22.34c-9.37-9.37-9.37-24.57 0-33.94L191.03 256 34.86 99.83c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L285.48 239c9.37 9.37 9.37 24.57 0 33.94z"/></svg> </a> </li> <li th:if="${pageInfo.pageNum < pageInfo.pages}"> <a th:href="@{/board/list(page=${pageInfo.pages}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="currentColor"> <path d="M224 239L29.66 44.66c-9.37-9.37-24.57-9.37-33.94 0L-26.34 67c-9.37 9.37-9.37 24.57 0 33.94L128.97 256-26.34 410.05c-9.37 9.37-9.37 24.57 0 33.94l22.34 22.34c9.37 9.37 24.57 9.37 33.94 0L224 273c9.37-9.37 9.37-24.57 0-33.94zM448 273L253.66 467.34c-9.37 9.37-24.57 9.37-33.94 0L197.34 445c-9.37-9.37-9.37-24.57 0-33.94L352.97 256 197.34 100.95c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L448 239c9.37 9.37 9.37 24.57 0 33.94z"/> </svg> </a> </li> </ul> </div> </th:block>
HTML
๋ณต์‚ฌ

10(count)๊ฐœ์”ฉ ๋Š์–ด์„œ ๊ณ ์ • ์ถœ๋ ฅ (pagination ์ง์ ‘๊ตฌํ˜„)

<!-- ํŽ˜์ด์ง€๋„ค์ด์…˜ --> <!-- โšก 10(count)๊ฐœ์”ฉ ๋Š์–ด์„œ ๊ณ ์ • --> <th:block th:if="${pageInfo.pages > 0}"> <div class="pagination flex justify-content-center"> <ul style="display: flex; list-style-type: none; gap: 10px;"> <li th:if="${pageInfo.pageNum > 1}"> <a th:href="@{/board/list(page=1, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="currentColor" transform="scale(-1, 1)"> <path d="M224 239L29.66 44.66c-9.37-9.37-24.57-9.37-33.94 0L-26.34 67c-9.37 9.37-9.37 24.57 0 33.94L128.97 256-26.34 410.05c-9.37 9.37-9.37 24.57 0 33.94l22.34 22.34c9.37 9.37 24.57 9.37 33.94 0L224 273c9.37-9.37 9.37-24.57 0-33.94zM448 273L253.66 467.34c-9.37 9.37-24.57 9.37-33.94 0L197.34 445c-9.37-9.37-9.37-24.57 0-33.94L352.97 256 197.34 100.95c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L448 239c9.37 9.37 9.37 24.57 0 33.94z"/> </svg> </a> </li> <li th:if="${pageInfo.hasPreviousPage}"> <a th:href="@{/board/list(page=${pageInfo.prePage}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" width="16" height="16" fill="currentColor"><path d="M34.52 239l194.34-194.34c9.37-9.37 24.57-9.37 33.94 0l22.34 22.34c9.37 9.37 9.37 24.57 0 33.94L128.97 256l156.17 156.17c9.37 9.37 9.37 24.57 0 33.94l-22.34 22.34c-9.37 9.37-24.57 9.37-33.94 0L34.52 273c-9.37-9.37-9.37-24.57 0-33.94z"/></svg> </a> </li> <li th:each="i : ${#numbers.sequence(pagination.start, pagination.end)}"> <a th:href="@{/board/list(page=${i}, size=${pageInfo.pageSize})}" th:text="${i}" class="page" th:classappend="${pageInfo.pageNum == i} ? 'active' : ''"></a> </li> <li th:if="${pageInfo.hasNextPage}"> <a th:href="@{/board/list(page=${pageInfo.nextPage}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" width="16" height="16" fill="currentColor"><path d="M285.48 273l-194.34 194.34c-9.37 9.37-24.57 9.37-33.94 0l-22.34-22.34c-9.37-9.37-9.37-24.57 0-33.94L191.03 256 34.86 99.83c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L285.48 239c9.37 9.37 9.37 24.57 0 33.94z"/></svg> </a> </li> <li th:if="${pageInfo.pageNum < pageInfo.pages}"> <a th:href="@{/board/list(page=${pageInfo.pages}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="currentColor"> <path d="M224 239L29.66 44.66c-9.37-9.37-24.57-9.37-33.94 0L-26.34 67c-9.37 9.37-9.37 24.57 0 33.94L128.97 256-26.34 410.05c-9.37 9.37-9.37 24.57 0 33.94l22.34 22.34c9.37 9.37 24.57 9.37 33.94 0L224 273c9.37-9.37 9.37-24.57 0-33.94zM448 273L253.66 467.34c-9.37 9.37-24.57 9.37-33.94 0L197.34 445c-9.37-9.37-9.37-24.57 0-33.94L352.97 256 197.34 100.95c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L448 239c9.37 9.37 9.37 24.57 0 33.94z"/> </svg> </a> </li> </ul> </div> </th:block>
HTML
๋ณต์‚ฌ

์ „์ฒด์ฝ”๋“œ list.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก</title> <style> .page { padding: 5px 10px; border: 1px solid #ccc; cursor: pointer; text-decoration: none; } .page.active { font-weight: bold; } </style> </head> <body> <h1>๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก</h1> <a href="/board/insert">๊ธ€์“ฐ๊ธฐ</a> <table border="1"> <tr> <th width="50">๋ฒˆํ˜ธ</th> <th width="300">์ œ๋ชฉ</th> <th width="100">์ž‘์„ฑ์ž</th> <th width="200">๋“ฑ๋ก์ผ์ž</th> <th width="200">์ˆ˜์ •์ผ์ž</th> </tr> <th:block th:each="board : ${pageInfo.list}"> <tr> <td align="center" th:text="${board.no}"></td> <td> <!-- th:???="|๋ฌธ์ž์—ด+${ํ‘œํ˜„์‹}|" --> <a th:href="|/board/read?no=${board.no}|" th:text="${board.title}"></a> </td> <td align="center" th:text="${board.writer}"></td> <!-- ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ์ฒด.๋ฉ”์†Œ๋“œ() #dates.format( ๋‚ ์งœ๊ฐ์ฒด๋ช…, '๋‚ ์งœํฌ๋งท' ) - #dates.format( board.regDate, 'yyyy-MM-dd HH:mm:ss' ) --> <td align="center"> <span th:text="${ #dates.format( board.createdAt, 'yyyy-MM-dd HH:mm:ss' ) }"></span> </td> <td align="center"> <span th:text="${ #dates.format( board.updatedAt, 'yyyy-MM-dd HH:mm:ss' ) }"></span> </td> </tr> </th:block> </table> <!-- ํŽ˜์ด์ง€๋„ค์ด์…˜ --> <!-- โšก ์œ ๋™์ ์ธ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ ์ถœ๋ ฅ (pagehelper) --> <th:block th:if="${pageInfo.pages > 0}"> <div class="pagination flex justify-content-center"> <ul style="display: flex; list-style-type: none; gap: 10px;"> <li th:if="${pageInfo.pageNum > 1}"> <a th:href="@{/board/list(page=1, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="currentColor" transform="scale(-1, 1)"> <path d="M224 239L29.66 44.66c-9.37-9.37-24.57-9.37-33.94 0L-26.34 67c-9.37 9.37-9.37 24.57 0 33.94L128.97 256-26.34 410.05c-9.37 9.37-9.37 24.57 0 33.94l22.34 22.34c9.37 9.37 24.57 9.37 33.94 0L224 273c9.37-9.37 9.37-24.57 0-33.94zM448 273L253.66 467.34c-9.37 9.37-24.57 9.37-33.94 0L197.34 445c-9.37-9.37-9.37-24.57 0-33.94L352.97 256 197.34 100.95c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L448 239c9.37 9.37 9.37 24.57 0 33.94z"/> </svg> </a> </li> <li th:if="${pageInfo.hasPreviousPage}"> <a th:href="@{/board/list(page=${pageInfo.prePage}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" width="16" height="16" fill="currentColor"><path d="M34.52 239l194.34-194.34c9.37-9.37 24.57-9.37 33.94 0l22.34 22.34c9.37 9.37 9.37 24.57 0 33.94L128.97 256l156.17 156.17c9.37 9.37 9.37 24.57 0 33.94l-22.34 22.34c-9.37 9.37-24.57 9.37-33.94 0L34.52 273c-9.37-9.37-9.37-24.57 0-33.94z"/></svg> </a> </li> <li th:each="i : ${#numbers.sequence(pageInfo.navigateFirstPage, pageInfo.navigateLastPage)}"> <a th:href="@{/board/list(page=${i}, size=${pageInfo.pageSize})}" th:text="${i}" class="page" th:classappend="${pageInfo.pageNum == i} ? 'active' : ''"></a> </li> <li th:if="${pageInfo.hasNextPage}"> <a th:href="@{/board/list(page=${pageInfo.nextPage}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" width="16" height="16" fill="currentColor"><path d="M285.48 273l-194.34 194.34c-9.37 9.37-24.57 9.37-33.94 0l-22.34-22.34c-9.37-9.37-9.37-24.57 0-33.94L191.03 256 34.86 99.83c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L285.48 239c9.37 9.37 9.37 24.57 0 33.94z"/></svg> </a> </li> <li th:if="${pageInfo.pageNum < pageInfo.pages}"> <a th:href="@{/board/list(page=${pageInfo.pages}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="currentColor"> <path d="M224 239L29.66 44.66c-9.37-9.37-24.57-9.37-33.94 0L-26.34 67c-9.37 9.37-9.37 24.57 0 33.94L128.97 256-26.34 410.05c-9.37 9.37-9.37 24.57 0 33.94l22.34 22.34c9.37 9.37 24.57 9.37 33.94 0L224 273c9.37-9.37 9.37-24.57 0-33.94zM448 273L253.66 467.34c-9.37 9.37-24.57 9.37-33.94 0L197.34 445c-9.37-9.37-9.37-24.57 0-33.94L352.97 256 197.34 100.95c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L448 239c9.37 9.37 9.37 24.57 0 33.94z"/> </svg> </a> </li> </ul> </div> </th:block> <!-- ํŽ˜์ด์ง€๋„ค์ด์…˜ --> <!-- โšก 10(count)๊ฐœ์”ฉ ๋Š์–ด์„œ ๊ณ ์ • --> <th:block th:if="${pageInfo.pages > 0}"> <div class="pagination flex justify-content-center"> <ul style="display: flex; list-style-type: none; gap: 10px;"> <li th:if="${pageInfo.pageNum > 1}"> <a th:href="@{/board/list(page=1, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="currentColor" transform="scale(-1, 1)"> <path d="M224 239L29.66 44.66c-9.37-9.37-24.57-9.37-33.94 0L-26.34 67c-9.37 9.37-9.37 24.57 0 33.94L128.97 256-26.34 410.05c-9.37 9.37-9.37 24.57 0 33.94l22.34 22.34c9.37 9.37 24.57 9.37 33.94 0L224 273c9.37-9.37 9.37-24.57 0-33.94zM448 273L253.66 467.34c-9.37 9.37-24.57 9.37-33.94 0L197.34 445c-9.37-9.37-9.37-24.57 0-33.94L352.97 256 197.34 100.95c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L448 239c9.37 9.37 9.37 24.57 0 33.94z"/> </svg> </a> </li> <li th:if="${pageInfo.hasPreviousPage}"> <a th:href="@{/board/list(page=${pageInfo.prePage}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" width="16" height="16" fill="currentColor"><path d="M34.52 239l194.34-194.34c9.37-9.37 24.57-9.37 33.94 0l22.34 22.34c9.37 9.37 9.37 24.57 0 33.94L128.97 256l156.17 156.17c9.37 9.37 9.37 24.57 0 33.94l-22.34 22.34c-9.37 9.37-24.57 9.37-33.94 0L34.52 273c-9.37-9.37-9.37-24.57 0-33.94z"/></svg> </a> </li> <li th:each="i : ${#numbers.sequence(pagination.start, pagination.end)}"> <a th:href="@{/board/list(page=${i}, size=${pageInfo.pageSize})}" th:text="${i}" class="page" th:classappend="${pageInfo.pageNum == i} ? 'active' : ''"></a> </li> <li th:if="${pageInfo.hasNextPage}"> <a th:href="@{/board/list(page=${pageInfo.nextPage}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" width="16" height="16" fill="currentColor"><path d="M285.48 273l-194.34 194.34c-9.37 9.37-24.57 9.37-33.94 0l-22.34-22.34c-9.37-9.37-9.37-24.57 0-33.94L191.03 256 34.86 99.83c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L285.48 239c9.37 9.37 9.37 24.57 0 33.94z"/></svg> </a> </li> <li th:if="${pageInfo.pageNum < pageInfo.pages}"> <a th:href="@{/board/list(page=${pageInfo.pages}, size=${pageInfo.pageSize})}"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="currentColor"> <path d="M224 239L29.66 44.66c-9.37-9.37-24.57-9.37-33.94 0L-26.34 67c-9.37 9.37-9.37 24.57 0 33.94L128.97 256-26.34 410.05c-9.37 9.37-9.37 24.57 0 33.94l22.34 22.34c9.37 9.37 24.57 9.37 33.94 0L224 273c9.37-9.37 9.37-24.57 0-33.94zM448 273L253.66 467.34c-9.37 9.37-24.57 9.37-33.94 0L197.34 445c-9.37-9.37-9.37-24.57 0-33.94L352.97 256 197.34 100.95c-9.37-9.37-9.37-24.57 0-33.94l22.34-22.34c9.37-9.37 24.57-9.37 33.94 0L448 239c9.37 9.37 9.37 24.57 0 33.94z"/> </svg> </a> </li> </ul> </div> </th:block> </body> </html>
HTML
๋ณต์‚ฌ