業務でしばしばエクセルVBAを用いたツールを作ってきた。
簡易ツールもあるが、かなり業務を遂行する上で必須となるようなツールも作ってきた。
はじめて触れたのは新人のころで実行環境と開発環境がエクセル1個で済み、
マクロの保存なんかですぐにコードが保存できる点なども勉強しやすくこれはいいと思って
食い入るように勉強したのを覚えている。
ただ、最近はVBAでツールを作成することに少し疑問を抱いてきた。(重要度が高いツールに限る)
業務上必須となるようなツール。
例えば開発ルーチンに組み込まれるようなツール。
ソースの自動生成とか。試験ツールとか。
こういったツールは、開発の状況次第でメンテナンスが頻繁に発生したりする物だと思う。
エクセルVBAをわざわざ使うということは、そのツールの扱うデータはエクセルである場合がほとんどである。
エクセルVBAはエクセルのデータを参照する場合にはとても楽で悪いところが見当たらないように思える。
だが、メンテナンスが頻繁に発生する場合に以下の観点でエクセルVBAはとても扱いづらい。
・バージョンの管理
・使用者へのアップデート通知とその徹底
・メンテナンスを行う人間の教育
上記のような理由で僕は最近VBAでツールを作成することに少し躊躇する。
これからはなるべくJavaを用いて業務ツールを作成しようと思う。
POI、VelocityをはじめJavaでも実現が可能だから。
あとVBAはOSによっていきなり参照が効かなくなったりするしね。
長々と講釈たれたなぁ。
何年後かに自分で見たら違う意見を持ってたりして恥ずかしくなるんだろうな。
2011年11月12日土曜日
2011年11月3日木曜日
MySQL5をMacにアンインストールとMacPortsで再インストール
MySqlはMacに前に入れたが、なんか入れ直したくなったので入れ直した。
まずアンインストール。
次に、MacPortsの更新確認とか行う。
とりあえずこれは馬鹿長い。
MacPortsで再インストールする。
以下のコマンドを実行しないと、MySqlが動かない。
rootのパスワードを上記メッセージないように従って、設定する。
これで再インストールは終わり。
続いて設定を行う。
MySQLの設定ファイルをテンプレートからコピーする。
編集する。
ここまでで再インストール作業は全て完了
すでにMySQLが立ち上がっているなら停止/起動を行う。
ちなみに、MySQLの文字コードが以下のようになっていることを接続した後確認すると良いです。
まずアンインストール。
# rm -rf /usr/local/mysql # rm -rf /usr/local/mysql-5.X.XXXXXXX # rm -rf /Library/StartupItems/MYSQLCOM # rm -rf /Library/PreferencePanes/MySQL.prefPane # rm -rf /Library/Receipts/mysql-XXXXXXXXXXXXXX.pkg
次に、MacPortsの更新確認とか行う。
とりあえずこれは馬鹿長い。
sudo port selfupdate sudo port upgrade outdated
MacPortsで再インストールする。
>sudo port install mysql5-server …省略… ########################################################### # A startup item has been generated that will aid in # starting mysql5-server with launchd. It is disabled # by default. Execute the following command to start it, # and to cause it to launch at startup: # # sudo port load mysql5-server ########################################################### ---> Installing mysql5-server @5.1.59_0 ****************************************************** * In order to setup the database, you might want to run * sudo -u _mysql mysql_install_db5 * if this is a new install ****************************************************** ---> Activating mysql5-server @5.1.59_0 ---> Cleaning mysql5-server
以下のコマンドを実行しないと、MySqlが動かない。
>sudo -u _mysql mysql_install_db5 …省略… PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER ! To do so, start the server, then issue the following commands: /opt/local/lib/mysql5/bin/mysqladmin -u root password 'new-password' /opt/local/lib/mysql5/bin/mysqladmin -u root -h PC名.local password 'new-password' Alternatively you can run: /opt/local/lib/mysql5/bin/mysql_secure_installation …省略…
rootのパスワードを上記メッセージないように従って、設定する。
>/opt/local/lib/mysql5/bin/mysqladmin -u root password '設定するパスワード'
これで再インストールは終わり。
続いて設定を行う。
MySQLの設定ファイルをテンプレートからコピーする。
>sudo cp /opt/local/share/mysql5/mysql/my-small.cnf /opt/local/etc/mysql5/my.cnf
編集する。
>sudo vim /opt/local/etc/mysql5/my.cnf …省略… # The MySQL server [mysqld] port = 3306 socket = /opt/local/var/run/mysql5/mysqld.sock skip-locking key_buffer_size = 16K max_allowed_packet = 1M table_open_cache = 4 sort_buffer_size = 64K read_buffer_size = 256K read_rnd_buffer_size = 256K net_buffer_length = 2K thread_stack = 128K ## OWNSETTINGS …書き加えたところ default-character-set = utf8 default-storage-engine=innodb skip-character-set-client-handshake
ここまでで再インストール作業は全て完了
すでにMySQLが立ち上がっているなら停止/起動を行う。
>sudo /opt/local/share/mysql5/mysql/mysql.server stop Shutting down MySQL ... SUCCESS! >sudo /opt/local/share/mysql5/mysql/mysql.server start Starting MySQL . SUCCESS!
ちなみに、MySQLの文字コードが以下のようになっていることを接続した後確認すると良いです。
mysql> show variables like 'char%'; +--------------------------+-----------------------------------------+ | Variable_name | Value | +--------------------------+-----------------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /opt/local/share/mysql5/mysql/charsets/ | +--------------------------+-----------------------------------------+ 8 rows in set (0.00 sec)
2011年10月15日土曜日
CassandraのCQLはスーパーカラム(SuperColumn)の存在無視なのか?
ご存知、Apache Cassandraは0.8からCQLなるものをリリースしました。
こりゃ便利だと、使ってるメモです。
CQLはSQLととても似てて(つか狙って似せてるんだろう)親しみやすいです。
SELECTなんかも以下のような構文でSQL知ってりゃすぐわかる感じです。
このCQLのちょっと意味不明な仕様にがっかりしたんじゃないのかと思う。
SELECT文にてWHERE句に指定できるカラムは
セカンダリインデックスが付いてないとダメ!!!
ええええ?だってさ、SuperColumnってセカンダリインデックス貼れないじゃん!
これは困りますよね。。。
SuperColumnってCassandraの強みと1つに数えられるくらい大切なものじゃないの?
新しくCQLなるものを出したんならそこに対応していないってのもどうかと思う。
ここで書いてるのはあくまで自分で調べた結果であって、
もし、、いやいやこーやればできんじゃん!ってのがあれば是非ご教授下さい。
こりゃ便利だと、使ってるメモです。
CQLはSQLととても似てて(つか狙って似せてるんだろう)親しみやすいです。
SELECTなんかも以下のような構文でSQL知ってりゃすぐわかる感じです。
SELECT * FROM カラムファミリ WHERE KEY = キーなので、こんな事もできます。
SELECT * FROM カラムファミリ WHERE COL1 = 条件1 AND COL2 = 条件2ただし、スーパーカラム(SuperColumn)をいっぱい使用している0.7時代のユーザは
このCQLのちょっと意味不明な仕様にがっかりしたんじゃないのかと思う。
SELECT文にてWHERE句に指定できるカラムは
セカンダリインデックスが付いてないとダメ!!!
ええええ?だってさ、SuperColumnってセカンダリインデックス貼れないじゃん!
これは困りますよね。。。
SuperColumnってCassandraの強みと1つに数えられるくらい大切なものじゃないの?
新しくCQLなるものを出したんならそこに対応していないってのもどうかと思う。
ここで書いてるのはあくまで自分で調べた結果であって、
もし、、いやいやこーやればできんじゃん!ってのがあれば是非ご教授下さい。
@PostConstructと@PreDestroyの悩み
アノテーションの使い方を前回で書いたのはいいんだけども。
ちょっと気になったので試したら悩みができた。。。
@Autowiredとか@Resourceとかで設定した場合でprototype指定されていたら、
ApplicationContextを直接持ってないとこでdestroyって呼べなくね?みたいな。
ApplicationContext持ち回せばいいのかな。。。。
試しに以下のようなコードを書いたが確かにdestroyは呼ばれない。(前回試してるから当たり前なんだが)
クラスを2重にするのがめんどくさかったのでJUnitで。。。。
対象Bean
実行クラス
んーどうすりゃいいんだ。
思いつくのはこれしかない。
実行クラス
これだと当たり前にdestroyも呼ばれるんだが。
他にいい方法ってないの?
ちょっと気になったので試したら悩みができた。。。
@Autowiredとか@Resourceとかで設定した場合でprototype指定されていたら、
ApplicationContextを直接持ってないとこでdestroyって呼べなくね?みたいな。
ApplicationContext持ち回せばいいのかな。。。。
試しに以下のようなコードを書いたが確かにdestroyは呼ばれない。(前回試してるから当たり前なんだが)
クラスを2重にするのがめんどくさかったのでJUnitで。。。。
対象Bean
package com.zomu.t.example;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("testComponent")
@Scope("prototype")
public class TestComponent {
@PostConstruct
public void init() {
System.out.println("init.");
}
public void outputMsg() {
System.out.println("msg....");
}
@PreDestroy
public void destroy() {
System.out.println("destroy.");
}
}
実行クラス
package com.zomu.t.example;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:ApplicationContext.xml" })
public class TestInitDestroy2 {
@Resource(name = "testComponent")
TestComponent tc = null;
@Test
public void main() {
tc.outputMsg();
}
}
んーどうすりゃいいんだ。
思いつくのはこれしかない。
実行クラス
package com.zomu.t.example;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:StoreManager-Common-ApplicationContext.xml" })
public class TestInitDestroy2 {
@Resource(name = "testComponent")
TestComponent tc = null;
@Autowired
ConfigurableApplicationContext appContext = null;
@Test
public void main() {
tc.outputMsg();
appContext.getBeanFactory().destroyBean("testComponent", tc);
}
}
やってることは、前回と変わりはない。ApplicationContextと手を握り合って「バルス」って唱えただけ。これだと当たり前にdestroyも呼ばれるんだが。
他にいい方法ってないの?
@PostConstructと@PreDestroy
Springの@PreDestroyと@PostConstructについて。
これはBean定義時代の「init-method」と「destroy-method」のアノテーション。
Scopeをprototypeで作成したBeanについて@PreDestroyはいつ呼ばれんだ?
って気になったので、サンプルを作成して確かめたんでメモる。
まずは、prototypeで作成しない場合の例
対象のComponent
実行クラス
結果
おお。ちゃんと呼ばれてますね。
では、prototypeで作成した場合。
対象のComponent
実行すると、、、
結果
あれ、destroyが呼ばれない。
なんじゃこりゃ。
プロトタイプだから、もうBeanFactoryの知ったこっちゃねぇって事?
じゃー実行クラスで実験してみる。
結果
なるほど。
ちゃんとインスタンスと登録名さえ渡してくれりゃケツ拭きまっせ。ってことっぽい。
めんどいから拭いてくれよー。って思いました。
これはBean定義時代の「init-method」と「destroy-method」のアノテーション。
Scopeをprototypeで作成したBeanについて@PreDestroyはいつ呼ばれんだ?
って気になったので、サンプルを作成して確かめたんでメモる。
まずは、prototypeで作成しない場合の例
対象のComponent
package com.zomu.t.example;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component("testComponent")
public class TestComponent {
@PostConstruct
public void init() {
System.out.println("init.");
}
public void outputMsg() {
System.out.println("msg....");
}
@PreDestroy
public void destroy() {
System.out.println("destroy.");
}
}
実行クラス
package com.zomu.t.example;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestInitDestroy {
public static void main(String[] args) {
ConfigurableApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "ApplicationContext.xml" });
TestComponent tc = (TestComponent) appContext.getBean("testComponent");
tc.outputMsg();
appContext.close();
}
}
結果
init. msg.... destroy.
おお。ちゃんと呼ばれてますね。
では、prototypeで作成した場合。
対象のComponent
package com.zomu.t.example;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("testComponent")
@Scope("prototype")
public class TestComponent {
@PostConstruct
public void init() {
System.out.println("init.");
}
public void outputMsg() {
System.out.println("msg....");
}
@PreDestroy
public void destroy() {
System.out.println("destroy.");
}
}
さっきと違うのは、@Scopeでprototype指定しているだけ。実行すると、、、
結果
init. msg....
あれ、destroyが呼ばれない。
なんじゃこりゃ。
プロトタイプだから、もうBeanFactoryの知ったこっちゃねぇって事?
じゃー実行クラスで実験してみる。
package com.zomu.t.example;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestInitDestroy {
public static void main(String[] args) {
ConfigurableApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "ApplicationContext.xml" });
TestComponent tc = (TestComponent) appContext.getBean("testComponent");
tc.outputMsg();
appContext.getBeanFactory().destroyBean("testComponent", tc);
appContext.close();
}
}
結果
init. msg.... destroy.
なるほど。
ちゃんとインスタンスと登録名さえ渡してくれりゃケツ拭きまっせ。ってことっぽい。
めんどいから拭いてくれよー。って思いました。
2011年10月5日水曜日
Castorの使い方「Unmarshal」
Castorを使い始めて間もないが、基本的にネット上に転がっている情報ではUnmarshalについて詳しく載っていなくて
英語もあまり得意でない僕にとっては、苦戦を強いられた。。。
まずUnmarshalは、XML→Objectのこと。
おいおいそこからかよ。。。っていう気持ちを抑えて無駄にメモることにする。
使い道はいろいろあるだろうけど、
自分の場合はWebAPIの返却をオブジェクトとして扱いたかったから。
(XSDとか提供されていない場合に)
Unmarshalを行うコードは以下のようになる。
はまったところだけを書いておくと、、、、
->変換するXMLはエンコーディング指定をSJISにしないとだめ!
->ArrayListへ詰めるには上記のようにしなきゃだめ!
->基本的にclassタグにはtypeを書いておけ!
->たぶんclassは入れ子になっちゃダメ?
こんくらいかな。
誰かが救われれば本望です。
英語もあまり得意でない僕にとっては、苦戦を強いられた。。。
まずUnmarshalは、XML→Objectのこと。
おいおいそこからかよ。。。っていう気持ちを抑えて無駄にメモることにする。
使い道はいろいろあるだろうけど、
自分の場合はWebAPIの返却をオブジェクトとして扱いたかったから。
(XSDとか提供されていない場合に)
Unmarshalを行うコードは以下のようになる。
public class CastorTest {
private static Mapping mapping;
private static Unmarshaller unmar;
private static CategoryList categoryList;
public CastorTest() {
}
private void initialize() {
mapping = new Mapping();
try {
mapping.loadMapping("xml/categoryList_mapping.xml");
System.out.println("categoryList_mapping succeeded.");
} catch (Exception e) {
}
}
private void HandleCategoryList() {
try {
unmar = new Unmarshaller(mapping);
categoryList = (CategoryList) unmar.unmarshal(new InputSource(
new FileReader("xml/categoryList.xml")));
Category[] categories = new Category[categoryList.getCategories().getCategories().size()];
categories = (Category[]) categoryList.getCategories().getCategories().toArray();
for (int i = 0; i < categories.length; i++) {
Category category = categories[i];
System.out.print(category.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
CastorTest test = new CastorTest();
test.initialize();
try {
test.HandleCategoryList();
} catch (Exception e) {
System.out.println(e);
}
}
}
僕がつまづいたのは、Mapping定義を示すXMLファイルの書き方。。。
Unmarchalを行うXMLとそのMapping定義のXMLを続けて以下に示す。
▼変換したいXML
▼Mapping定義002名前1 キー1 親1 001名前2 キー2 親2
はまったところだけを書いておくと、、、、
->変換するXMLはエンコーディング指定をSJISにしないとだめ!
->ArrayListへ詰めるには上記のようにしなきゃだめ!
->基本的にclassタグにはtypeを書いておけ!
->たぶんclassは入れ子になっちゃダメ?
こんくらいかな。
誰かが救われれば本望です。
2011年10月1日土曜日
JSFの限界点 - イントロ -
JSF(JavaServerFaces)はSunが作ったフレームワーク。
MVC2を採用していてるJEEに準拠したもの。
導入はとても簡単でっていっても書かないけど、
GlassFishと併せて使ってみて相性がとてもいいんではないかと感じた。
基本的に製造順序としては以下のようになるのでは?と考えている。
1.画面(XHTML)の作成(ただし、ManagedBeanがなくてもいいようなプロト状態)
2.ManagedBeanの作成
〜ビジネスロジック等も製造するけどまー省略〜
3.画面のManagedBeanへの適用
何回かに分けてこれから書こうかと思うが、
実際に使うことを検討したが、辞めた理由についてメモしていく。
MVC2を採用していてるJEEに準拠したもの。
導入はとても簡単でっていっても書かないけど、
GlassFishと併せて使ってみて相性がとてもいいんではないかと感じた。
基本的に製造順序としては以下のようになるのでは?と考えている。
1.画面(XHTML)の作成(ただし、ManagedBeanがなくてもいいようなプロト状態)
2.ManagedBeanの作成
〜ビジネスロジック等も製造するけどまー省略〜
3.画面のManagedBeanへの適用
何回かに分けてこれから書こうかと思うが、
実際に使うことを検討したが、辞めた理由についてメモしていく。
登録:
投稿 (Atom)