基于spring jdbc的通用存取层

来源:互联网 发布:js srcelement 编辑:程序博客网 时间:2024/05/16 12:39

博主在spring jdbc的基础上封装了层数据库存取层,好处在于大部分的数据存取已经可以使用,单表编码几乎不用编码,并且支持数据库分页。

使用注解在实体描述数据库的情况,进而从程序员角度只看到对象而不需要写sql语句,也无需从结果集填充属性值到实体。

先介绍api:

限定符和类型方法和说明Longcount(String sql, Object... values)

计算结果个数的辅助方法
voidcreate(T t)
创建对象
voiddelete(String sql, Object... values)
批量删除对象
voiddelete(T t)
删除对象
Tload(T t)
读取对象
PageDto<T>page(PageDto<T> pageDto, String sql, Object... values)
根据分页对象PageDto中的ranges的数值来读取数据库数据
List<T>query(String sql, Object... values)
查询对象列表
List<T>queryAll()
获取所有对象
TqueryById(Object key)
适用于单主键的对象获取
voidsetInjectDataSource(DataSource dataSource)
子类调用本方法注入数据源
Subclass call this method to inject DataSource.
voidupdate(String sql, Object... values)
批量更新对象
voidupdate(T t)
更新单个对象
以下介绍使用范例:

1 通用dao接口

import ifunsu.at.gmail.base.dao.BaseDao;
public interface InjectDataSourceDao<T> extends BaseDao<T>{
}

2 通用dao实现

import ifunsu.at.gmail.base.dao.BaseDaoImpl;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;

public class InjectDataSourceDaoImpl<T> extends BaseDaoImpl<T>{
@Autowired
private DataSource dataSource;

@PostConstruct
public void buildDataSource() {
this.setInjectDataSource(dataSource);
}
}

=================================================

以上是为了引入dao所写的代码,每个项目都有这样两个文件。

=================================================

3 实体

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@AllArgsConstructor
@NoArgsConstructor
@ToString
@EqualsAndHashCode
@Entity
@Table(name="users")
public class PortalUser implements Serializable {

private static final long serialVersionUID = 192903603246880174L;
@Id
@Column(name = "username", length = 128, nullable = false)
private @Setter @Getter String username;
@Column(name = "password", length = 128, nullable = true)
private @Setter @Getter String password;
@Column(name = "enabled")
private @Setter @Getter boolean enabled;
}

上面的实体代码重点在于有@Table注解和@Id、@Column。

有table注解则知道表的名称,有column则知道表的字段名,有id则知道主键(支持多主键)。

4 实体dao接口

public interface PortalUserDao extends InjectDataSourceDao<PortalUser> {
}

可以看到无需写方法。

5 实体dao实现

import org.springframework.stereotype.Repository;
import com.highjet.portal.dao.entity.PortalUser;
import com.highjet.portal.dao.jdbc.PortalUserDao;
@Repository
public class PortalUserDaoImpl extends InjectDataSourceDaoImpl<PortalUser>
implements PortalUserDao {
}

可以看到实现也无需写方法。

6 service调用

public class PortalServiceImpl implements PortalService {
@Autowired
private @Setter PortalUserDao portalUserDao;

@Override
public PortalUser productPortalToken(String username, String token){
PortalUser portalUser = new PortalUser(username, token, true);
this.portalUserDao.update(portalUser);
return portalUser;
}

}

虽然PortalUserDao没写update方法,但是其父接口有,所以可以直接调用。

============================================================

以上即是使用方法,以下是分页代码。

============================================================

public class PageDto<T>extends Objectimplements Serializable

分页对象(page object)

缓存pageSize * pageSize个数的结果集

典型用法:(Typical usage:)

PageDto page = new PageDto();
page.changePageSize(size);
page = this.service.search(page);
request.setAttribute("page", page, WebRequest.SCOPE_SESSION);

以上是读取一次放在session中。下面在分页时获取。(Above read and put into session. Below used when pageing.)


PageDto page = (PageDto) request.getAttribute("page", WebRequest.SCOPE_SESSION); 
List list = page.getList(pageNumber);
if(list == null){
  page = this.service.search(page);//读取的范围超过缓存需要向数据库重新读取。(Access database when read beyond ranges.) 
}
request.setAttribute("page", page, WebRequest.SCOPE_SESSION);// 再放进session中保存。(Result into session again.)

后台数据库读取代码,通常与BaseDaoImpl配合使用。(Codes at Dao. Use with BaseDaoImpl.)
PageDto page(PageDto pageDto, final String sql, final Object... objects); 


限定符和类型方法和说明voidalignList()

对齐结果集
voidchangePageSize(int pageSize)
改变页尺寸同时会影响缓存的长度
Change page size will affect cache size.
List<T>getList()
默认读取当前页
Load data from current page.
List<T>getList(int currentPage)
读取指定页并改变当前页
Change current page and load data.
int[]nextRanges()
获取下一个数据库读取区间
Get next ResultSet ranges.
voidsetResultSetList(int totalRecord, List<T> list, int[] ranges)
设置结果集
Set result after read data from database.
================================================================================

如果为自定义查询,则需要做些改变。

================================================================================

实体:

@Table(name="fakeTable")
public class Complex implements Serializable {

@Id

@Column(name = "fakeColumn", nullable = false)

private @Setter @Getter String id;

}

重点在于fakeTable和fakeColumn,系统检测到这两个关键字时则知道这是组合表的查询。

dao实现:

@Repository
public class ComplexDaoImpl extends InjectGreenPlumDataSourceDaoImpl<Complex>
implements ComplexDao {

     @Override
public
PageDto queryForList(PageDtopageDto) {

                pageDto = this.page(pageDto, "select 语句", 可变条件参数);

condition.setPageDto(pageDto);
return condition;

}

}

重点在于select语句中的结果列名需要和实体名字一致,结果列数可以比实体个数多。

==============================================================================

以上为所有用法,附件是jar包,不开源但可以免费使用。

jar包下载 

api下载 


0 0
原创粉丝点击