Hibernate - 試してみようサンプル
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- ドライバ --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!-- 接続情報 --> <property name="connection.url">jdbc:mysql://localhost/hibernate</property> <property name="connection.username">root</property> <property name="connection.password">xxxx#</property> <!-- 各種設定 --> <property name="hibernate.c3p0.max_size">20</property> <property name="hibernate.c3p0.min_size">1</property> <property name="hibernate.c3p0.timeout">5000</property> <!-- プール内最大Statement --> <property name="hibernate.c3p0.max_statements">100</property> <property name="hibernate.c3p0.idle_test_period">3000</property> <property name="hibernate.c3p0.acquire_increment">2</property> <property name="hibernate.c3p0.validate">true</property> <!-- DB方言解消 --> <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <!-- 必要に応じて表生成? --> <property name="hbm2ddl.auto">update</property> <!-- 生成SQL表示 --> <property name="show_sql">true</property> <property name="hibernate.format_sql">true</property> <!-- マッピングテーブル --> <mapping class="entity.Item"/> </session-factory> </hibernate-configuration>
永久化クラス : Item.java
package entity; import java.math.BigDecimal; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="m_item") public class Item { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; private String name; private BigDecimal price; public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Dao親クラス : DaoSupport.java
package dao; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; public abstract class DaoSupport { protected Session getSession() { // Configurationインスタンス化 Configuration conf = new Configuration() // 引数なし : hibernate.cfg.xml // 引数あり : 引数の設定ファイル .configure(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(conf.getProperties()).build(); // SessionFactory生成 SessionFactory sf = conf.buildSessionFactory(serviceRegistry); // Session生成 Session session = sf.openSession(); return session; } }
ItemのDaoクラス : ItemDao.java
package dao; import java.util.List; import org.hibernate.Session; import org.hibernate.Transaction; import entity.Item; public class ItemDao extends DaoSupport { public void save(Item item) { Session session = super.getSession(); // TX開始 Transaction tx = session.beginTransaction(); session.save(item); tx.commit(); session.close(); } public Item load(Integer id) { Session session = super.getSession(); // loadすると // Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Sessionが発生する // Item item = (Item) session.load(Item.class, id); Item item = (Item) session.get(Item.class, id); session.close(); return item; } public void update(Item item) { Session session = super.getSession(); // TX開始 Transaction tx = session.beginTransaction(); session.update(item); tx.commit(); session.close(); } public void delete(Item item) { Session session = super.getSession(); // TX開始 Transaction tx = session.beginTransaction(); session.delete(item); tx.commit(); session.close(); } public List<Item> searchAll() { Session session = getSession(); @SuppressWarnings("unchecked") List<Item> list = session.createCriteria(Item.class).list(); return list; } }
・登録テスト
import java.math.BigDecimal; import dao.ItemDao; import entity.Item; public class TestEntity { public static void main(String[] args) { ItemDao itemDao = new ItemDao(); Item item = new Item(); // Item生成 item.setPrice(new BigDecimal(100)); item.setName("item01"); // 登録 itemDao.save(item); // // 更新 // item.setPrice(new BigDecimal(200)); // itemDao.update(item); // // 検索 // Item item2 = itemDao.load(1); // System.out.println(item2.getId()); // System.out.println(item2.getName()); // System.out.println(item2.getPrice()); // // // // 削除 // itemDao.delete(item); } }
Hibernate: insert into m_item (name, price, id) values (?, ?, ?) mysql> select * from m_item; +----+--------+-------+ | id | name | price | +----+--------+-------+ | 1 | item01 | 100 | +----+--------+-------+ 1 row in set (0.00 sec)
・更新テスト
// 更新 item.setPrice(new BigDecimal(200)); itemDao.update(item);
Hibernate: update m_item set name=?, price=? where id=? mysql> select * from m_item; +----+--------+-------+ | id | name | price | +----+--------+-------+ | 1 | item01 | 200 | +----+--------+-------+ 1 row in set (0.00 sec)
・検索テスト
// 検索 Item item2 = itemDao.load(1); System.out.println(item2.getId()); System.out.println(item2.getName()); System.out.println(item2.getPrice());
Hibernate: select item0_.id as id1_0_0_, item0_.name as name2_0_0_, item0_.price as price3_0_0_ from m_item item0_ where item0_.id=? 1 item01 200
・削除テスト
// 削除 itemDao.delete(item);
Hibernate: select item_.id, item_.name as name2_0_, item_.price as price3_0_ from m_item item_ where item_.id=? Hibernate: delete from m_item where id=? mysql> select * from m_item; Empty set (0.00 sec)
※deleteの場合は、SQLがseleteとdelete2回発行されているね。
Spring4 - AOP
SpringのAOP。
Annotation (XML定義も可能ね)
- @AspectJ
- @Before
- @After
- @AfterReturing
- @AfterThrowing
- @Aroud
- @Pointcut
必要なjar
- aopalliance.jar
- aspectjrt.jar
- aspectjweaver.jar
コード
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <!-- bean検索 --> <context:component-scan base-package="app.aop"/> <!-- @AspectJ起動 --> <aop:aspectj-autoproxy/> <!-- xmlスキーマ使用しない場合 --> <!-- bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" --> </beans>
package app.aop; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Aspect @Component @Order(1) // 優先順位 public class FourAdviceTest { // pointcut定義 @Pointcut("execution(* app.aop.*.*(..))") private void myPointCut(){} // pointcut実行前 // @Before("execution(* app.aop.*.*(..))") @Before(value="myPointCut()") public void authority(JoinPoint jp) { System.out.println("Before advice."); System.out.println("目標オブジェクト" + jp.getTarget()); System.out.println("目標メソッド : " + jp.getSignature().getName()); System.out.println("目標メソッド引数 : " + Arrays.toString(jp.getArgs())); } // pointcut正常終了後 @AfterReturning(pointcut = "execution(* app.aop.*.*(..))", returning = "ret") public void log(JoinPoint jp, String ret) { System.out.println("AfterReturning advice."); System.out.println("戻り値 : " + ret); System.out.println("目標オブジェクト" + jp.getTarget()); System.out.println("目標メソッド : " + jp.getSignature().getName()); System.out.println("目標メソッド引数 : " + Arrays.toString(jp.getArgs())); } // pointcut正常、異常終了後 @After("execution(* app.aop.*.*(..))") public void release(JoinPoint jp) { System.out.println("After advice."); System.out.println("目標オブジェクト" + jp.getTarget()); System.out.println("目標メソッド : " + jp.getSignature().getName()); System.out.println("目標メソッド引数 : " + Arrays.toString(jp.getArgs())); } // pointcut前後、引数、戻り値修正可能 // 強力な機能だな @Around("execution(* app.aop.*.*(..))") public Object processTx(ProceedingJoinPoint jp) throws java.lang.Throwable { System.out.println("Around advice."); Object[] args = jp.getArgs(); if (args != null && args.length > 0 && args[0].getClass() == String.class) { // 引数を修正する args[0] = "AAA" + args[0]; } // pointcutを実行する Object ret = jp.proceed(args); System.out.println("pointcut実行完了"); // if (ret != null && ret instanceof Integer) ret = (Integer) ret * (Integer) ret; return ret; } }
package app.aop; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component("helloWorld") @Scope("singleton") public class HelloWorld{ public String hello(String str1, String str2) { return str1 + str2; } }
package app.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestAOP { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("aop-beans.xml"); HelloWorld h = (HelloWorld) context.getBean("helloWorld"); h.hello("aaa", "bbb"); } }
Around advice. Before advice. 目標オブジェクトapp.aop.HelloWorld@20d525 目標メソッド : hello 目標メソッド引数 : [AAAaaa, bbb] pointcut実行完了 After advice. 目標オブジェクトapp.aop.HelloWorld@20d525 目標メソッド : hello 目標メソッド引数 : [AAAaaa, bbb] AfterReturning advice. 戻り値 : AAAaaabbb 目標オブジェクトapp.aop.HelloWorld@20d525 目標メソッド : hello 目標メソッド引数 : [AAAaaa, bbb]
Spring4 - 零配置ファイル - Annotation利用
Springは「配置より規約」を採用してなく、Annotationを利用してどれをBeanとして扱うを決める。
SpringのBean定義用Annotaion
- @Component
- @Controller
- @Service
- @Repository
ライフサイクルAnnotation
- @PostConstruct
- @PreDestory
Spring3.0追加
- @DependsOn : 他のbean強制初期化
- @Lazy : 前もって初期化するか
Spring4.0
@Autowired
- setter,通常メソッド、変数、コンストラクター修飾可能
- setter修飾の場合、byTypeでDIする
- @Autowired public void prepare(ClassA a, ClassB b)
- byTypeの場合、複数見つかったらBeanCreateExceptionが発生する
- private ClassA[] a; // ClassAのすべてのBeanをDI
@Qualifier
- @Autowired @Qualifier("beanName") private ClassA classA; // ClassAのbeanNameのbean
- public void setA(@Qualifier("beanName") ClassA classA) // 引数にも指定可能
サンプル
package app.annotationTest; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("singleton") public class Japanese{ private int age; // 年齢 private String name; // 名前 @Autowired @Qualifier("pen") private Pen pen; public Pen getPen() { return pen; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } public void info() { System.out.println("名前 : " + this.name); System.out.println("年齢 : " + this.age); } // 生成後 @PostConstruct public void init() { System.out.println("初期化処理"); } // 破棄前 @PreDestroy public void destory() { System.out.println("破棄する前の処理"); } }
package app.annotationTest; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("singleton") public class Pen { public void write() { System.out.println("文字を書きました"); } }
package app.annotationTest; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestComponent { public static void main(String[] args) { // ApplicationContext context = new ClassPathXmlApplicationContext("component-beans.xml"); // Springコンテナー生成 AbstractApplicationContext context = new ClassPathXmlApplicationContext("component-beans.xml"); // JVM終了時にコンテナーを破棄する context.registerShutdownHook(); Japanese j = context.getBean(Japanese.class); j.info(); j.getPen().write(); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 指定パッケージ配下のbeanを検索する --> <context:component-scan base-package="app.annotationTest"/> </beans>
初期化処理 名前 : null 年齢 : 0 文字を書きました 破棄する前の処理
Spring4 - BeanFactoryPostProcessor - PropertyPlaceholderConfigurer
PropertyPlaceholderConfigurerは、
propertiesファイルを読み取り、Springコンテナーのデータとして使える。
package app.propertyOverrideConfigurer; public class Japanese{ private int age; // 年齢 private String name; // 名前 public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } public void info() { System.out.println("名前 : " + this.name); System.out.println("年齢 : " + this.age); } }
<?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean class= "org.springframework.beans.factory.config.PropertyOverrideConfigurer"> <property name="locations"> <list> <!-- propertieyファイル --> <value>japanese.properties</value> <!-- 複数指定可能 --> <!--value>xxx.properties</value--> </list> </property> </bean> <!-- Bean定義 --> <!-- 属性を設定する必要がなく、propertyファイルから設定される --> <bean id="japanese" class="app.propertyOverrideConfigurer.Japanese" /> <!-- XMLスキーマ利用 --> <!-- context-property-override location="classpath:japanese.properties" --> </beans>
package app.propertyOverrideConfigurer; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestPropertyOverrideConfigurer { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("PorpertyOverrideConfigurerBean.xml"); // Bean取得 Japanese p = context.getBean("japanese", Japanese.class); p.info(); } }
名前 : SATO 年齢 : 20
Spring4 - BeanFactoryPostProcessor - PropertyPlaceholderConfigurer
PropertyPlaceholderConfigurerは、
propertiesファイルを読み取り、Springコンテナーのデータとして使える。
package app.beanFactoryPostFrocessor; public class Japanese{ private int age; // 年齢 private String name; // 名前 public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } public void info() { System.out.println("名前 : " + this.name); System.out.println("年齢 : " + this.age); } }
<?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean class= "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <!-- propertieyファイル --> <value>japanese.properties</value> <!-- 複数指定可能 --> <!--value>xxx.properties</value--> </list> </property> </bean> <!-- Bean定義 --> <bean id="japanese" class="app.beanFactoryPostFrocessor.Japanese" p:name="${name}" p:age="${age}" /> <!-- XMLスキーマ利用 --> <context:property-placeholder loaction="classpath:japaense.properties" /> </beans>
japanese.properties
name=SATO age=20
package app.beanFactoryPostFrocessor; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestPropertyPlaceholderConfigurer { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("PorpertyPlaceholderConfigurerBean.xml"); // Bean取得 Japanese p = context.getBean("japanese", Japanese.class); p.info(); } }
名前 : SATO 年齢 : 20