專案結構概覽
- Entity:
org.shirdrn.entity.MyUser(JPA 註解映射)
- DAO Interface:
org.shirdrn.dao.MyUserDAO(@Transactional)
- DAO Impl:
org.shirdrn.dao.impl.MyUserDAOImpl(繼承 JpaDaoSupport)
- Spring Config:
applicationContext.xml + META-INF/persistence.xml
- 測試類:
org.shirdrn.test.*
1. 實體類 MyUser
@Entity
public class MyUser {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="userName") private String userName;
@Column(name="password") private String password;
@Column(name="gender") private String gender;
@Column(name="age") private Integer age;
@Column(name="addr") private String addr;
@Column(name="email") private String email;
@Transient // 不映射資料庫欄位
private Integer birthYear;
// Getter/Setter 略
public Integer getBirthYear() { return 2008 - age; }
}
2. DAO 介面與實作
@Transactional
public interface MyUserDAO {
void createMyUser(MyUser u);
void deleteMyUser(MyUser u);
void updateMyUser(MyUser u);
List queryMyUser(String jpql);
List queryAll();
}
public class MyUserDAOImpl extends JpaDaoSupport implements MyUserDAO {
public void createMyUser(MyUser u) { getJpaTemplate().persist(u); }
public void deleteMyUser(MyUser u) {
MyUser db = getJpaTemplate().find(MyUser.class, u.getId());
getJpaTemplate().remove(db);
}
public void updateMyUser(MyUser u) {
MyUser db = getJpaTemplate().find(MyUser.class, u.getId());
if (u.getUserName() != null) db.setUserName(u.getUserName());
if (u.getAddr() != null) db.setAddr(u.getAddr());
getJpaTemplate().merge(db);
}
public List queryMyUser(String jpql) { return getJpaTemplate().find(jpql); }
public List queryAll() { return getJpaTemplate().find("from MyUser"); }
}
3. Spring 配置 applicationContext.xml
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:tx="https://www.springframework.org/schema/tx"
xsi:schemaLocation=".../spring-beans-2.0.xsd .../spring-tx-2.0.xsd">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="myUserDAOImpl" class="org.shirdrn.dao.impl.MyUserDAOImpl">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
</beans>
4. JPA 配置 META-INF/persistence.xml
<persistence xmlns="https://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="default">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.shirdrn.entity.MyUser</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
5. CRUD 測試範例
// 新增
MyUserDAO dao = ctx.getBean("myUserDAOImpl", MyUserDAO.class);
MyUser u = new MyUser();
u.setUserName("JohnXa"); u.setPassword("123456"); u.setGender("男");
u.setAge(25); u.setAddr("NewYork"); u.setEmail("john@hotmail.com");
dao.createMyUser(u);
// 刪除
MyUser del = new MyUser(); del.setId(29L); dao.deleteMyUser(del);
// 修改
MyUser upd = new MyUser(); upd.setId(28L); upd.setAddr("北京市"); dao.updateMyUser(upd);
// 查詢
List list = dao.queryAll();
for (MyUser user : list) { System.out.println(user.getUserName() + " ..."); }
心得總結
- JPA 註解免去大量 XML 映射檔,關聯關係一目瞭然。
JpaTemplate API 不如 HibernateTemplate 直觀,修改/刪除需先 find 再操作。
- 查詢簡單強大,但插入/修改/刪除必須在交易中,否則無效。
- 整合門檻較高,錯誤排查不易,適合表格多、關聯複雜的專案。