一个SpringJDBC的泛型DAO和通用业务层组件
jopen
9年前
1说明一下
最近要做一个系统,这个系统是基于Spring的。这篇博客减少了一些无关的代码。这个比较简单容易看懂。另外一些一对多多对多等等没有贴出来,但大体是一样的,基于反射机制去实现,并且自定义一些注解来设置实体间关系等等。。。。
实体类:
为了方便,这里自定义一个规范,就是主键一定要命名为id,field名称一定要与表的字段名一致。
package com.lin.jllm.domain; import java.text.SimpleDateFormat; import java.util.Date; /** * * create table ORDER_INFO( id int not null primary key auto_increment, #订单号 startTime date not null, #发货时间 stateTime date, #状态时间 positionInfo varchar(255) not null default '未发货', #位置信息 sourceInfo varchar(255) not null, #来源信息 destinationInfo varchar(255) not null); #目的地信息 * * @author lin * */ public class OrderInfo { private Integer id; private Date startTime; private Date stateTime; private String positionInfo; private String sourceInfo; private String destinationInfo; public OrderInfo() { super(); // TODO Auto-generated constructor stub } public OrderInfo(Integer id, Date startTime, Date stateTime, String positionInfo, String sourceInfo, String destinationInfo) { super(); this.id = id; this.startTime = startTime; this.stateTime = stateTime; this.positionInfo = positionInfo; this.sourceInfo = sourceInfo; this.destinationInfo = destinationInfo; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getStateTime() { return stateTime; } public void setStateTime(Date stateTime) { this.stateTime = stateTime; } public String getPositionInfo() { return positionInfo; } public void setPositionInfo(String positionInfo) { this.positionInfo = positionInfo; } public String getSourceInfo() { return sourceInfo; } public void setSourceInfo(String sourceInfo) { this.sourceInfo = sourceInfo; } public String getDestinationInfo() { return destinationInfo; } public void setDestinationInfo(String destinationInfo) { this.destinationInfo = destinationInfo; } @Override public String toString() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:SS"); return "OrderInfo [id=" + id + ", startTime=" + sdf.format(getStartTime()).toString() + ", stateTime=" + sdf.format(getStateTime()).toString() + ", positionInfo=" + positionInfo + ", sourceInfo=" + sourceInfo + ", destinationInfo=" + destinationInfo + "]"; } }
2 DAO接口
2.1泛型DAO接口
package com.lin.jllm.dao.intf; import java.util.List; import com.lin.jllm.exception.DaoException; public interface IBaseDao<T> { public void create(T t) throws DaoException; public T read(Integer id) throws DaoException; public void update(T t) throws DaoException; public void delete(Integer id) throws DaoException; public List<T> listAll() throws DaoException; }
2.2 DAO组件接口
package com.lin.jllm.dao.intf; import com.lin.jllm.domain.OrderInfo; public interface IOrderInfoDao extends IBaseDao<OrderInfo> { }
3 DAO实现类
3.1 泛型DAO实现类
package com.lin.jllm.dao.impl; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import com.lin.jllm.dao.intf.IBaseDao; import com.lin.jllm.exception.DaoException; public abstract class AbstractDaoImpl<T> implements IBaseDao<T> { protected JdbcTemplate jdbcTemplate; protected String table_name; protected Class<? extends T> type; public AbstractDaoImpl() { // 获取真实泛型数据类型 Type t = getClass().getGenericSuperclass(); ParameterizedType pt = (ParameterizedType) t; type = (Class) pt.getActualTypeArguments()[0]; } public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public String getTable_name() { return table_name; } public void setTable_name(String table_name) { this.table_name = table_name; } /** * 注入数据源 * @param dataSource */ public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } @Override public void create(T t) throws DaoException { if (t != null) { try { Field[] fields = t.getClass().getDeclaredFields(); String nameString = ""; String valueString = ""; String sql = "insert into "+table_name; Object[] values = new Object[fields.length]; //设置SQL中的参数名和参数个数 for(int i=0;i<fields.length;i++) { fields[i].setAccessible(true);//设置private属性可访问 nameString += fields[i].getName() + ","; valueString += "?,"; values[i] = fields[i].get(t); } //组织SQL语句 nameString = "(" + nameString.substring(0, nameString.length() - 1) + ")values"; valueString = "(" + valueString.substring(0, valueString.length() - 1) + ")"; sql = sql + nameString + valueString; jdbcTemplate.update(sql,values); } catch (Exception e) { e.printStackTrace(); } } } @Override public T read(Integer id) throws DaoException { final Class tempType = type; T t = jdbcTemplate.queryForObject( "select * from "+table_name+" where id=?;", new Object[] { id }, new RowMapper<T>() { public T mapRow(java.sql.ResultSet rs, int arg1) throws SQLException { try { Object temp = tempType.newInstance();//实例化一个类用于获取field的值 Field[] fields = tempType.getDeclaredFields(); for(int i=0;i<fields.length;i++) { fields[i].setAccessible(true);//设置field可访问 fields[i].set(temp, rs.getObject(fields[i].getName()));//设置field的值 } return (T) temp; } catch (Exception e) { e.printStackTrace(); return null; } } }); return t; } @Override public void update(T t) throws DaoException { if(t != null) { try { String sql = "update "+table_name+" set "; Field[] fields = t.getClass().getDeclaredFields(); Object[] values = new Object[fields.length]; int index = 0; //构造SQL语句 for(Field field : fields) { field.setAccessible(true); //判断是不是主键 if(field.getName().equals("id")) { values[values.length - 1] = field.get(t); } else { sql += field.getName()+"=?,"; values[index] = field.get(t); index++; } } sql = sql.substring(0, sql.length() - 1) + " where id=?";//为了去掉逗号 jdbcTemplate.update(sql, values); } catch (Exception e) { e.printStackTrace(); } } } @Override public void delete(Integer id) throws DaoException { jdbcTemplate.update("delete from "+table_name+" where id=?", new Object[]{id}); } @Override public List<T> listAll() throws DaoException { final Class tempType = type; return jdbcTemplate.query("select id,startTime,stateTime,positionInfo,sourceInfo,destinationInfo from "+table_name+";", new RowMapper<T>() { @Override public T mapRow(ResultSet rs, int arg1) throws SQLException { try { Object temp = tempType.newInstance();//实例化一个类用于获取field的值 Field[] fields = tempType.getDeclaredFields(); for(int i=0;i<fields.length;i++) { fields[i].setAccessible(true);//设置field可访问 fields[i].set(temp, rs.getObject(fields[i].getName()));//设置field的值 } return (T) temp; } catch (Exception e) { e.printStackTrace(); return null; } } }); } }
3.2 DAO组件
package com.lin.jllm.dao.impl; import com.lin.jllm.dao.intf.IOrderInfoDao; import com.lin.jllm.domain.OrderInfo; public class OrderInfoDaoImpl extends AbstractDaoImpl<OrderInfo> implements IOrderInfoDao { }
4 业务层
4.1 泛型业务接口
package com.lin.jllm.service.intf; import java.util.List; public interface IBaseService<T> { public void add(T t) throws Exception; public void delete(Integer id) throws Exception; public void update(T t) throws Exception; public T get(Integer id) throws Exception; public List<T> getAll() throws Exception; }
4.2 业务接口
package com.lin.jllm.service.intf; import com.lin.jllm.domain.OrderInfo; public interface IOrderInfoService extends IBaseService<OrderInfo> { }
4.3 泛型业务组件
package com.lin.jllm.service.impl; import java.util.List; import com.lin.jllm.dao.intf.IBaseDao; import com.lin.jllm.service.intf.IBaseService; public class AbstractServiceImpl<T> implements IBaseService<T> { private IBaseDao<T> baseDao; public AbstractServiceImpl() { } //注入DAO public AbstractServiceImpl(IBaseDao<T> baseDao) { this.baseDao = baseDao; } public IBaseDao<T> getBaseDao() { return baseDao; } public void setBaseDao(IBaseDao<T> baseDao) { this.baseDao = baseDao; } @Override public void add(T t) throws Exception { if(t != null) { baseDao.create(t); } } @Override public void delete(Integer id) throws Exception { if(id != null) { baseDao.delete(id); } } @Override public void update(T t) throws Exception { if(t != null) { baseDao.update(t); } } @Override public T get(Integer id) throws Exception { if(id != null) { return baseDao.read(id); } return null; } @Override public List<T> getAll() throws Exception { return baseDao.listAll(); } }
4.4 业务组件
package com.lin.jllm.service.impl; import com.lin.jllm.dao.intf.IBaseDao; import com.lin.jllm.dao.intf.IOrderInfoDao; import com.lin.jllm.domain.OrderInfo; import com.lin.jllm.service.intf.IOrderInfoService; public class OrderInfoServiceImpl extends AbstractServiceImpl<OrderInfo> implements IOrderInfoService { private IOrderInfoDao orderInfoDao; public OrderInfoServiceImpl() { } public OrderInfoServiceImpl(IBaseDao<OrderInfo> baseDao) { super(baseDao); this.orderInfoDao = (IOrderInfoDao)baseDao; } public IOrderInfoDao getOrderInfoDao() { return orderInfoDao; } public void setOrderInfoDao(IOrderInfoDao orderInfoDao) { this.orderInfoDao = orderInfoDao; } }
5 在Spring容器中配置依赖关系
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <!-- JDBC数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/jeanselam" /><!-- 这个系统不使用新的数据库,使用jeanseLam的数据库 --> <property name="username" value="root" /> <property name="password" value="root" /> </bean> <!-- 通用泛型DAO组件 --> <bean name="abstractDaoImpl" class="com.lin.jllm.dao.impl.AbstractDaoImpl" abstract="true"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- OrderInfo --> <bean name="orderInfoDaoImpl" class="com.lin.jllm.dao.impl.OrderInfoDaoImpl" parent="abstractDaoImpl"> <!-- 与该DAO组件对应的表名 --> <property name="table_name" value="OrderInfo"></property> </bean> </beans>
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <!-- 抽象父业务组件 --> <bean name="abstractServiceImpl" class="com.lin.jllm.service.impl.AbstractServiceImpl" abstract="true"> </bean> <!-- 订单信息管理业务组件 --> <bean name="orderInfoServiceImpl" class="com.lin.jllm.service.impl.OrderInfoServiceImpl" parent="abstractServiceImpl"> <constructor-arg ref="orderInfoDaoImpl"></constructor-arg> </bean> </beans>