CRUD — это четыре необходимые функции приложения хранилища
- Создайте
- читать
- Обновить
- Удалить
Сегодня давайте посмотрим, как создать простой веб-сайт блога с помощью Spring MVC.
- создать устаревший проект
- Изменить версию Spring в pom.xml
- Добавить тест Spring, Spring JDBC, Spring tx
- Изменить версию Junit
- Изменить версию сервлета
- Добавить HiakriCp, MyBatis, Mybatis-spring, Log4jdbc
- Добавьте драйвер JDBC в проект.
- Настройка Ломбок и т. д.
Добавить зависимость из репозитория Maven в pom.xml
«Репозиторий Maven: поиск/обзор/исследование
no.priv.bang.authservice “ authservice.definitions “ 1.11.13 Apachemvnrepository.com”
Плюсы и минусы Хикари.
- Быстрый с небольшим количеством пользователей (до 16000)
- Может быть медленным с большим количеством пользователей
<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP --> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>3.4.5</version> </dependency>
Log4jdbc
- Распечатать лог.
- Полезно для разработчиков.
Вот видео с экрана
- создать проект
- добавить зависимости из репозитория maven
добавить зависимости из репозитория maven
spring tx: весенняя транзакция 5.2.8
Пул подключения к БД
-hikaricp
мибатис 3.5.5
мибатис весна 2.0.5
Ломбок 1.18.12
- Бин
- Аннотация — автоматически генерировать геттер и сеттер.
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency>
Log4Jdbc Log4j2 JDBC 4 1
<dependency> <groupId>org.bgee.log4jdbc-log4j2</groupId> <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> <version>1.16</version> </dependency>
- изменить путь к серверу
- установить языковой фильтр (корейский)
→ Скопируйте и вставьте соответствующий фильтр в файл XML
Оракул
1. создать учетную запись
2. Создайте таблицу и вставьте строку
создать последовательность seq_board;
create sequence seq_board; create table board( bno number primary key, title varchar2(100) not null, content varchar2(2000)not null, writer varchar2(50) not null, regdate date default sysdate, updatedate date default sysdate); insert into board(bno,title, content, writer)values (seq_board.nextval, '테스트 제목' ,'테스트내용' ,'user01'); select * from baord;
выберите * с доски; вот видео процесса.
Для подключения к базе данных
подключить пул
<!-- Root Context: defines shared resources visible to all other web components --> <!-- resource적는거임 --> <!-- Root Context: defines shared resources visible to all other web components --> <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig"> <!-- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:XE"/> --> <property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"></property> <property name="jdbcUrl" value="jdbc:log4jdbc:oracle:thin:@localhost:1521:XE"></property> <property name="username" value="spring" /> <property name="password" value="1234" /> </bean>
Фабрика сеансов SQL
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- datasource로 --> <property name="dataSource" ref="dataSource" /> </bean>
создайте пакет для создания картографа.
Сопоставьте путь с BoardMapper.java
→ Сервис → Контроллер → Возврат результата
контроллер.java
package org.knr.boardex001.controller; import org.knr.boardex001.domain.BoardVO; import org.knr.boardex001.service.BoardService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import lombok.AllArgsConstructor; import lombok.extern.java.Log; import oracle.net.ano.Service; @Controller @Log @RequestMapping("/board") @AllArgsConstructor public class BoardController { private BoardService service; @GetMapping("/list") public void list(Model model) { log.info("list..........!"); model.addAttribute("list",service.getList()); } @GetMapping("/register") public void register() { } @PostMapping("/register") public String registerPro(BoardVO board,RedirectAttributes rttr) { log.info("registerPro"); service.register(board); rttr.addFlashAttribute("result", board.getBno()); return "redirect:list"; } @GetMapping("/get") public void get(Long bno,Model model) { log.info("get"); model.addAttribute("board", service.get(bno)); } @PostMapping("/update") public String update(BoardVO board) { log.info("update"); if(service.modify(board)) { return "redirect:list"; }else { return "redirect:get"; } } @GetMapping("/delete") public String delete(Long bno) { log.info("delete"); if(service.remove(bno)) { return "redirect:list"; }else { return "redirect:get"; } } }
Добавить objdbc6.jar
- проект → путь сборки → настроить путь сборки → добавить внешний Jar
- Построить путь
проект → свойства→ сборка развертывания→ добавить
→записи путей сборки java
УСТАНОВИТЬ контекст данных
- Запись ресурса
- Настройка отношения к базе данных
Пакет домена
- то же самое с содержимым базы данных оракула
"@Данные"
package org.knr.boardex001.domain;
import java.util.Date; import lombok.Data;
@Data public class BoardVO { private Long bno; private String title; private String content; private Date regdate; private Date updatedate;
}
Сопоставитель
- сделать как интерфейс
package org.knr.boardex001.mapper; import java.util.List; import org.apache.ibatis.annotations.Select; import org.knr.boardex001.domain.BoardVO; //원래 결과arraylist에 넣던거를 이렇게 간단하게 할수있음 public interface BoardMapper { @Select("select * from board where bno>0") public List<BoardVO> getList();
дайте знать расположение Mybatis‹путь BoardMapper в моем примере›
в корневом контексте.xml
<mybatis-spring:scan base-package="org.knr.boardex001.mapper"/>
Тестовое подключение к базе данных с тестовым кодом
если это не работает, попробуйте обновление maven
package org.knr.boardex001; import java.sql.Connection; import javax.sql.DataSource; import org.junit.Test; import org.junit.runner.RunWith; import org.knr.boardex001.domain.BoardVO; import org.knr.boardex001.mapper.BoardMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import lombok.Setter; import lombok.extern.log4j.Log4j; //junit가지고 테스트 할게요 @RunWith(SpringJUnit4ClassRunner.class) //안에 db설정한 파일 설정한거 @ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml") //로그 찍는거 //함수를 쓰려면 객체를 만들어야 되는데 // 객체를 가져와야 하는데 객체를 못 만들기 때문에 @Log4j public class BoardMapperTest { @Setter(onMethod_ = @Autowired) private BoardMapper mapper; @Setter(onMethod_ = @Autowired) private DataSource dataSource; @Test public void testConnection() { try (Connection conn = dataSource.getConnection()) { log.info(conn); } catch (Exception e) { e.printStackTrace(); } } // mapper에 getlist의 결과를 얻어와서 각각의 것을 board에 넣어서 log.info를 출력함 @Test public void testGList() { mapper.getList().forEach(board -> log.info(board)); } @Test public void testInsert() { BoardVO board = new BoardVO(); board.setTitle("새글 제목"); board.setContent("새글 내용"); board.setWriter("newUser"); mapper.insertSelectKey(board); log.info(board); } @Test public void testRead() { // L을 붙이는 이유는 Long이라서 BoardVO board = mapper.read(1L); log.info(board); } @Test public void testDelete() { int n= mapper.delete(2l); if(n==1) { log.info("삭제성공"); } } @Test public void testUpdate() { BoardVO board = new BoardVO(); board.setBno(1L); board.setTitle("수정제목"); board.setContent("수정내용"); board.setWriter("user01"); int n =mapper.update(board); if(n==1) { log.info("수정성공"); } } }
Добавить Мибатиса
получить источник данных из нижней части файла корневого контекста
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring" xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- Root Context: defines shared resources visible to all other web components --> <!-- resource적는거임 --> <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig"> <!-- 데이터베이스,url, pw뭔지 --> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:XE"></property> <property name="username" value="spring" /> <property name="password" value="1234" /> </bean> <!-- 실제로 resource얻을때 datasource로 얻음 이 안에 데이터 설정해 놓은 hikariConfig를 넣는다. --> <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close"> <constructor-arg ref="hikariConfig" /> </bean> <!-- 하나 접속이 세션 그걸 생성하는 factorybean --> <!-- mybatis는 sql로 이루어져 있고 , 접속하는bean을 만드는 factory --> <!-- 원래는 field로 datasource를 들고 있음 --> <!-- jsp로 할때는 없어도 되는데 지금은 my batis를 사용하기 때문에 필요함 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- datasource로 --> <property name="dataSource" ref="dataSource" /> </bean> <!-- mybatis가 어디 있는지 --> <mybatis-spring:scan base-package="org.knr.boardex001.mapper"/> <!-- 스캔하는 default package --> <context:component-scan base-package="org.knr.boardex001"/> </beans>
Коннекпул
- Сохраните использованный и принесите его из бассейна.
- Добавьте драйвер JDBC в проект.
Разрешить Eclipse использовать Lombok.
Эта часть тестируется непосредственно прямым впрыском.
@Setter(onMethod_=@Autowired) private DataSource dataSource;
Внедрить этот компонент
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close"> <constructor-arg ref="hikariConfig" /> </bean>
Контекст сервлета
- Включить бины, управляющие веб-настройкой
- найти местоположение контроллера
- Логический вид -> физический вид
Корневой контекст
Настройки отличные от сети.
Сделать маппер с MyBatis
<?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"> 우리가 만들 mybatis의 namespace위치 <mapper namespace="org.mybatis.example.BlogMapper"> <select id="selectBlog" resultType="Blog"> select * from Blog where id = #{id} </select> </mapper> <?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="org.knr.boardex001.mapper.BoardMapper"> <select id="getList" resultType="org.knr.boardex001.domain.BoardVo"> <!-- where절을 넣지 않으면 index사용 안함 --> select * from board </select> </mapper> <?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="org.knr.boardex001.mapper.BoardMapper"> <select id="getList" resultType="org.knr.boardex001.domain.BoardVo"> <!-- where절을 넣지 않으면 index사용 안함 --> select * from board </select> <insert id="insert"> insert into board(bno, title, content, writer) values (seq_board.nextval, #{title},#{content},#{writer}) </insert> <insert id="insertSelectKey"> <selectKey keyProperty="bno" order="BEFORE" resultType="long"> select seq_board.nextval from dual </selectKey> insert into board(bno, title, content, writer) values (#{bno},#{title},#{content},#{writer}) </insert> </mapper>
Вставить тест
- просто нужно создать функцию, потому что картограф существует
Бизнес
- сделка
например в банке
Транзакции A и B сгруппированы как
- Деньги уходят со счета А
- Деньги поступают на счет Б.
если один из них терпит неудачу, сама транзакция терпит неудачу.
Мы делаем то же самое здесь.
Мы группируем услуги в соответствии с использованием веб-сайта.
- Создать пакет услуг
2. создать сервисный интерфейс
package org.knr.boardex001.service; import java.util.List; import org.knr.boardex001.domain.BoardVO; public interface BoardService { //게시물 등록, 얻기 , 수정 , 삭제, 리스트 얻기 //인터페이스니까 추상 메소드로 public void register(BoardVO board); public BoardVO get(Long bno); public boolean modify(BoardVO board); public boolean remove(Long bno); public List<BoardVO> getList(); }
3. Реализовать интерфейс и создать класс
- импортировать картограф
- добавить журнал и сервис
package org.knr.boardex001.service; import java.util.List; import org.knr.boardex001.domain.BoardVO; import org.knr.boardex001.mapper.BoardMapper; import org.springframework.stereotype.Service; import lombok.AllArgsConstructor; import lombok.extern.java.Log; //로그 찍기 위해서 @Log //자동으로dependency injection할거라서 component라는 걸 알려줘야 스캔을 해서 만들 수 있음 @Service //서비스 객체 생성할때 field자동으로 다 만들어서 주입한다. @AllArgsConstructor public class BoardServicempl implements BoardService { // mapper가 있어야함 private BoardMapper boardMapper; @Override public void register(BoardVO board) { // TODO Auto-generated method stub boardMapper.insert(board); } @Override public BoardVO get(Long bno) { // TODO Auto-generated method stub return boardMapper.read(bno); } @Override public boolean modify(BoardVO board) { // TODO Auto-generated method stub int n = boardMapper.update(board); if (n == 1) { return true; } else { return false; } } @Override public boolean remove(Long bno) { // TODO Auto-generated method stub int n = boardMapper.delete(bno); if (n == 1) { return true; } else { return false; } } @Override public List<BoardVO> getList() { // TODO Auto-generated method stub return boardMapper.getList(); } }
allargsconstructor
автоматически создавать и вводить поле при создании объекта службы
- autowire весь маппер внутри.
Создать контроллер
package org.knr.boardex001.controller; import org.knr.boardex001.domain.BoardVO; import org.knr.boardex001.service.BoardService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import lombok.AllArgsConstructor; import lombok.extern.java.Log; import oracle.net.ano.Service; @Controller @Log @RequestMapping("/board") @AllArgsConstructor public class BoardController { private BoardService service; @GetMapping("/list") public void list(Model model) { log.info("list..........!"); model.addAttribute("list",service.getList()); } @GetMapping("/register") public void register() { } @PostMapping("/register") public String registerPro(BoardVO board,RedirectAttributes rttr) { log.info("registerPro"); service.register(board); rttr.addFlashAttribute("result", board.getBno()); return "redirect:list"; } @GetMapping("/get") public void get(Long bno,Model model) { log.info("get"); model.addAttribute("board", service.get(bno)); } @PostMapping("/update") public String update(BoardVO board) { log.info("update"); if(service.modify(board)) { return "redirect:list"; }else { return "redirect:get"; } } @GetMapping("/delete") public String delete(Long bno) { log.info("delete"); if(service.remove(bno)) { return "redirect:list"; }else { return "redirect:get"; } } }
2. список.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <table> <tr> <th>bno</th> <th>title</th> <th>writer</th> <th>regdate</th> <th>updatedate</th> </tr> <c:forEach items="${list }" var="board"> <tr> <td>${board.bno }</td> <td>${board.title }</td> <td>${board.writer }</td> <td><fmt:formatDate value="${board.regdate }" /> </td> <td><fmt:formatDate value="${board.updatedate }" /></td> </tr> </c:forEach> </table> </body> </html>
3.get.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action="update" method="post"> <table> <tr> <th>번호</th> <td><input type="text" name="bno" value="${board.bno}" readonly></td> </tr> <tr> <th>제목</th> <td><input type="text" name="title" value="${board.title}"></td> </tr> <tr> <th>내용</th> <td><textarea rows="5" cols="50" name="content">${board.content}</textarea></td> </tr> <tr> <th>작성자</th> <td><input type="text" name="writer" value="${board.writer}"></td> </tr> <tr> <th>작성일</th> <td>${board.regdate}"</td> </tr> <tr> <th>수정일</th> <td>${board.updatedate}</td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="수정"> <input type="button" value="삭제" onclick="location.href='delete?bno=${board.bno}'"> <input type="reset" value="취소"></td> </tr> </table> </form> </body> </html>
регистрация.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action="register" method="post"> <table> <tr> <th>제목</th> <td><input type="text" name="title"></td> </tr> <tr> <th>내용</th> <td><textarea rows="5" cols="50" name="content"></textarea></td> </tr> <tr> <th>작성자</th> <td><input type="text" name="writer"></td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="등록"> <input type="reset" value="취소"></td> </tr> </table> </form> </body> </html>