Kinopyo Blog

プログラマとしてRuby, Rails, iPhone, iPad,Macなどなどと向き合う日々のログポース

Posts Tagged ‘Java’

Spring DataSource beanのメモ

2010年12月06日

DataSource Beanを定義する際applicationContext.xmlの書き方と、Javaで呼び出すコードのメモです。ずいぶん昔のメモです。。

こんなjdbc.propertiesファイルがクラスパスにあるとします。

jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:~/test
jdbc.username=sa
jdbc.password=

そしてSpringのapplicationContext.xmlにはこう書きます。

<context:property-placeholder location="jdbc.properties"/>

<bean id="dataSource"
	class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	<property name="driverClassName" value="${jdbc.driverClassName}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<property name="password" value="${jdbc.password}" />
</bean>

<bean id="accountDao" class="test.dao.AccountDao">
	<property name="dataSource" ref="dataSource" />
</bean>

Javaでの呼び出し:

ApplicationContext context = new ClassPathXmlApplicationContext(
		"applicationContext.xml");

AccountDao accountDao = (AccountDao) context.getBean("accountDao");

// other code...

Hibernate:複数項目のPKに対応するアノテーションの記述方法

2010年12月03日

一つ以上の項目がPKとなったケースでHibernateはどう設定すればいいのかを説明します。

ずいぶん昔のメモになります。

こんなテーブルがあるとします。

create table Account (
	code varchar(255) not null,
	number integer not null,
	description varchar(255),
	primary key (code, number)
);

PKは’code’と’number’です。

方法は三つあります

まずPKを表すクラスを作ります。PKクラスは以下の条件を満足しなければなりません。

  1. publicクラス
  2. デフォルトのコンストラクタ
  3. シリアライズを実装
  4. hashCode()とequals()を実装

そしてエンティティクラスは以下の三つの方法のうちどれかで実装します。

  • PKクラスを@Embeddableアノテーションで記述し、エンティティクラスのプロパティとして書いて@Idとマーク
  • PKクラスをエンティティクラスにプロパティとして書いて@EmbeddableIdとマーク
  • PKを表す全ての項目をエンティティクラスのプロパティとして登録し@Idとマーク

それぞれのソースコードをリストします。

一番目@Embeddable

ここはAccountとそのPKを表すクラスAccountPkを作成しました。

メリットはPKクラスを再利用できるところです。

もっとも自然的なアプローチだそうです。


package sample.annotations;

import java.io.Serializable;

import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Account {
	private String description;
	private AccountPk id;

	public Account(String description) {
		this.description = description;
	}

	protected Account() {
	}

	@Id
	public AccountPk getId() {
		return this.id;
	}

	public String getDescription() {
		return this.description;
	}

	public void setId(AccountPk id) {
		this.id = id;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	@Embeddable
	public static class AccountPk implements Serializable{
		private String code;
		private Integer number;

		public AccountPk() {
		}

		public String getCode() {
			return this.code;
		}

		public Integer getNumber() {
			return this.number;
		}

		public void setNumber(Integer number) {
			this.number = number;
		}

		public void setCode(String code) {
			this.code = code;
		}

		public int hashCode() {
			int hashCode = 0;
			if (code != null)
				hashCode ^= code.hashCode();
			if (number != null)
				hashCode ^= number.hashCode();
			return hashCode;
		}

		public boolean equals(Object obj) {
			if (!(obj instanceof AccountPk))
				return false;
			AccountPk target = (AccountPk) obj;
			return ((this.code == null) ? (target.code == null) : this.code
					.equals(target.code))
					&& ((this.number == null) ? (target.number == null)
							: this.number.equals(target.number));
		}
	}
}

検証するクラスを作成しました。

package sample.annotations;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import sample.annotations.Account.AccountPk;

public class TestAccount {
	public static void main(String[] args) {
		SessionFactory sessionFactory = new AnnotationConfiguration()
				.configure().buildSessionFactory();
		Session session = sessionFactory.openSession();
		session.beginTransaction();

		Account account = new Account("This is the first type.");

		// construct pk value
		AccountPk accountPk = new AccountPk();
		accountPk.setCode("kinopyo001");
		accountPk.setNumber(12345);
		// set pk
		account.setId(accountPk);

		// save
		session.save(account);
		session.getTransaction().commit();
		System.out.println("Commit");

		// load
		List list = session.createQuery("from Account").list();
		Iterator i = list.iterator();
		while (i.hasNext()) {
			Account a = (Account) i.next();
			System.out.println("code: " + a.getId().getCode() + ", number: "
					+ a.getId().getNumber() + "  Description: "
					+ a.getDescription());
		}
		session.close();

	}
}

設定が正しければこんなログが出るはずです。

Commit
code: kinopyo001, number: 12345  Description: This is the first type.

二番目@EmbeddableId(抜粋)

@EmbeddedId
public AccountPk getId() {
	return this.id;
}

三番目@IdClass(抜粋)

@Entity
@IdClass(Account.AccountPk.class)
public class Account {

	private String description;
	private String code;
	private Integer number;

	public Account(String description) {
		this.description = description;
	}

	protected Account() {
	}

	@Id
	public String getCode() {
		return this.code;
	}

	@Id
	public Integer getNumber() {
		return this.number;
	}

	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public void setNumber(Integer number) {
		this.number = number;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public static class AccountPk {
	// ...
}

SpringでH2 Databaseを使う(HSQL、Derby)

2010年11月29日

Springのコンテキストファイルにjdbc:embedded-databaseタグで

type=”H2″でbeanを登録します。

jdbc:scriptタグで初期化時に実行したいSQLファイルを指定できます。

Sprintって、本当に便利ですね。

<jdbc:embedded-database id="dataSource" type="H2">
	<jdbc:script location="classpath:schema.sql"/>
	<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>

ちなみにjdbcのnamespaceの登録も忘れずに。

xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc

http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">

H2以外でもHSQL、Derbyがサポートされています。

jspにメソッドを定義するには

2010年05月06日

<&!~&>宣言部でメソッドを定義することができます。

<%!
private String myMethod (String str) {
    // some code
    return "ok";
}
%>

参考サイトはこちら:

J2EE講座 [ JSPの基本構文 ]

Java:Integer.parseInt時のNumberFormatExceptionについて

2010年04月16日

ハマっちゃったException第二弾です。

実際はハマったワケではありませんが、

一応こんなExceptionがあると。

String blank = "";

int i = Integer.parseInt(blank);

これで余裕に下記のExceptionが出ます。


java.lang.NumberFormatException: For input string: ""

何も考えずにあるJavascriptの処理をJavaに書き換える作業で発生したんです。

JavascriptはブランクをparseIntするとNaN(Not a Number)になるが、

Javaは完全におちますね。。。

Java:List操作時のUnsupportedOperationExceptionについて

久々にJavaを書いたので、表題のExceptionにハマっちゃいました。

こんなコードでした。

String[] array = {"a", "b", "c"};

List<String> list = Arrays.asList(array);

list.add("d");

ちょこっとググッてみたらasListで作ったListに

add()で要素を追加すると上記のExceptionになるそうです。

asListのJavadocでの記載は

指定された配列を基にする固定サイズのリストを返します。返されたリストへの変更は、そのまま配列に書き込まれます。(後は省略)

なるほど。。。

とりあえず深く考えずに下記のように書き換えて回避しました。

String[] array = {"a", "b", "c"};

List<String> list = new ArrayList<String>();

list.addAll(Arrays.asList(array)); 

list.add("d");

Java: Mapをnewした時に値を入れて初期化するコード

2010年03月31日

表題の通り、Mapをnewしたときに値を入れて

初期化するコード方法です。

Map<String, Integer> map = new HashMap<String, Integer>() {
    {
        put("one", 1);
    }
};

Javaの.classファイルからソースを見れるツール:Java Decompiler

2010年01月18日

Javaの.classから逆コンパイラしてもともとのソースコードが見れるツールです。

ずいぶん前一度使ったことがあります。

スタンドアロンのJD-GUIツールと、

Eclipseのプラグインとして使えるJD-Eclipseがあるらしいです。

スタンドアロンはJRE環境が必要とせずインストールだけで使えます。

jarファイルもサポートされているようです。

java-decompiler

公式サイト:JD | Java Decompiler