트랜잭션 - 일을 처리할 때의  최소 단위(송금)

서비스 - 트랜잭션을 포함한 관련된 로직들이 묶여 있는 것(송금 후 잘들어갔는지 리턴하여 메시지를 띄우는 등)

ex)기능: 입금(서비스)
1 update()

1이 트랜잭션
ex)기능: 송금(서비스)
1 update() 나의 돈을 줄인다
2 update() 상대방의 돈을 늘인다

1~2가 트랜잭션

 

하나의 트랜잭션이 끝나면 롤백을 하거나 커밋을 해야한다.

데이터베이스에 변경이 일어나는 것(dml) - UPDATE, INSERT, DELETE 이 묶여있다면 트랜잭션이다.

 

ex)기능: 입금(서비스)
1 update() - 트랜잭션

2-1 업데이트가 실패했을 경우 메시지를 띄운다
2-2 업데이트가 성공했을 경우 성공관련 창을 띄운다

 

위의 모든 내용을 완수하면 서비스가 된다

테이블이 나오면 테이블에 대한 모델을 만들어야하고,

모델에 대한 DAO(데이터 엑세스 오브젝트)를 만들어 줘야한다.

롬복을 설치한 후

 

아래와 같은 생성자로 new를 하려면 값의 순서가 햇갈릴 수가 있다.

이런걸 방지하기위한 방법 중 하나가 빌더 패턴이다.

 

메인 프레임에서 데이터를 넣는 부분을 아래와 같이 만들어보자.

 

아래와 같이 잘 나온다.

 

모든 경우의 수의 생성자를 사용할 수 있다.

즉, 생성자에 필요한 데이터를 몇가지 빼먹어도 인스턴스가 생성된다

* 다만 기본생성자가 필요하다면 그것은 직접 만들어 줘야한다

 

빌더패턴에 대해 더 알아보기

https://johngrib.github.io/wiki/builder-pattern/#%EB%B9%8C%EB%8D%94-%ED%8C%A8%ED%84%B4effective-java-%EC%8A%A4%ED%83%80%EC%9D%BC

 

빌더 패턴(Builder Pattern)

객체의 생성 방법과 표현 방법을 분리한다

johngrib.github.io

 

필수인자를 세팅하는법.

개요

 

 

*설계할때에는 먼저 테이블을 만들어야하는데 최근에는 자바에서 클래스로 모델을 먼저 만드는 경우도 있다고 한다.

*모델마다 dao가 필요하다는 점 꼭 참고하자

 

 

그룹을 스트링으로하면 도메인설정이 되지 않는다.

아래에서 enum으로 설정하는 법을 알아보자.

 

 

enum을 쓰면 강제성이 생긴다.

 

타입을 지정해버리면 다른 타입을 넣을 수 없다.

 

group타입을 이넘으로 바꾸자

 

싱글톤으로 MemberDao 제작

 

빌드패스

 

 

테스트를 위한 내부라이브러리 빌드패스

 

JUnit은 일부 메서드를 테스트하기위한 기능이다.

 

일단 4번을 쓰자

 

스태틱이면 안되고 void여야한다고 에러가남(참고만하자)

 

테스트 파일을 하나 만들어서 아까 것을 테스트 해본다.

 

 

정상이면 빨강이다.

 

 

DBUtils에는 DB에 필요한 부가기능들을 넣자

 

gui

package address.gui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import address.model.GroupType;
import address.model.Member;

public class MainFrame extends JFrame {
	
	
	private JFrame mainFrame = this;
	
	private Container backgroundPanel;
	
	private JPanel topPanel, menuPanel, listPanel;
	
	private JButton homeButton, frButton, coButton, scButton, faButton, addButton;
	
	private JList<Member> userList;
	
	private DefaultListModel<Member> listModel; // Jlist에 이것을 넣어야 한다.
	
	private JScrollPane jsPane;
	
	public MainFrame() {
		initObject();
		initData();
		initDesign();
		initListener();
		setVisible(true);
	}
	
	// new
	private void initObject() {
		backgroundPanel = getContentPane();
		
		topPanel = new JPanel();
		menuPanel = new JPanel();
		listPanel = new JPanel();
		
		homeButton = new JButton("주소록 전체");
		frButton = new JButton("친구");
		coButton = new JButton("회사");
		scButton = new JButton("학교");
		faButton = new JButton("가족");
		addButton = new JButton("추가");
		
		listModel = new DefaultListModel<>();
		userList = new JList<>(listModel);
		
		jsPane = new JScrollPane(userList); // 뒤의 패널색깔을 유지하려면 그냥 ScrollPane을 이용하자
	}
	
	// 데이터 초기화
	private void initData() {
		for (int i = 1; i < 31; i++) {
			listModel.addElement(new Member(i, "홍길동", "0102222", "부산시", GroupType.친구));
		}
	}
	
	// 디자인
	private void initDesign() {
		// 1. 기본세팅
		setTitle("주소록 메인");
		setSize(400, 500);
		setLocationRelativeTo(null); // 모니터 중앙에 배치
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		// 2. 패널세팅
		backgroundPanel.setLayout(new BorderLayout());
		topPanel.setLayout(new GridLayout(2,1));
		menuPanel.setLayout(new GridLayout(1,4));
		listPanel.setLayout(new BorderLayout());
		
		// 3. 디자인
		userList.setFixedCellHeight(50); // 리스트각각의 높이
		topPanel.setPreferredSize(new Dimension(0, 100)); // 그리드레이아웃이라 가로를 0으로해도 자동으로 꽉차게된다.
		
		// 4. 패널에 컴포넌트 추가
		menuPanel.add(frButton);
		menuPanel.add(coButton);
		menuPanel.add(scButton);
		menuPanel.add(faButton);
		
		listPanel.add(jsPane);
		
		topPanel.add(homeButton);
		topPanel.add(menuPanel);
		
		backgroundPanel.add(topPanel, BorderLayout.NORTH);
		backgroundPanel.add(listPanel, BorderLayout.CENTER);
		backgroundPanel.add(addButton, BorderLayout.SOUTH);
	}
	
	// 리스너 등록
	private void initListener() {
		
	}
}

 

 

카드레이아웃의 기본은 아래 블로그에서 이해하자

https://m.blog.naver.com/PostView.nhn?blogId=shimchan2&logNo=70108791279&proxyReferer=https:%2F%2Fwww.google.com%2F

 

자바 GUI - CardLayout

import java.awt.*; import java.awt.event.*; public class CardLayoutTest {  /** * 카드레이아웃 이용...

blog.naver.com

 

이 글에서는 카드레이아웃과 그것을 사용한 리스너 컨트롤에 대해서 설명할 것이다.

 

기본 프레임 제작은 windowBuider를 사용하였으니 참고하자.

모든 파일은 따로 만들었다.

아래에 파일이 있으니 참고로 사용하자.

listenAdapter.java
0.00MB
CookieRun.java
0.00MB
IntroPanel.java
0.00MB
LoginPanel.java
0.00MB

 

 

리스너 어댑터 파일

리스너 어댑터는 필요없는 리스너들을 쓰지 않을 수 있도록 하는 중간 다리 역할이다.

키리스너 마우스리스너 액션리스너 인터페이스를 받아서 어댑터를 만들었다.

 

인트로 패널 파일

다른 파일로 만든 인트로 클래스이다.

이미지를 그리는 기능 밖에 없다.

 

로그인패널 파일

더보기를 눌러 로그인패널 코드 확인

더보기
package Test5;

import java.awt.AlphaComposite;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

public class LoginPanel extends JPanel {
	
	JLabel idLabel;
	JLabel pwLabel;
	
	JTextField idField;
	JPasswordField pwField;
	
	JButton loginBtn;
	JButton signBtn;
	
	ImageIcon loginIc = new ImageIcon("img/out/intro.png");
	private AlphaComposite alphaComposite;
	
	public LoginPanel(Object o) {
		idLabel = new JLabel("ID : ");
		Font f1 = new Font("Arial", Font.PLAIN, 20);
		idLabel.setFont(f1);
		idLabel.setBounds(550, 50, 100, 20);
		add(idLabel);
		
		pwLabel = new JLabel("PW : ");
		pwLabel.setFont(f1);
		pwLabel.setBounds(550, 80, 100, 20);
		add(pwLabel);
		
		idField = new JTextField();
		idField.setBounds(650, 50, 110, 20);
		add(idField);
		
		pwField = new JPasswordField();
		pwField.setBounds(650, 80, 110, 20);
		add(pwField);
		
		loginBtn = new JButton("login");
		loginBtn.setName("loginBtn");
		loginBtn.addMouseListener((MouseListener)o);
		loginBtn.setBounds(660, 110, 100, 20);
		add(loginBtn);
		
		signBtn = new JButton("sign");
		signBtn.setName("signBtn");
		signBtn.setBounds(550, 110, 100, 20);
		signBtn.addMouseListener((MouseListener)o);
		add(signBtn);
	}
	
	public String getId(){
		return idField.getText();
	}
	
	public String getPw(){
		return pwField.getText();
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D)g;
		
		alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)100/255);
		g2.setComposite(alphaComposite);
		
		g.drawImage(loginIc.getImage(), -60, 0,/* this.getWidth(), this.getHeight(),*/ null);
		
		alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)255/255);
		g2.setComposite(alphaComposite);
		
	}
}

 

코드가 길어보이지만 크게 어려울 것은 없다.

라벨 2개

텍스트필드, 패스워드필드 하나씩

버튼 2개 선언

생성자에서 각 컴포넌트를 생성하고 위치를 정해주고 추가한다.

생성자가 Object 매개변수를 받는데,

메인 클래스가 리스너 역할을 하기 때문에 메인에서 자기자신을 로그인패널에 넣어주면

리스너를 이용할 수 있기 때문이다.

지금 이해가 바로 안되더라도 계속 진행해보자.

아이디와 패스워드를 리턴하는 메서드를 생성

 

 

메인 클래스 파일

메인클래스는 맨위에서 만들어둔 listenAdapter를 상속받는다.

그리고 전역공간에 각종 패널들의 레퍼런스만 선언해두고,

카드레이아웃 레퍼런스도 선언해두자.

 

 

초기화 메서드

초기화 메서드에서 카드레이아웃 레퍼런스(cl)에  카드레이아웃 객체를 연결하고

프레임의 레이아웃을 카드로 변경한다.

로그인패널에서 Object를 매개변수로 받았다는 점을 기억할 것이다.

위 사진을보면 LoginPanel생성자 뒤에 this를 넘겨준다.

this는 이 메인클래스 자체를 의미하며, 메인클래스는 리스너를 상속받고 있으니 리스너 역할을 하게된다.

인트로패널에 마우스리스너를 넣어주자. 마찬가지로 this를 넘겨준다.

카드레이아웃은 컨텐트페인에 여러개의 패널을 추가할 수 있다.

만들어둔 패널들을 모두 추가하자. 추가할 시 이름을 정해줘야한다.

마지막으로 리스너 내용들이다.

메인 클래스는 리스너를 상속받았기때문에 클래스 내부에 리스너들을 넣을 수 있다.

인트로 패널에서 사용될 기능이다.

화면을 누르면 로그인페이지로 넘어가도록 하였다.

 

+ Recent posts