在上一篇中,我们创建了HibernateConfigurationUtil类,可以通过它来获得实体类对应的表名、列名等相关信息,本篇我们会就借助于HibernateConfigurationUtil类以及Java反射,来实现一个JDBCUitl工具类,实现类似于Hibernate中Session.save(Object object)的功能
JDBCUtil类
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;
}
}
注意:在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