Hibernate--根據實體類獲得表名、主鍵名、欄位名(與Spring整合)(二)
阿新 • • 發佈:2019-02-08
在上一篇中,我們建立了HibernateConfigurationUtil類,可以通過它來獲得實體類對應的表名、列名等相關資訊,本篇我們會就藉助於HibernateConfigurationUtil類以及Java反射,來實現一個JDBCUitl工具類,實現類似於Hibernate中Session.save(Object object)的功能
JDBCUtil類
User類package util; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.List; public class JDBCUtil { /** * 利用反射+JDBC實現類似於Session.save(Object object)的操作,適用於主鍵為單一自增主鍵 * 這裡只是提供一種實現思路,可以根據需要進行擴充套件以及實現類似的update、delete、get操作 * * @param connection 資料庫連線 * @param entity 要儲存的實體類 * @throws Exception */ public static <T> void save(Connection connection, T entity) throws Exception { Class<? extends Object> clazz = entity.getClass(); Field[] fields = clazz.getDeclaredFields(); StringBuilder builder = new StringBuilder(); builder.append("insert into "); builder.append(HibernateConfigurationUtil.getTableName(clazz)); builder.append(" ("); List<Field> useFields = new ArrayList<Field>(); Field field = null; for (int i = 0; i < fields.length; i++) { //設定欄位可以被訪問,如果不設定此選項就無法訪問private欄位 field = fields[i]; field.setAccessible(true); // 過濾不需要的屬性, if ("id".equals(field.getName())) { continue; } useFields.add(field); builder.append(HibernateConfigurationUtil.getColumnName(clazz, field.getName())); if (i < fields.length - 1) builder.append(", "); } builder.append(") values ("); for (int i = 0; i < useFields.size(); i++) { builder.append(" ?"); if (i < useFields.size() - 1) { builder.append(", "); } else { builder.append(" )"); } } PreparedStatement pstmt = connection.prepareStatement(builder .toString()); Class<?> clazz2 = null; for (int i = 0; i < useFields.size(); i++) { field = useFields.get(i); // 根據欄位的型別設定對應型別的值 clazz2 = field.getType(); if (clazz2 == String.class) { pstmt.setString(i + 1, field.get(entity).toString()); continue; } if (clazz2 == Integer.class || clazz2 == int.class) { pstmt.setInt(i + 1, field.getInt(entity)); continue; } if (clazz2 == Double.class || clazz2 == double.class) { pstmt.setDouble(i + 1, field.getDouble(entity)); continue; } if (clazz2 == Date.class) { Date date = (Date) field.get(entity); pstmt.setTimestamp(i+1, new Timestamp(date.getTime())); continue; } } pstmt.executeUpdate(); } }
package bean; import java.util.Date; public class User { private int id; private String username; private String password; private int intValue; private double doubleValue; private Date dateValue; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getIntValue() { return intValue; } public void setIntValue(int intValue) { this.intValue = intValue; } public double getDoubleValue() { return doubleValue; } public void setDoubleValue(double doubleValue) { this.doubleValue = doubleValue; } public Date getDateValue() { return dateValue; } public void setDateValue(Date dateValue) { this.dateValue = dateValue; } }
User.hbm.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="bean.User" table="_user"> <id name="id" type="int"> <column name="id" /> <generator class="identity" /> </id> <property name="username" type="string"> <column name="_username" /> </property> <property name="password" type="string"> <column name="_password" /> </property> <property name="intValue" type="int"> <column name="_intValue" /> </property> <property name="doubleValue" type="double"> <column name="_doubleValue" /> </property> <property name="dateValue" type="timestamp"> <column name="_dateValue" /> </property> </class> </hibernate-mapping>
UserDao
package dao;
import bean.User;
public interface UserDao {
public void addUser(User user);
}
UserDaoImpl
package dao.impl;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.jdbc.Work;
import util.JDBCUtil;
import bean.User;
import dao.UserDao;
public class UserDaoImpl implements UserDao {
private SessionFactory sessionFactory;
@Override
public void addUser(final User user) {
Session session = sessionFactory.getCurrentSession();
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
try {
JDBCUtil.save(connection, user);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
applicationContext.xml
注意:在Hibernate4中必須要配置事務,否則上面的sessionFactory.getCurrentSession()將無法取到值
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>bean/User.hbm.xml</value>
</list>
</property>
</bean>
<!-- 配置事務 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!-- 配置事務的傳播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 配置參與事務的類和方法 -->
<aop:config>
<aop:pointcut expression="execution(* dao.impl.*.*(..))"
id="allServiceMethod" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethod" />
</aop:config>
<bean id="userDao" class="dao.impl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
下面是測試程式碼:
package test;
import java.util.Date;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import bean.User;
import dao.UserDao;
public class TestJDBCUtil {
@SuppressWarnings("resource")
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) context.getBean("userDao");
User user = new User();
user.setUsername("name");
user.setPassword("password");
user.setIntValue(2);
user.setDoubleValue(4.0);
user.setDateValue(new Date());
userDao.addUser(user);
}
}
注:所使用的資料庫為mysql,Hibernate版本為4.2.12.Final