List의 구현 클래스이므로 ArrayList나 Vector와 사용 방법은 동일하다. 하지만 구조는 다르게 구성되어있다. 위의 컬렉션들은 인덱스로 데이터를 관리하지만 LinkedList는 인접한 곳을 링크하여 체인처럼 관리한다. LinkedList는 중간의 데이터를 삭제할 때 인접한 곳의 링크만을 변경하면 되기 때문에 중간에 데이터를 추가/삭제하는 경우 처리 속도가 빠르다.
List<E> list = new LinkedList<E>();
상황에 따라 적절한 컬렉션을 사용하면 될거같다. 찾아보니 vector의경우 요즘 JAVA에서는 잘안쓰이는 추세라고한다...
boolean,char byte,short,int,long,float,double와 같이 계산을 할 수 있는 타입.
저장 공간에 값 자체를 저장함
기본형 변수의 타입
정수 타입: byte (1byte), short (2byte), int (4byte), long (8byte)
부동소수점 타입: float (4byte) , double (8byte)
부울 타입: boolean (1byte) // true,false 두 가지 값만 표현
문자 데이터 타입: char (2byte)
기본형 변수의 선언
정수 타입
int age = 20;
long age = 20L; —> Long type을 사용하기 위해선 반드시 붙여야 함
부동소수점 타입
double dot = 10.2
float dot = 10.2F —> float 타입을 사용하기 위해선 반드시 붙여야 함
변수 형변환
확장 변환
데이터 타입보다 더 큰 타입으로 변환되기 때문에, 값의 손실이 없다
축소 변환
데이터 타입보다 더 작은 타입으로 메모리 공간이 축소되기 때문에, 값의 손실이 생김
데이터 변환 방법
데이터 손실이 생기는 축소 변환에만 casting 필요
ex) int a = (int)10.2F;
boolean을 제외한 7가지 기본형 간에는 서로간의 형변환이 가능
참조형
기본형을 제외한 나머지 타입. String , StringBuffer ,List등 혹은 개인이 만든 클래스도 참조형 타입이 가능
참조 값(주소)를 가지는 자료형
자바 API에서 제공되거나 프로그래머에 의해서만들어진 클래스를 자료형으로 선언하는 경우
참조변수는 클래스 이름을 가지고 만들 수있다. (Member mem;) ==> 변수의 타입이 기본형이 아닌것들은 모두 참조 변수
힙과 스택의 저장되는 메모리 차이
위의 사이트서 자세하게 다루고있다.
== 과 Equals()의 차이점
1) 형태의 차이
우선 가장 단순한 차이점은 형태의 차이이다
equals()는 메소드이다 --> 객체끼리 내용을 비교할 수 있도록 한다.
== 는 비교를 위한 연산자 이다.
equlas 메소드는 비교하고자 하는 대상의 내용 자체를 비교하지만
== 연산자는 비교하고자 하는 대상의 주소값을 비교한다.
String a = "bbb";
String b = a;
String c = new String("bbb");
위 코드에서 보면 변수 b는 a를참조하고있어서 둘다 bbb를 가지고있다. 또한 변수 c도 문자열을 선언하여 bbb를 가지고있다.
변수 b는 a를 참조하고있어서 a의 주소값과 b의 주소값이 같고 c의 경우 문자열을 새로 선언해주었기 때문에 새로운 주소값을 할당받게되어 a,b 의 주소값가 다른 주소값을 가지게 된다.
여기서 ==연산자의 경우 a==b 의 경우 주소값이 같으므로 true를 반환하지만 a==c or b==c의경우 주소값이 다르므로 false를 반환한다.
equals()메소드라면 어떨까?
equals()메소드는 비교하는 대상자체 즉 변수의 value값을 통해서 비교한다고 위에 표기해두었다. 이걸 생각하면 a.equlas(b) 는 당연하게 true를 반환한다. 그리고 a.equlas(c)와 a.equlas(b)의 경우도 둘다 value값은 bbb로 동일하기때문에 true를 반환하게 된다.
결론
==연산자는 Call By Reference (대상을 선언했을 때 ,주소값 부여) 에 따라서 해당 객체나 변수의 주소값을 통한 비교
equals()메소드는 Call By Value(기본적으로 대상에 주소값을 가지지 않는 것으로 값을 할당 받는 형태)에 따라 해당 변수에 value값 자체를 비교하며 boolean값을 반환한다.
개발자가 자신만의 version history를 가질 수 없다. (local history를 사용하지만 일시적, 내가 몇일전 까지 했던 작업 내역을 확인 가능하지만 버전관리가 되지 않는다.)
프로젝트 소스는SVN서버의Trunk라는 곳에 위치->자신의Local에Trunk의 소스를 다운 받아(update)수정 및 추가 후 다시 업로드(commit)하는 방식자신만의 소스를 다른 개발자들과 떨어져서 작업하려면Branch(원 소스의 나뭇가지)를 만들어 작업 후 자기자신만 접근하여 개발하며 완성되면Merge기능을 사용하여Trunk와 소스를 합치면 된다
SVN최대 장점은 직관적이다. 하지만 두 사람이 하나의 파일을 동시에 수정하고 커밋하였을 때 충돌이 일어날 확률이 높아진다.
1-2.GIT
-소스코드의 효율적인 관리를 위한 형상 관리 도구
-매우 빠른 속도의 분산형 저장소. SVN보다 많은 기능을 지원하는 대신 익숙해지는데 더많은 시간이 필요함.
-여러명이 동시에 작업하는 병렬 개발이 가능함
-소스를 최신으로 유지하면서 개발자들이 원하는 때에 원하는 만큼 수정이 가능
git은 개발자가 자신만의 commit history를 가질 수 있고, 개발자와 서버의 저장소는 독립적으로 관리가 가능하다.
commit한 내용에 실수가 있더라고 바로 서버에 영향을 미치지 않는다.
모든 작업이 로컬에서 이루어지고 네트워크 사용은 원격 저장소로 저장할 때 한번이므로 개발시 처리속도가 빠르다.
원격저장소의 내용이 로컬 저장소에 저장되어 있으므로 중앙 저장소에 에러가 생기면 모든 작업이 마비되는 SVN과는 다르게 원격저장소에 에러가 생겨도 로컬에서 복구하기 용이하고, 히스토리 관리가 잘 제공되어 있어 히스토리 관리가 용이하다.
로컬pc에서 작업내용으로 Commit하여 로컬 저장소에서 반영후 -> 원격저장소에서 fetch로 로컬저장소로 마스터 파일을 받아온후 -> 충돌이 나지않게 merge를 이용하여 합친다음 -> 나의 로컬 저장소 내용을 Push 하여 원격 저장소에 올려 다른 사람들에게 나의 작업내용을 공유한다.
2. Git의 Merge와 Rebase의 차이
Merge 장점
이해하기쉽다, 원래 브랜치의 컨텍스트를 유치한다. Fast-Forward Merge를 하지 않는다면 브랜치 별로 커밋을 분리해 유지한다. 이러한 기능은 브랜치에 유용하다.
원래 브랜치의 커밋들은 변경되지 않고 계속 유지되어 다른 개발자들의 작업과 공유되는 것에 대해 신경쓸 필요가없다.
Merge 단점
단순히 모든 사람들이 같은 브랜치에서 작업하기 때문에 merge해야할 때는 merge가 커밋 히스토리상으로 전혀 유용하지 않고 어지럽기만 하다.
Rebase 장점
단순한 히스토리
여러 개발자들이 같은 브랜치를 공유할 때 커밋을 합치는 가장 직관적이고 깔끔한 방법.
Rease 단점
충돌 상황에서 다소복잡. 커밋 순서대로 Rebase를 하는데, 각 커밋마다 충돌해소를 순서대로 해주어야 한다.
해당 커밋들을 다른 곳에 푸시한 적이 있다면 히스토리를 다시 쓰는것에 부작용이 발생한다.
Git에서는 Push할 수 있으나 당신이 혼자 쓰는 리모트 브랜치 에서만 가능하다.
결론
1.여러 개발자들이 같은 브랜치를 공유 할 때는 Pull&Rebase가 히스토리를 깔끔하게 유지하는데 좋음.
2. 완료된 기능 브랜치를 다시 합칠 때는 Merge를 사용.
Remote 와 Local 에 동시에 존재하는 브랜치를 Pull 할 때에는 Rebase 를 사용하도록 한다.
기능 브랜치에 대해서는 Merge 를 사용, Rebase 와 비슷한 동작을 하게되는 Fast-Forward Merge 를 사용하지 않는다.
기능 브랜치에 그 부모 브랜치의 내용을 합칠 때는 로컬 브랜치일 때만 Rebase 로 합침.
package com.example.test;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="testdb") //디비이름써줌
public class MemberDB {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 이 Annotation을 붙여주면 해당 변수를 PrimaryKey로 인식한다.
private Long id;
private String name;
private String zipcode;
private String email;
private String active;
public MemberDB(Long id, String name, String zipcode, String email, String active) {
super();
this.id = id;
this.name = name;
this.zipcode = zipcode;
this.email = email;
this.active = active;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
@Override
public String toString() {
return "MemberDB [id=" + id + ", name=" + name + ", zipcode=" + zipcode + ", email=" + email + ", active="
+ active + "]";
}
}
jdbc템플릿을 이용하기 위해 member VO의 생성자 유무가 중요하다.
CrudRepository I.O를 상속받아 사용하면 생성자는 protect 생성자이름(){};
만 지정해줘도 자동으로 객체를 할당해준다.
위의 @Id,@Entitiy,@table 등의 어노테이션은 이프로젝트는 JPA를 사용하지 않았기에 빼도 아무상관이없다.
package com.example.test;
import java.util.List;
import org.springframework.stereotype.Repository;
@Repository
public interface MemberRepository{
List<MemberDB> findAll();
int save(MemberDB member);
int update(MemberDB member);
int DeleteById(Long id);
List<MemberDB> findById(Long id);
}
레포지터리 인터페이스
package com.example.test.JDBC;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import com.example.test.MemberDB;
import com.example.test.MemberRepository;
@Repository
public class JDBCMemberRepository implements MemberRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<MemberDB> findAll() {
// TODO Auto-generated method stub
return jdbcTemplate.query("select * from testdb where active ='TRUE' order by id",(rs,rowNum) -> new MemberDB(
rs.getLong("id"),
rs.getString("name"),
rs.getString("zipcode"),
rs.getString("email"),
rs.getString("active")
));
}
@Override
public int save(MemberDB member) {
return jdbcTemplate.update("insert into testdb values(?,?,?,?,default)",
member.getId(),member.getName(),member.getZipcode(),member.getEmail());
}
@Override
public int update(MemberDB member) {
// TODO Auto-generated method stub
return jdbcTemplate.update("update testdb set name = ? where id= ? ",
member.getName(),member.getId()
);
}
@Override
public int DeleteById(Long id) {
// TODO Auto-generated method stub
return jdbcTemplate.update("update testdb set active = 'FALSE' where id = ?",
id
);
}
@Override
public List<MemberDB> findById(Long id,String name) {
return jdbcTemplate.query("select * from testdb where id =? or name like ?", new Object[] {id,"%"+name+"%"},(rs,rowNum) ->
new MemberDB(
rs.getLong("id"),
rs.getString("name"),
rs.getString("zipcode"),
rs.getString("email"),
rs.getString("active")
));
}
}
JDBC레포지터리 코드
스프링 부트서 레포지터리를사용시 반드시 @Repository를 어노테이션해줘야하는걸 잊지말자.