2018. 10. 13. 21:27ㆍWeb/JPA
spring boot 환경이 아니라, 일반 springframework 환경에서 진행하였습니다.
모든 소스는 mac OS 환경에서 진행되었습니다.
이번에는 ORM을 이용한 데이터베이스 조작입니다. ORM이란 자바객체와 관계형데이터베이스의 테이블 간의 매핑을 아주 쉽게 해주는 기술입니다. 주로 mybatis만 이용하는 저였기에 이 기술을 접하고 아주 신세계...하지만 둘다 장단점이 있는 기술인 것같습니다. 아직까지는 우리나라는 mybatis를 더욱 많이 쓰고 있는 것 같기도 한데....맞나요..
project 우클릭 -> properties -> project facets -> JPA 선택.
resources 밑에 영속성 관련 설정을 할 수 있는 persistence.xml이 생성되어 있을 것입니다. 요 설정 파일에 영속성 엔티티 클래스 및 기타 설정파일을 따로 설정하실수 있습니다.
pom.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 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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.spring</groupId> <artifactId>jpa</artifactId> <name>springjpa</name> <packaging>war</packaging> <version>1.0.0-BUILD-SNAPSHOT</version> <properties> <java-version>1.8</java-version> <org.springframework-version>5.0.2.RELEASE</org.springframework-version> <org.aspectj-version>1.6.10</org.aspectj-version> <org.slf4j-version>1.6.6</org.slf4j-version> </properties> <!-- 오라클 저장소 --> <repositories> <repository> <id>codelds</id> <url>https://code.lds.org/nexus/content/groups/main-repo</url> </repository> </repositories> <dependencies> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.1.11.Final</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>2.0.2.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm --> <!-- <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${org.springframework-version}</version> </dependency> --> <!-- oracle --> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ucp</artifactId> <version>11.2.0.3</version> <scope>compile</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.0</version> </dependency> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework-version}</version> <exclusions> <!-- Exclude Commons Logging in favor of SLF4j --> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework-version}</version> </dependency> <!-- AspectJ --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${org.aspectj-version}</version> </dependency> <!-- Logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${org.slf4j-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> <exclusions> <exclusion> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> </exclusion> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> </exclusions> <scope>runtime</scope> </dependency> <!-- @Inject --> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <!-- Servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Test --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-eclipse-plugin</artifactId> <version>2.9</version> <configuration> <additionalProjectnatures> <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature> </additionalProjectnatures> <additionalBuildcommands> <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand> </additionalBuildcommands> <downloadSources>true</downloadSources> <downloadJavadocs>true</downloadJavadocs> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.6</source> <target>1.6</target> <compilerArgument>-Xlint:all</compilerArgument> <showWarnings>true</showWarnings> <showDeprecation>true</showDeprecation> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <mainClass>org.test.int1.Main</mainClass> </configuration> </plugin> </plugins> </build> </project> | cs |
application.properties, servlet-context.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 | <?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <mvc:annotation-driven /> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <mvc:resources mapping="/resources/**" location="/resources/" /> <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean> <context:component-scan base-package="com.spring.jpa.controller" /> </beans:beans> | cs |
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 | <?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:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://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 http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- Root Context: defines shared resources visible to all other web components --> <context:component-scan base-package="com.spring.jpa"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/> </bean> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:59162:xe"/> <property name="username" value="springjpa"/> <property name="password" value="springjpa"/> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <tx:annotation-driven/> <jpa:repositories base-package="com.spring.jpa.repository"/><!-- transactionManager라는 이름이 아니면 명시적으로 등록해주어야한다. --> </beans> | cs |
만약 트랜잭션매니저 빈의 id을 transactionManager라고 지정하지 않았다면, jpa:repositories 태그에 명시적으로 트랜잭션 id값 설정을 넣어줘야한다.
UserEntity.java , NationEntity.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 | package com.spring.jpa.model; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.PrePersist; import javax.persistence.Table; @Entity @Table(name="TBL_USER") public class UserEntity implements Serializable{ @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="USER_ID") private long id; private String userName; private int age; private Date createdAt; @Column(name="role") @Enumerated(EnumType.ORDINAL) //ORDINAL -> int로 할당 STRING -> 문자열로 할당 private UserRole role; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name="NATION_ID") private NationEntity nationEntity; @PrePersist public void beforeCreate() { createdAt=new Date(); } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getCreatedAt() { return createdAt; } public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } public UserRole getRole() { return role; } public void setRole(UserRole role) { this.role = role; } public NationEntity getNationEntity() { return nationEntity; } public void setNationEntity(NationEntity nationEntity) { this.nationEntity = nationEntity; } } | cs |
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 | package com.spring.jpa.model; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name="TBL_NATION") public class NationEntity { @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="NATION_ID") private long id; private String nationName; private String nationCode; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getNationName() { return nationName; } public void setNationName(String nationName) { this.nationName = nationName; } public String getNationCode() { return nationCode; } public void setNationCode(String nationCode) { this.nationCode = nationCode; } } | cs |
기타 어노테이션들은 구글링으로...
persistence.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="springjpa"> <class>com.spring.jpa.model.UserEntity</class> <class>com.spring.jpa.model.NationEntity</class> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.use_sql_comments" value="false"/> <property name="hibernate.id.new_generator_mappings" value="true"/> <property name="hibernate.hbm2ddl.auto" value="create"/> </properties> </persistence-unit> </persistence> | cs |
JpaUserRepository.java , JpaNationRepository.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package com.spring.jpa.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import com.spring.jpa.model.UserEntity; @Repository("jpaUserRepository") public interface JpaUserRepository extends JpaRepository<UserEntity, Long> { UserEntity findByUserName(String userName); @Query(value="SELECT * FROM TBL_USER WHERE USERNAME=?1 AND AGE=?2",nativeQuery=true) UserEntity findByUserNameAndAge(String userName,int age); } | cs |
1 2 3 4 5 6 7 8 9 10 | package com.spring.jpa.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.spring.jpa.model.NationEntity; public interface JpaNationRepository extends JpaRepository<NationEntity, Long> { NationEntity findByNationName(String nationName); } | cs |
JpaReposotory 인터페이스는 기본적으로 CRUDRepository,PagingAndSortingRepository,QueryByExampleExecutor,Repository 인터페이스들을 상속한 인터페이스입니다. 즉, JpaRepository 인터페이스 하나면 상속받으면 대부분 기본기능들은 모두 사용가능합니다. 하지만 조금은 복잡한 쿼리를 일반 쿼리로 작성하고 싶다면, 위의 예제처럼 native한 쿼리를 작성하여 메소드에 매핑해 줄 수 있습니다.
UserController.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 | package com.spring.jpa.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import com.spring.jpa.model.NationEntity; import com.spring.jpa.model.UserEntity; import com.spring.jpa.model.UserRole; import com.spring.jpa.repository.JpaNationRepository; import com.spring.jpa.service.UserService; @Controller public class UserController { private final static Logger log=LoggerFactory.getLogger(UserController.class); @Autowired UserService userService; @Autowired JpaNationRepository jpaNationRepository; @GetMapping("/user") public String getUserView() { return "user"; } @GetMapping("/usersave") public String saveUser(ModelMap map,UserEntity userEntity,NationEntity nationEntity) { nationEntity.setNationCode("KR"); nationEntity.setNationName("대한민국"); jpaNationRepository.save(nationEntity); userEntity.setUserName("여성게"); userEntity.setAge(27); userEntity.setRole(UserRole.USER); userEntity.setNationEntity(nationEntity); userService.save(userEntity); UserEntity saveUser=userService.findByUserName("여성게"); UserEntity user=userService.findByUserNameAndAge(saveUser.getUserName(), saveUser.getAge()); log.info("username={},user age={}",user.getUserName(),user.getAge()); log.info("nationCode={},nationName={}",user.getNationEntity().getNationCode(),user.getNationEntity().getNationName()); map.addAttribute("userEntity", saveUser); return "userlist"; } } | cs |
기타 Service클래스 등은 첨부하지 않았습니다.
굉장히 간단한 jpa 예제입니다. 추후 QueryDsl과 jpa를 이용한 예제를 업로드할 예정입니다.
부족한점은 많이 코멘트 남겨주시면 감사하겠습니다...
'Web > JPA' 카테고리의 다른 글
JPA- 연관관계 외래키의 주인과 주인의 참조자 관계 (0) | 2019.01.24 |
---|---|
JPA - 다대다 연관관계(@ManyToMany),N:N (0) | 2019.01.24 |
JPA - 기본 키 매핑 전략(@Id) (0) | 2019.01.17 |
JPA 영속성 관리 - persistence context(영속성컨텍스트) (1) | 2019.01.15 |
springframework JPA + QueryDSL (0) | 2018.10.14 |