一个SpringJDBC的泛型DAO和通用业务层组件

jopen 8年前

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>


来自: http://my.oschina.net/u/2328736/blog/597139