public class ArticleService {
private ArticleRepository articleRepository;
@Autowired
ArticleService(ArticleRepository articleRepository){
this.articleRepository =articleRepository;
articleRepository.makeTestData();
}
1. mybatis, MySql JDBC 드라이버 추가
//MySql JDBC 드라이버
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
//mybatis
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
2. 설정파일에 DB 접속정보 추가
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/SB_AM?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul&useOldAliasMetadataBehavior=true&zeroDateTimeNehavior=convertToNull
username: root
password:
mybatis:
type-aliases-package: com.kjh.exam.demo.vo
3. mybatis 활용하여 SELECT, DELETE, UPDATE 구현
@Mapper
public interface ArticleRepository {
public Article writeArticle(String title, String body);
@Select("SELECT * FROM article WHERE id = #{id}")
public Article getArticle(int id);
@Select("SELECT * FROM article")
public List<Article> getArticles();
@Delete("DELETE FROM article WHERE id = #{id}")
public void deleteArticle(int id);
@Update("UPDATE article SET updateDate = NOW(), title = #{title}, `body`= #{body} WHERE id = #{id}")
public void modifyArticle(int id, String title, String body);
}
repository를 class대신 interface로 사용
interface는 구현부가 존재하지 않아야한다.
@Select, @Delete, @Update 어노테이션안의 쿼리문을 토대로 실행시켜주고 @Select의 경우 결과 값을 반환
동적바인딩을 하고 싶다면 #{ }를 이용, 매개변수를 받아올때 #{ }사용
1. ArticleRepository
@Mapper
public interface ArticleRepository {
@Insert("INSERT INTO article SET regDate = NOW(), updateDate = NOW(), title = #{title}, `body`= #{body}")
public void writeArticle(String title, String body);
@Select("SELECT LAST_INSERT_ID()")
public int getLastInsertId();
2. ArticleService
@Service
public class ArticleService {
public int writeArticle(String title, String body) {
articleRepository.writeArticle(title, body);
return articleRepository.getLastInsertId();
}
3. ArticleController
@Controller
public class UsrArticleController {
@RequestMapping("usr/article/doAdd")
@ResponseBody
public Article doAdd(String title, String body) {
int id = articleService.writeArticle(title, body);
Article article = articleService.getArticle(id);
return article;
}
Spring IoC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라는 용어로 부른다.
new 연산자로 어떤 객체를 생성했을 때 그 객체는 빈이 아니다.
ApplicationContext.getBean()으로 얻어질 수 있는 객체는 빈이다.
즉 Spring에서의 빈은 ApplicationContext가 알고있는 객체,
즉 ApplicationContext가 만들어서 그 안에 담고있는 객체를 의미
빈을 만드는 방법은 다양하지만 기본적으로 크게 두가지 방법이 있다.
1.Component Scanning
2.빈 설정파일에 직접 빈을 등록
@ComponentScan 어노테이션과 @Component 어노테이션을 사용해서 빈을 등록하도록 하는 방법
@ComponentScan 어노테이션은 어느 지점부터 컴포넌트를 찾으라고 알려주는 역할을 하고
@Component는 실제로 찾아서 빈으로 등록할 클래스를 의미
@ComponentScan 어노테이션은 어디서부터 컴포넌트를 찾아볼 것인지 알려주는 역할을 한다.
@ComponentScan이 붙어있는 클래스가 있는 패키지
에서부터 모든 하위 패키지의 모든 클래스
를 훑어보며 @Component 어노테이션(또는 @Component 어노테이션을 사용하는 다른 어노테이션)이 붙은 클래스를 찾는다. 하지만 이 패키지 밖에있는 클래스들은 스캔이 되지 않는다.
Spring이 IoC 컨테이너를 만들때 위와 같은 과정을 거쳐 빈으로 등록해주는 것이다.
@SpringBootApplication
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {... 생략 ...
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") Class<?>[] scanBasePackageClasses() default {};
내가 아무런 ComponentScan 관련 설정을 하지 않았다면 바로 이 @SpringBootApplication
가 정의된 곳이 base package
@AliasFor
부분에 나온 basePackages
와 basePackagesClasses
도 중요하다. Springboot Main Class의 위치에 구애받지 않고 내가 마음대로 ComponentScan을 할 곳을 정의할때 사용된다
Spring boot 프로젝트에서는 @SpringBootApplication에 이미 @Configuration과 @ComponentScan이 붙어있다. 따라서 @SpringBootApplication 기준으로 스캐닝이 시작된다.
- 빈 등록을 위한 어노테이션 @Bean, @Configuration, @Component -
????????일단 패키지가 다른데@Component repository가 scan되는 이유..가 뭘까?