OpenJWeb平台数据库API调用手册
王保政
QQ:29803446
一、 说明
在OpenJWeb平台中主要使用Spring+Hibernate封装对数据库的访问。可使用ServiceLocator.getDBSupportService()获得一个数据库访问的业务逻辑对象。ServiceLocator是一个服务定位器,也可以说是大多数业务逻辑的门面类,getDBSupportService返回了一个IDBSupportService接口的实例,在此接口的实现类中封装了基于Hibernate的数据库访问。
在core-service.xml中这样配置IDBSupportService接口的一个bean实例:
<?xml version="1.0" encoding="GB2312"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="IDBSupportService" class="org.apache.easframework.core.service.impl.DBSupportServiceImpl">
<constructor-arg><ref local="IBaseDao"/></constructor-arg>
</bean>
<bean id="INodeService" class="org.apache.easframework.core.service.impl.NodeServiceImpl">
<constructor-arg><ref local="IBaseDao"/></constructor-arg>
</bean>
<bean id="IBaseDao" class="org.apache.easframework.core.dao.impl.DBSupportDaoImpl">
<property name="hibernateTemplate">
<ref bean="hibernateMysqlTemplate"/>
</property>
</bean>
<!-- Timer Schedule config start -->
<!-- defime a business timer object-->
<bean id="EAITimerBean" class="org.openjweb.common.timer.JobSchedule"/>
<!--defime which method of class to be called in timer schedule -->
<bean id="EAITimerMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="EAITimerBean" />
<property name="targetMethod" value="doTimerSchedule" />
<property name="concurrent" value="false" /> <!--将并发设置为false-->
</bean>
<!-- 设置定时器 -->
<bean id="eaiTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="EAITimerMethod" />
<!--每两分钟触发-->
<property name="cronExpression" value="0 1/2 * * * ?" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!--EAI调度器,list下可加入其他的调度器-->
<ref bean="eaiTrigger"/>
</list>
</property>
</bean>
<!-- Timer Schedule config end -->
</beans>
二、 ServiceLocator服务定位器
凡新增加的业务逻辑层的调用,都可以在这里注册声明一个业务逻辑接口的调用,在上文的core-service.xml中对应添加的声明来配置一个bean,下面是serviceLocator的代码:
package org.apache.easframework.core.service;
import org.apache.log4j.Logger;
import org.openjweb.common.IMailService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.easframework.core.service.ISysConfig;
public class ServiceLocator {
private static final Logger log = Logger.getLogger(ServiceLocator.class);
private static ApplicationContext context;
public static final ServiceLocator thisService = new ServiceLocator(); //单例类
private static final String[] xmlFiles = new String[] {
"/core-service.xml", "/datasource.xml" ,"/system-config.xml","/mailServer.xml"};
//public static ServiceLocator getInstance()
//{
// return thisService;
//}
public static IMailService getMailService()
{
String beanName = "IMailService";
IMailService service = null;
try
{
service = (IMailService) getBeanService(beanName);
}
catch(Exception ex)
{
ex.printStackTrace();
System.out.println("接口转换异常!");
}
return service;
}
/**
* 系统配置组件
*
* @return
*/
public static ISysConfig getSysConfigService() {
String beanName = "ISysConfig";
ISysConfig service = (ISysConfig) getBeanService(beanName);
return service;
}
public static INodeService getNodeService()
{
String beanName ="INodeService";
INodeService service = (INodeService)getBeanService(beanName);
return service;
}
public static IDBSupportService getDBSupportService() {
String beanName = "IDBSupportService"; // IDBSupportService对应core-service.xml中的bean id,此xml文件中配置的IDBSupportService的实现类是org.apache.easframework.core.service.impl.DBSupportServiceImpl
IDBSupportService service = (IDBSupportService) getBeanService(beanName);
return service;
}
private static IService getBeanService(String serviceName) {
IService bean = null;
try {
if (context == null) {
context = new ClassPathXmlApplicationContext(xmlFiles);
}
bean = (IService) context.getBean(serviceName);
} catch (Exception e) {
log.error("获取Service Bean对象失败!");
log.error(e.getMessage());
e.printStackTrace();
}
return bean;
}
}
在JSP,控制层,业务逻辑层,都可以使用ServiceLocator.getDBSupportService()的格式来调用增删改查等方法。
三、 如何使用ServiceLocator.getDBSupportService调用数据库相关的API:
3.1、AbstractEntity抽象实体类
本平台所有的数据库实体类都继承了org.apache.easframework.core.entity. AbstractEntity,这样在增删改查过程中通过实体传递参数时,只需要传递一个AbstractEntity类型的变量,不要传递具体类变量,这样就保证了所有的实体类都可以使用相同的调用方法。AbstractEntity的代码如下:
package org.apache.easframework.core.entity;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 基础抽象实体类
* @author bzwang
*
*/
public abstract class AbstractEntity implements Serializable
{
/**
* 在列表页面显示的记录行号,注意设计表时注意表字段映射后的列名不要与这个重复
*/
protected long lr = -1;
protected String rowId="";
private String createDt;
private String createUid;
private String updateDt;
private String updateUid;
private String objId;
private String treeCode;//用于树形的实体
public void setTreeCode(String code)
{
this.treeCode = code;
}
public String getTreeCode()
{
return this.treeCode;
}
public void setObjId(String id)
{
this.objId = id;
}
public String getObjId()
{
return this.objId;
}
public void setR(long lr)
{
this.lr = lr;
}
public long getR()
{
return this.lr;
}
public void setRowId(String rowId)
{
this.rowId = rowId;
}
public String getRowId()
{
return this.rowId;
}
public String getCreateDt() {
return this.createDt;
}
public void setCreateDt(String createDt) {
this.createDt = createDt;
}
public String getCreateUid() {
return this.createUid;
}
public void setCreateUid(String createUid) {
this.createUid = createUid;
}
public String getUpdateDt() {
return this.updateDt;
}
public void setUpdateDt(String updateDt) {
this.updateDt = updateDt;
}
public String getUpdateUid() {
return this.updateUid;
}
public void setUpdateUid(String updateUid) {
this.updateUid = updateUid;
}
public Object getFieldValueByName(String fieldName) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
Object obj = null;
String methodName = "get"+fieldName.toUpperCase().substring(0,1)+fieldName.substring(1);
System.out.println("AbstractEntity中计算的方法名:"+methodName);
System.out.println("类名:"+this.getClass().getName());
Method method = null;
method = this.getClass().getMethod(methodName, null);
obj = method.invoke(this, null);
return obj;
}
/**
* 为指定的字符串类型的列赋值,此方法暂未测试
* @param fieldName
* @param fieldValue
* @throws SecurityException
* @throws NoSuchMethodException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public void setProperty(String fieldName,String fieldValue) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
String methodName="set"+fieldName.toUpperCase().substring(0,1)+fieldName.substring(1);
Method method = null;
method = this.getClass().getMethod(methodName,new Class[]{String.class});
method .invoke(this, new Object[]{fieldValue});
}
}
3.2、增删改查示例
以Blog(博客)表为例,表名cms_blog,对应的实体类为CmsBlog.java实体类的代码:
package org.apache.easframework.core.entity;
/**
This POJO generated by OpenJWeb - Hibernate Tools
*/
public class CmsBlog extends org.apache.easframework.core.entity.AbstractEntity implements java.io.Serializable {
//….
}
插入实例:
在JSP文件中使用增加一个实体类:
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import="org.apache.easframework.core.service.*"%>
<%@ page import="org.apache.easframework.core.entity.*"%>
<%@ page import="org.apache.easframework.common.StringUtil"%>
<%
CmsBlog entity = new CmsBlog();
entity.setObjId(StringUtil.getUUID());//创建唯一ID
entity.setBlogName("梦之城");
entity.setBlogClass("CMS");
entity.setRowId(StringUtil.getUUID());//创建唯一行号
try
{
ServiceLocator.getDBSupportService().insert(entity,null);
System.out.println("成功!");
}
catch(Exception ex)
{
System.out.println("----------------");
ex.printStackTrace();
System.out.println("----------------");
}
%>
上面也可以使用saveOrUpdate来替代insert,saveOrUpdate既支持增加实体,又支持修改实体:
ServiceLocator.getDBSupportService().saveOrUpdate(entity,null);
修改实例:
try
{
CmsBlog entity =(CmsBlog)ServiceLocator.getDBSupportService().findById("org.apache.easframework.core.entity.CmsBlog", "objId", "
entity.setBlogName("更改后的BLOG");
ServiceLocator.getDBSupportService().saveOrUpdate(entity, null);
}
catch(Exception ex)
{
ex.printStackTrace();
}
上文的findById是根据一个唯一值列查询出一个CmsBlog实体,然后更改实体的blogName字段,修改后保存。其中findById参数说明:第一个参数是实体类的全路径名,第二个是唯一值的列名比如主键名,第三个参数是指定列名的值,也就是查询条件.
删除实例:
try
{
CmsBlog entity =(CmsBlog)ServiceLocator.getDBSupportService().findById("org.apache.easframework.core.entity.CmsBlog", "objId", "
ServiceLocator.getDBSupportService().delete(entity, null);
}
catch(Exception ex)
{
ex.printStackTrace();
}
删除也可以根据一个条件值或者一个String数组列表来查询:
ServiceLocator.getDBSupportService().deleteById(entityClassName, keyFieldName, keyFieldValue, request);
ServiceLocator.getDBSupportService().deleteByIds(entityClassName, fieldName, pkIds, request);
查询:
//entityClassName是被操作实体类的全路径名,request可以为null.
ServiceLocator.getDBSupportService().findAll(entityClassName, request);
}
//根据hql语句查询:
Hql的格式为:”from CmsBlog cmsblog where cmsblog...”
ServiceLocator.getDBSupportService().findByHqlQuery(hql, request);
}
如果查询一个标签/值,例如代码/名称,可以使用:
ServiceLocator.getDBSupportService().findLabelValueBean(sql, request);
}
这个返回的是struts一个LabelValueBean: org.apache.struts.util.LabelValueBean。
//下面的调用的使用方式时设定一个实体类的某些字段作为查询条件,然后根据设定的条件对对应的表进行查询。
ServiceLocator.getDBSupportService().findSimilarEntities(conditionEntity, request);
}
下面的两个方法可以使用select max(),select count(*) 等格式的sql,只要返回的是一个唯一值,都可以用下面格式的语句,返回的结果是字符串,要根据实际情况转换为数字或其他类型,findSingleValueByHql是基于hql的语句,例如select max(objId) from CmsBlog vo where vo…….
findSingleValueBySql是基于sql的语句,例如select count(*) from ….
ServiceLocator.getDBSupportService().findSingleValueByHql(hql, request);
ServiceLocator.getDBSupportService().findSingleValueBySql(sql, request);
四、 DAO层封装的BaseHibernateDao.java,供大家参考:
package org.apache.easframework.core.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.easframework.core.entity.AbstractEntity;
import org.apache.easframework.core.service.ServiceLocator;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
public abstract class BaseHibernateDao extends HibernateDaoSupport implements IBaseDao {
private static final Logger logger = Logger
.getLogger(BaseHibernateDao.class);
private JdbcTemplate template;
public void insert(AbstractEntity entity) {
getHibernateTemplate().save(entity);
}
public void delete(AbstractEntity entity) {
getHibernateTemplate().delete(entity);
}
public AbstractEntity findById(String entityClassName, String keyFieldName,
Object keyFieldValue) throws Exception {
AbstractEntity entity = null;
String sql = "";
if (keyFieldValue instanceof java.lang.String) {
// String型测试通过
sql = "from " + entityClassName + " as vo where vo." + keyFieldName
+ " = '" + keyFieldValue + "'";
} else {
// 数值型的未测试
sql = "from " + entityClassName + " as vo where vo." + keyFieldName
+ " = " + String.valueOf(keyFieldValue) + " ";
}
List list = getHibernateTemplate().find(sql);
if (list.size() > 0)
entity = ((AbstractEntity) list.get(0));
return entity;
}
public List findListByFieldValue(String entityClassName,
String keyFieldName, Object keyFieldValue, boolean isSortAsc,
String sortFieldName) throws Exception {
String sSort = "asc";
if (isSortAsc == false)
sSort = "desc";
String sql = "";
if (keyFieldValue instanceof java.lang.String) {
// String型测试通过
sql = "from " + entityClassName + " as vo where vo." + keyFieldName
+ " = '" + keyFieldValue + "' order by " + sortFieldName
+ " " + sSort;
} else {
// 数值型的未测试
sql = "from " + entityClassName + " as vo where vo." + keyFieldName
+ " = " + String.valueOf(keyFieldValue) + " order by "
+ sortFieldName + " " + sSort;
}
List list = getHibernateTemplate().find(sql);
return list;
}
public void deleteById(String entityClassName, String keyFieldName,
Object keyFieldValue) throws Exception {
AbstractEntity entity = findById(entityClassName, keyFieldName,
keyFieldValue);
if (entity != null) {
delete(entity);
}
}
public void deleteByIds(String entityClassName, String fieldName,
Object[] pkIds) throws Exception {
if (pkIds != null && pkIds.length > 0) {
for (int i = 0; i < pkIds.length; i++) {
deleteById(entityClassName, fieldName, pkIds[i]);
}
}
}
public void update(AbstractEntity entity) throws Exception {
getHibernateTemplate().update(entity);
}
public void saveOrUpdate(AbstractEntity entity) throws Exception {
getHibernateTemplate().saveOrUpdate(entity);
}
// entityClassName需要类的全路径名
public List findAll(String entityClassName) throws Exception {
List list = getHibernateTemplate().loadAll(
Class.forName(entityClassName));
return list;
}
public List findByHqlQuery(String hql) throws Exception {
List list = getHibernateTemplate().find(hql);
return list;
}
public List findByDetachedCriteria(DetachedCriteria criteria)
throws Exception {
List list = getHibernateTemplate().findByCriteria(criteria);
return list;
}
public List findSimilarEntities(AbstractEntity conditionEntity)
throws Exception {
List list = getHibernateTemplate().findByExample(conditionEntity);
return list;
}
public Object findSingleValueByHql(String hql) throws Exception {
Object obj = findByHqlQuery(hql).get(0);
return obj;
}
public void updateHql(String hql) throws Exception {
Session session = super.getSession();
session.createQuery(hql).executeUpdate();
session.flush();
super.releaseSession(session);
}
public Object findSingleValueBySql(String sql) throws Exception {
Connection con = null;
Object obj = null;
Session session = null;
session = super.getSession();
con = session.connection();
PreparedStatement stmt = null;
stmt = con.prepareStatement(sql);
try {
ResultSet rst = stmt.executeQuery();
while (rst.next()) {
obj = rst.getObject(1);
break;
}
rst.close();
stmt.close();
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("出现异常:" + ex.getMessage());
throw ex;
} finally {
con.close();
super.releaseSession(session);
}
if(obj==null)
{
obj = new String("");//进行一下处理以免外部调用还要执行异常处理
}
else
{
}
return obj;
}
public void updateSql(String sql) throws Exception {
Connection con = null;
Session session = null;
session = super.getSession();
con = session.connection();
PreparedStatement stmt = null;
stmt = con.prepareStatement(sql);
try {
stmt.executeUpdate();
stmt.close();
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("出现异常:" + ex.getMessage());
throw ex;
} finally {
con.close();
super.releaseSession(session);
}
}
public List findLabelValueBean(String sql) throws Exception {
List list = new ArrayList();
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rst = null;
Session session = null;
session = super.getSession();
con = session.connection();
try {
pstmt = con.prepareStatement(sql);
rst = pstmt.executeQuery();
String sName = "";
String sCode = "";
while (rst.next()) {
sName = rst.getString(2);
sCode = rst.getString(1);
//System.out.println(sCode + sName);
list
.add(new org.apache.struts.util.LabelValueBean(sName,
sCode));
}
rst.close();
pstmt.close();
} finally {
con.close();
super.releaseSession(session);
}
return list;
}
public List findPage(String entityClassName, String hqlWhere,
int currentPage, int linePerPage) throws Exception {
List list = null;
Session session = null;
if (!(currentPage >= 0))
currentPage = 1;
if (!(linePerPage >= 0))
linePerPage = 10;
try {
session = super.getSession();
Query query = session.createQuery("from " + entityClassName + " "
+ hqlWhere);
query.setFirstResult((currentPage - 1) * linePerPage);
query.setMaxResults(linePerPage);
list = query.list();
} finally {
super.releaseSession(session);
}
return list;
}
/**
* 执行建表、删表等操作
* @param ddlStmt
*/
public void executeDDL(String ddlStmt) throws Exception
{
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(ServiceLocator.getSysConfigService().getStringValueByParmName("driverClassName")) ;
ds.setUrl(ServiceLocator.getSysConfigService().getStringValueByParmName("dbUrl"));
ds.setUsername(ServiceLocator.getSysConfigService().getStringValueByParmName("userName"));
ds.setPassword(ServiceLocator.getSysConfigService().getStringValueByParmName("password"));
//ds.setDriverClassName("org.gjt.mm.mysql.Driver");
//ds.setUrl("jdbc:mysql://localhost:3333/eas?useUnicode=true&characterEncoding=GBK");
//ds.setUsername("root");
//ds.setPassword("mysql");
template = new JdbcTemplate(ds);
template.execute(ddlStmt);
}
}
IBaseDao:
package org.apache.easframework.core.dao;
import java.util.List;
import org.apache.easframework.core.entity.AbstractEntity;
import org.hibernate.criterion.DetachedCriteria;
/**
* 基础Dao接口
* @author bzwang
*
*/
public interface IBaseDao
{
/**
* 插入实体
* @param entity
* @throws Exception
*/
public void insert(AbstractEntity entity ) throws Exception;
/**
* 删除实体
* @param entity
* @throws Exception
*/
public void delete(AbstractEntity entity ) throws Exception;
/**
* 根据某列的值查询实体,只返回单一实体
* @param entityClassName 实体类的名字,可以不带package
* @param keyFieldName 类字段名
* @param keyFieldValue 类字段值
* @return AbstractEntity
* @throws Exception
*/
public AbstractEntity findById(String entityClassName,String keyFieldName,Object keyFieldValue ) throws Exception;
/**
* 根据某列的值查询实体列表
* @param entityClassName 实体类名,可以不带包路径
* @param fieldName 类字段名
* @param fieldValue 类字段值
* @param isSortAsc 是否升序排列,升序true,降序false
* @param sortFieldName 排序的类字段名
* @return 返回实体的List
* @throws Exception
*/
public List findListByFieldValue(String entityClassName,String fieldName,Object fieldValue,boolean isSortAsc,String sortFieldName ) throws Exception;
/**
* 根据某列的值删除实体(此列应为唯一值列)
* @param entityClassName 实体类名
* @param keyFieldName 类字段名
* @param keyFieldValue 类字段值
* @throws Exception
*/
public void deleteById(String entityClassName, String keyFieldName, Object keyFieldValue ) throws Exception ;
/**
* 删除某列的值在ID数组中的实体
* @param entityClassName 实体类名
* @param fieldName 类字段名
* @param pkIds ID数组,可以整型数组或字符串叔祖
* @throws Exception
*/
public void deleteByIds(String entityClassName,String fieldName,Object[] pkIds ) throws Exception; //删除一组实体
/**
* 保存修改后的实体
* @param entity 实体对象
* @throws Exception
*/
public void update(AbstractEntity entity ) throws Exception;
/**
* 保存修改或新增的实体,具有新增和修改两种作用
* @param entity 新增或修改的实体
* @throws Exception
*/
public void saveOrUpdate(AbstractEntity entity ) throws Exception;
/**
* 给定实体类名查询所有实体
* @param entityClassName 实体类名,此参数需要类的全路径名(实现方法中使用了Class.forName())
* @return List
* @throws Exception
*/
public List findAll(String entityClassName ) throws Exception;
/**
* 给定一个hql语句来查询某列值,如select max(),select count(*),select (colunmname)...
* @param hql Hiberate的hql语句
* @return Object返回一个单一对象,可能为字符串类,也可能返回各种数字类,所以取得返回值后,要对返回的Object进行类型转换。
* @throws Exception
*/
public List findByHqlQuery(String hql ) throws Exception;
/**
* 设定criteria查询条件进行查询
* @param criteria 查询条件类
* @return
* @throws Exception
*/
public List findByDetachedCriteria(DetachedCriteria criteria ) throws Exception;
/**
* 根据查询条件类中的字段值作为查询条件进行查询,查询条件类的字段在查询时是进行相等性匹配的,不支持like模糊查询。
* @param conditionEntity 条件类,此类中各列的值作为查询条件。
* @return
* @throws Exception
*/
public List findSimilarEntities(AbstractEntity conditionEntity ) throws Exception;
/**
* @param hql
* @return
* @throws Exception
*/
public Object findSingleValueByHql(String hql ) throws Exception;
/**
* 给定一个sql语句来查询某列值,如select max(),select count(*),select (colunmname)...
* @param sql sql语句
* @return Object返回一个单一对象,可能为字符串类,也可能返回各种数字类,所以取得返回值后,要对返回的Object进行类型转换。
* @throws Exception
*/
public Object findSingleValueBySql(String sql ) throws Exception;
/**
* 执行delete或update的Hibernate HQL语句
* @param hql hql语句
* @throws Exception
*/
public void updateHql(String hql ) throws Exception;
/**
* 执行delete或update 的SQL语句
* @param sql SQL语句
* @throws Exception
*/
public void updateSql(String sql ) throws Exception;
/**
* 返回一个org.apache.struts.util.LabelValueBean的List
* @param sql 此sql的格式为select code,name from ... where...,返回由代码名称两字段构成的org.apache.struts.util.LabelValueBean
* @return List org.apache.struts.util.LabelValueBean
* @throws Exception
*/
public List findLabelValueBean(String sql ) throws Exception;
/**
* 给定Hibernate where条件进行分页查询,e.g List list = ServiceLocator.getDBSupportService().findPage("CmsApp"," order by appSenname asc",1,2,null);
* @param entityClassName 要查询的实体类名
* @param hqlWhere Hibernate的HQL Where语句
* @param currentPage 当前页面
* @param linePerPage 每页行数
* @return List 实体类的列表
* @throws Exception
*/
public List findPage(String entityClassName,String hqlWhere,int currentPage,int linePerPage ) throws Exception;
public void executeDDL(String ddlStmt) throws Exception;
}