博主在spring jdbc的基础上封装了层数据库存取层,好处在于大部分的数据存取已经可以使用,单表编码几乎不用编码,并且支持数据库分页。
使用注解在实体描述数据库的情况,进而从程序员角度只看到对象而不需要写sql语句,也无需从结果集填充属性值到实体。
先介绍api:
| 限定符和类型 | 方法和说明 |
|---|---|
Long | count(String sql, Object... values)
计算结果个数的辅助方法
|
void | create(T t)
创建对象
|
void | delete(String sql, Object... values)
批量删除对象
|
void | delete(T t)
删除对象
|
T | load(T t)
读取对象
|
PageDto<T> | page(PageDto<T> pageDto, String sql, Object... values)
根据分页对象
PageDto中的ranges的数值来读取数据库数据
|
List<T> | query(String sql, Object... values)
查询对象列表
|
List<T> | queryAll()
获取所有对象
|
T | queryById(Object key)
适用于单主键的对象获取
|
void | setInjectDataSource(DataSource dataSource)
子类调用本方法注入数据源
Subclass call this method to inject DataSource.
|
void | update(String sql, Object... values)
批量更新对象
|
void | update(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 Object implements 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);
| 限定符和类型 | 方法和说明 |
|---|---|
void | alignList()
对齐结果集
|
void | changePageSize(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. |
void | setResultSetList(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包,不开源但可以免费使用。

本文介绍了如何基于Spring JDBC封装一层通用的数据库存取层,简化单表操作并支持数据库分页。通过注解实体描述数据库结构,避免手动编写SQL和填充结果集。示例展示了从通用DAO接口、实现、实体定义到具体服务调用的完整流程,并提供了分页查询的实现方式。
660

被折叠的 条评论
为什么被折叠?



