NC-UAP客户化开发-4.NC数据库持久化技术

在NC中很多时候需要我们直接操作数据库,对数据库的访问NC提供了框架类。JDBC FrameWork为NC访问数据库提供统一的数据操作访问,简化数据访问操作。BaseDao是在JDBC FrameWork之上提供数据持久化的工具类。下图是NC 数据库访问的层次图:

NC-UAP客户化开发-4.NC数据库持久化技术

核心类介绍

  • PersistenceManager 

管理连接会话的生命周期,并提供了对单表VO操作的常用实现;

可以传递构造参数选择不同的数据源。 

  • JdbcSession 

对JDBC的API封装和简化

  • SQLParameter 

封装执行SQL的参数

  • ResultSetProcessor 

结果集处理回调接口,封装结果集处理

  • DbException 

封装不同数据库的异常,和统一处理不同数据库的Error Code

  • BaseDAO / IUAPQueryBS / IVOPersistence

管理连接会话的生命周期,提供了对单表VO操作的常用实现

JdbcSession几种参数语法

  • 无参查询
String sql = "select * from bd_deptdoc"; //构造查询语句
List list = (List) session.executeQuery(sql, new ArrayListProcessor());
  • 有参查询
String sql = "select * from bd_deptdoc where dept_code=?";
SQLParameter param = new SQLParameter(); //构造参数对象
param.addParam(“aaa”); //添加参数
List list=(List) session.executeQuery(sql, param, new ArrayListProcessor());
  • 有参更新
String sql = "update bd_deptdoc set dept_code =‘aaa’ where dept_code=?”; 
SQLParameter param = new SQLParameter(); //构造参数对象param.addParam(“bbb”); //添加参数
session.executeUpdate(sql, param);
  • 无参批量更新
String sql = "update bd_deptdoc set dept_code =‘aaa’ where dept_code=‘bbb’"; 
session.addBatch(sql); //添加需要执行的同构SQL
int rows = session.executeBatch(); //执行
  • 特殊参数
Null参数  param.addNullParam(java.sql.Types.INTEGER);
Blob参数 param.addBlobParam (new Object());
Clob参数 param.addClobParam (new String());

 结果集合操作

 对查询结果集合的操作,主要由ResultProcessor类来实现,这是一个接口 ResultProcessor包含有一个简单的方法,不同的ResultProcessor实现返回不同的结果对象。系统提供了一系列常用的默认实现。

NC-UAP客户化开发-4.NC数据库持久化技术

ArrayProcessor 数组处理器,返回一个对象数组,结果集中只有一行数据,其中结果集中每一列对应数组的一个元素。

ArrayListProcessor 数组集合处理器,返回一个ArrayList集合,集合中的每一个元素是一个数组,每个数组对应结果集中的一行数据,其中结果集中每一列对应数组的一个元素。

MapProcessor HashMap处理器,返回一个HashMap, 结果集中只有一行数据,其中结果集合中每一列的列名和列值对应HashMap的一个关键字和相应的值。

MapListProcessor HashMap集合处理器,返回一个ArrayList集合,集合中的每一个元素是一个HashMap,每个HashMap对应结果集中的一行数据, 其中结果集合中每一列的列名和列值对应HashMap的一个关键字和相应的值。

BeanProcessor 值对象处理器,返回一个JavaBean,结果集中只有一行数据,该处理器能自动把结果集中的值按列的名称映射到javaBean中,如:结果集中有名称为”name”的字段,那么只要该java对象中有getName()方法就能把结果集合中”name”对应的值映射到对象中。

BeanListProcessor值对象集合处理器,返回一个ArrayList集合,集合中的每一个元素是一个javaBean,每个javaBean对应结果集合中一行数据,其中每个JavaBean中的数据映射关系和BeanProcess同理。还有ColumnProcessor ,BeanMappingListProcessor ,BeanMappingProcessor几个类

BeanListProcessor作为结果集的例子:

ArrayList list=(ArrayList) session.executeQuery(sql, param, new BeanListProcessor(TrainReqmatbillVO.class));   // TrainReqmatbillVO是一个普通vo类
int listcount = list.size();
TrainReqmatbillVO[] vos = new TrainReqmatbillVO[listcount];
for (int i = 0; i < vos.length; i++) {
        vos[i] = (TrainReqmatbillVO)list.get(i);
}

结果集控制

在NC持久层中为了防止执行大查询后返回结果集合过多导致系统内存溢出系统默认设置了最大返回结果集行数是10万行,如果如要返回更多行数或者不限制返回行数,需要做如下设置:

在SuperDMO中设置返回行数

SuperDMO superDmo=new SuperDMO();

superDmo. setMaxRows(行数);

如果rows= -1表示不限制返回行数

在BaseDAO中设置返回行数

BaseDAO baseDao=new BaseDAO();

BaseDAO. setMaxRows(行数);

如果rows= -1表示不限制返回行数

在ResultsetProcessor中设置返回行数

BaseProcessor processor=new ArrayListProcessor();

Processor. setMaxRows(行数);

在结果集中设置返回行数

CrossDBResultset resultset=( CrossDBResultset)rs;

Resultset.setMaxRows(行数);

实例讲解

通过JDBC FrameWork访问数据库

通过代码和注释来看如何通过JdbcSession访问数据库 (该实例在培训教程提供的“\配套示例\示例代码”目录下压缩包nc5Xsample.ara中的工程NC_DEMO的private端nc.impl.sample.DAOPubImpl里)

//JdbcSession访问数据库的示例
    private void testPersistenceManager() {
        int resultSize = 0;
        PersistenceManager sessionManager = null;
        try {
            // 开始JDBC会话
            sessionManager = PersistenceManager.getInstance("design");
            JdbcSession session = sessionManager.getJdbcSession();
            String sql = "SELECT * FROM bd_corp WHERE unitcode = ?"; 
            SQLParameter param = new SQLParameter(); // 构造参数对象
            param.addParam("ufida"); // 添加参数           
            ArrayList list = (ArrayList) session.executeQuery(sql, param,
                    new BeanListProcessor(CorpVO.class));
            resultSize = list.size();
            for (int i = 0; i < resultSize; i++) {
                CorpVO temp = (CorpVO) list.get(i);
                System.out.println(temp.getUnitcode());
                System.out.println(temp.getUnitname());
            }
        } catch (DbException e) {
            e.printStackTrace();
        } finally {
            if (sessionManager != null) {
                sessionManager.release(); // 关闭和释放连接会话
            }
        }
    }

 通过BaseDao进行对象的持久化

通过持久层框架可以很方便的实现把内存中的对象持久化到数据库、把数据库中的关系数据加载到内存中。作为入门的一个例子,我们使用一个简单的Java Bean Person类(注意需要进行持久化的VO类必须符合Java Bean规范) 

  • 前台数据访问

使用IVOPersistence服务组件,进行增删改操作;

IVOPersistence iVOPersistence=( IVOPersistence)NCLocator.getInstance().lookup(IVOPersistence.class.getName());

使用IUAPQueryBS服务组件,进行查询操作

// IUAPQueryBS 例子
    private void testIUAPQueryBS() {
        try {
            IUAPQueryBS iUAPQueryBS = (IUAPQueryBS) NCLocator.getInstance()
                    .lookup(IUAPQueryBS.class.getName());
            String sql = "SELECT * FROM bd_corp";
            SQLParameter param = new SQLParameter(); // 构造参数对象
            ArrayList list = (ArrayList) iUAPQueryBS.executeQuery(sql,param,
                    new BeanListProcessor(CorpVO.class));
            int resultSize = list.size();
            for (int i = 0; i < resultSize; i++) {
                CorpVO usrVo = (CorpVO) list.get(i);
                System.out.println(usrVo.getUnitcode());
                System.out.println(usrVo.getUnitname());
            }
        } catch (ComponentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BusinessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
  • 后台数据访问 

使用BaseDAO工具类

// BaseDAO 例子
    private void testBaseDAO() {
        try {
            BaseDAO dao = new BaseDAO();
            AreaclVO vo1 = new AreaclVO();
            vo1.setAreaclcode("1111");
            vo1.setAreaclname("2222");
            vo1.setPk_corp("1002");
            dao.insertVO(vo1);            
        } catch (DAOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //业务锁:把业务锁放在事务之外,可行原因主要有业务锁不是基于数据库和业务锁是基于Select的处理,无需事务。
    public void updateAreaclVO(AreaclVO vo) {
        boolean islock = PKLock.getInstance().acquireLock(vo.getPrimaryKey(),null, null);

        if (!islock)
            try {
                throw new nc.vo.pub.BusinessException(nc.vo.bd.BDMsg.MSG_LOCKED());
            } catch (BusinessException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        try {
            String[] updateFields = null;
            String[] fields = vo.getAttributeNames();
            Vector v = new Vector();
            v.add("vdef1");
            if (v.size() > 0) {
                updateFields = new String[v.size()];
                updateFields = (String[]) v.toArray(updateFields);
            }
            try {
                new BaseDAO().updateVO(vo, updateFields);
            } catch (DAOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        // 解锁
        finally {
            PKLock.getInstance().releaseLock(vo.getPrimaryKey(), null, null);
        }
    }

通过客户端委托类访问数据库

单据的访问数据库委托类:nc.ui.trade.bsdelegate.BusinessDelegator

基本档案访问数据库的委托类:nc.ui.trade.bsdelegate.BDBusinessDelegator

(此部分内容后面章节再讲解)

相关推荐