Các phương thức thường dùng của Session trong Hibernate

Vòng đời của Hibernate

Trong Hibernate một đối tượng có thể thuộc 3 trạng thái:

Transient: Đối tượng không có quan hệ với Session hiện tại của Hibernate.

Persistent: Đối tượng có quan hệ với Session hiện tại của Hibernate và trạng thái của nó được đồng bộ với cơ sở dữ liêu

Detache: Đối tượng đã từng có trạng thái persistent nhưng hiện tại đã không còn giữ quan hệ với Session.

Ở đây chúng ta nói một đối tượng có quan hệ với Session nghĩa là Session có tham chiếu đến đối tượng đó, hay một cách khác là chịu sự quản lý của Session (dùng tiếng Việt giải nghĩa kỹ thuật khó kinh khủng).

  • save() dùng để lưu một đối tượng với trạng thái transient thành đối tượng persistent, trả về id persist() giống save nhưng không trả về gì cả.
  • saveOrUpdate() nếu là đối tượng mới thì lưu xuống db, nếu không thì update xuống db, cái này sẽ select để kiểm tra trước khi save hoặc update
  • merge() kiểm tra xem có đối tương nào với id như thế tồn tại trong session không, nếu có thì update vào đối tượng đã tồn tại đó, nếu không thì tạo mới một đối tượng và save xuống
  • load() dùng để load một đối tượng từ database lên, nó sẽ có trạng thái persistent, throw exception nếu id không tồn tại
  • get() giống load(), trả về null nếu không tồn tại
  • refresh() refresh một đối tượng đang ở trạng thái persistent
  • delete() load đối tượng lên và xoá nó đi, nếu không muốn load lên thì dùng session.createQuery(“delete from user where …”).executeUpdate()
  • evict() tách một đối tượng ra khỏi session, biến nó từ trạng thái persistent thành transient
  • isDirty() kiểm tra xem session có sync với db không

Chú ý sự khác nhau giữa saveOrUpdate và merge
saveOrUpdate()
-Nếu đối tượng đã được persistent thì không làm gì cả
-Nếu có đối tượng khác được persistent với cùng id thì throw exception
-Nếu đối tượng không có id hoặc có id mới thì gọi save
-Trường hợp khác thì update (có id đã có trong db nhưng chưa được persistent)
merge()
-Nếu có đối tượng trong session với cùng id thì cập nhật giá trị từ thằng ngoài vào. Như vậy thằng ngoài vẫn detach.
-Nếu trong session không có đối tượng vào với cùng id như thế thì load lên từ db. Nếu load lên không có thì tạo đối tượng mới. Xong rồi cập nhật dữ liệu từ thằng ngoài vào thằng trong session.
-Đối tượng trả về ở trạng thái detach

Khác nhau giữa Struts 1 và Struts 2 phần 1

Trong bài viết dưới đây chúng ta sẽ cùng nhau so sánh những đặc tính quan trọng của Struts 2 so với Struts 1:

1. Phụ thuộc vào Servlet API
Các Action trong Struts 1 bị phụ thuộc vào servlet API bởi vì các đối tượng HttpServletRequest và HttpServletResponse được truyền vào phương thức execute của Action khi Action được thực thi. Trong trường hợp của Struts 2, Action chỉ là một class bình thường và chúng ta không cần truyền đối tượng HttpServletRequest và HttpServletResponse cho phương thức execute.

Do Struts 2 không phụ thuộc vào API của servlet nên chúng ta có thể dễ dàng test các Action mà không cần chạy chúng trong web container. Mặc dù vậy các Action của Struts 2 vẫn có cách để truy cập đến các đối tượng request và response khi cần.

2. Các lớp Action
Tư tưởng lập trình dựa trên việc extends từ class có sẵn chứ không phải dựa vào việc sử dụng interface chính là nhược điểm của Struts 1.
Action của Struts 1 được quy định phải extends một lớp abstract của Struts 1, trong khi đó trong Struts 2 Action của bạn có thể là bất kỳ một lớp Java nào.
Struts 2 cũng cung cấp một interface chung cho các Action là interface ActionSupport, tuy vậy việc implement interface này không bắt buộc.

3. Validate dữ liệu
Struts1 and Struts 2 both supports the manual validation via a validate method.
Cả Struts 1 và 2 đều hỗ trợ validate dữ liệu thông qua phương thức validate.
Struts 1 sử dụng phương thức validate dữ liệu trong class ActionForm, hoặc validate dựa vào thành phần mở rộng Common Validator. Struts 2 hỗ trợ validate bằng phương thức validate và sử dụng XWork Validation. XWORK Validation hỗ trợ việc validate dữ liệu bằng việc kết hợp một chuỗi các bộ validate và validate dữ liệu dựa vào kiểu của thuộc tính và ngữ cảnh.

Ví dụ đọc dữ liệu từ file text có cấu trúc.

E viết chương trình đổi tiền, muốn class program của mình nhận vào một bảng tỷ giá là file .txt. nhưng ko biết làm sao duyệt qua từng phần tử trong bảng tỷ giá. Em định dùng List để chứa bảng tỷ giá này. Trong lớp tỷ giá có ngoại tệ (String), tỷ giá mua(double), tỷ giá bán(double). Và bảng tỷ giá là một danh sách các tỷ giá. Mong các anh chị giúp dùm.

Đầu tiên bạn lưu tỷ giá vào một file rates.txt có nội dung như sau:

USD,17000,16800
EURO,27000,26500

Chúng ta sử dụng đối tượng Rate để lưu thông tin về mỗi tỷ giá:

/**
* Rate class to store rate's informations
*
* @author cuonglm
*
*/
class Rate {
private String name;

private int buy;

private int sell;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getBuy() {
return buy;
}

public void setBuy(int buy) {
this.buy = buy;
}

public int getSell() {
return sell;
}

public void setSell(int sell) {
this.sell = sell;
}

@Override
public boolean equals(Object obj) {
if (obj == null && !(obj instanceof Rate))
return false;
Rate rate = (Rate) obj;
if (name != null && name.equals(rate.getName()) && buy == rate.getBuy()
&& sell == rate.getSell())
return true;
return false;
}

@Override
public int hashCode() {
return super.hashCode();
}

@Override
public String toString() {
return "Rate " + name + "(" + buy + "," + sell + ");";
}

}

Sau đó chúng ta viết lớp Demo để đọc file rates.txt với các yêu cầu sau:
+ Danh sách các đối tượng Rate được lưu vào Set để không có tỷ giá nào trùng nhau.
+ Bất cứ lỗi IO nào sẽ ngừng chương trình ngay lập tức.
+ Nếu một dòng có định dạng không đúng thì bỏ qua và đọc dòng tiếp theo

public class Demo {
private static final String RATE_FILE = "rates.txt";

@SuppressWarnings("unchecked")
public static void main(String args[]) {
try {
// Array list to store all rates
Set rates = new HashSet();
String tempStr = null;
BufferedReader br = null;

// Try to read file with BufferedReader
br = new BufferedReader(new FileReader(RATE_FILE));

Rate rate = null;
StringTokenizer st = null;
// Read each line and create Rate object
while ((tempStr = br.readLine()) != null) {
st = new StringTokenizer(tempStr, ",");
if (st.countTokens() == 3) {
try {
rate = new Rate();
rate.setName(st.nextToken());
rate.setBuy(Integer.valueOf(st.nextToken()));
rate.setSell(Integer.valueOf(st.nextToken()));
rates.add(rate);
} catch (Exception e) {
continue;
}

}
}

for (Rate rt : rates) {
System.out.println(rt);
}
} catch (FileNotFoundException e) {
System.out.println("Rate file not found!");
} catch (IOException e) {
System.out.println("Error while read rate data: " + e.getMessage());
}
}
}

Tớ chưa test tất cả các case nên có thể có bug nhưng về cơ bản là thế.

Bỏ qua việc kiểm tra null pointer

Edited : nhầm tên phương thức nên không rõ nghĩa.

Thường trong khi lập trình bạn không tránh khỏi có lúc quên không kiểm tra xem đối tượng có null không. Thế nên chúng ta sẽ tìm cách viết code thế nào để quên không kiểm tra mà vẫn không bị lỗi NullPointerException.

Ví dụ code xấu:

private boolean isEmptyString(String string) {
return (string.equals(""));
}

Như bạn thấy nếu ta gọi isNullString(null); thì phương thức trên sẽ tung ra exception.

Ví dụ code ngon:

private boolean isEmptyString(String string) {
return ("".equals(string));
}

Bây giờ ta có gọi isNullString(null) thì return (“”.equals(null)) sẽ trả về false mà không bị Exception.

Truy cập file resource, file ảnh trong file jar

File jar thường được dùng để triển khai ứng dụng. Trong file jar thường có các class java và các file khác như file ảnh, properties … Để truy cập một file trong file jar chúng ta sử dụng phương thức getResource. Đoạn code sau đây sẽ đọc 2 file ảnh từ trong file jar ra thành đối tượng Icon

// Get current classloader
ClassLoader cl = this.getClass().getClassLoader();
// Create icons
Icon saveIcon = new ImageIcon(cl.getResource("images/save.gif"));
Icon cutIcon = new ImageIcon(cl.getResource("images/cut.gif"));

Sắp xếp các đối tượng sử dụng phương thức Collection.sort

Lập trình viên thường phải sắp xếp một tập hợp các dữ liệu đầu vào. Java đã có sẵn một tập hợp các API cho việc sắp xếp. Trong java, khi chúng ta muốn so sánh nhiều đối tượng thuộc một class thì class đó cần phải thi hành interface Comparable. Các lớp sẵn có của java như Integer, Date cũng thi hành interface này, dó đó những dối tượng thuộc những lớp trên có thể dễ dàng được sắp xếp dựa vào phương thức Collection.sort. Chúng ta cũng có thể thi hành interfaceComparable để các đối tượng của class đó có thể sắp xếp bằng phương thức Collection.sort

package test;
import java.util.ArrayList;

import java.util.Collections;

import java.util.Iterator;

import java.util.List;

public class ListExample {

	List list;

	public ListExample() {

		list = new ArrayList();

	}

	private List getList() {

		return list;

	}

	public static void main ( String [] args ) {

		ListExample lExam = new ListExample();

		List tempList = lExam.getList();

		tempList.add(new Car(2));

		tempList.add(new Car(3));

		tempList.add(new Car(1));

		tempList.add(new Car(6));

		Collections.sort(tempList);

		Iterator iterator = lExam.getList().iterator();

		while (iterator.hasNext()) {

			System.out.println(((Car)iterator.next()).getCapacity());

		}

	}

}
package test;class Car implements Comparable{

	int capacity;public Car(int c){

		this.capacity=c;

	}

	public int compareTo(Object o) {

		int thisVal = this.capacity;

		int anotherVal = ((Car)o).capacity;

		return (thisVal<anotherval (thisval="=anotherVal">
		</anotherval>
	}

	public int getCapacity(){

		return capacity;

	}

}

Output :

	1

	2

	3

	6

(java-tips)

Hiển thị ngày tháng trong java

Lớp java.text.DateFormat rất hữu dụng dùng để hiển thị ngày tháng với những định dạng khác nhau. Ví dụ sau đây sẽ trình bày cho bạn thấy những kiểu hiển thị khác nhau của dữ liệu ngày tháng:

Date now = new Date();
DateFormat df =  DateFormat.getDateInstance();
DateFormat df1 = DateFormat.getDateInstance(DateFormat.SHORT);
DateFormat df2 = DateFormat.getDateInstance(DateFormat.MEDIUM);
DateFormat df3 = DateFormat.getDateInstance(DateFormat.LONG);
DateFormat df4 = DateFormat.getDateInstance(DateFormat.FULL);
String s =  df.format(now);
String s1 = df1.format(now);
String s2 = df2.format(now);
String s3 = df3.format(now);
String s4 = df4.format(now);
System.out.println("(Default) Today is " + s);
System.out.println("(SHORT)   Today is " + s1);
System.out.println("(MEDIUM)  Today is " + s2);
System.out.println("(LONG)    Today is " + s3);
System.out.println("(FULL)    Today is " + s4);

Output:

(Default) Today is 04.06.2008
(SHORT) Today is 04.06.08
(MEDIUM) Today is 04.06.2008
(LONG) Today is 4. June 2008
(FULL) Today is Friday, 6. June2008

Đọc 1 file ảnh trong java

Bạn có thể đọc file ảnh gif, jpeg và png sử dụng phương thức tĩnh của đối tượng Toolkit:

Image i = Toolkit.getDefaultToolkit().getImage("car.png");

Mặc dù vậy, phương thức trên sử dụng kỹ thuật lazy load cho nên nội dung của bức ảnh chỉ được bắt đầu đọc khi bạn muốn hiển thị bức ảnh đó. Để đọc nội dung bức ảnh ngay lập tức bạn có thể sử dụng phương thức khởi tạo của đối tương ImageIcon, khi gọi phương thức này bạn sẽ chờ cho đến khi toàn bộ dữ liệu của bức ảnh được nạp vào bộ nhớ:

Image i = new javax.swing.ImageIcon("car.png").getImage();

Annotation @Override trong java 6

Phiên bản java cung cấp sẵn nhiều annotation, một trong số đó là @Override. @Override được dùng đối với một phương thức để xác định rằng phương thức đó ghi đè (override) một phương thức của lớp cha. Ví dụ như sau:

package com.domian.a.test;

public class OverrideTester {

  public OverrideTester() { }

  @Override
  public String toString() {
    return super.toString() + " [Override Tester Implementation]";
  }

  @Override
  public int hashCode() {
    return toString().hashCode();
  }
}

Trong ví dụ trên, @Override được dùng đối với hai phương thức toString() và hashCode() để cho biết rằng những phương thức đó là phương thức ghi đè lên phương thức của lớp cha java.lang.Object

(Java tips blog)