2.3.2. 使用JdbcDao
1.1.准备
首先,新建一个com.bstek.demo.jdbcDao包,在这个包中添加一个继承com.bstek.bdf2.core.orm.jdbc.JdbcDao类的子类JdbcDaoTest和一个视图文件JdbcDaoTest.view.xml。然后,在JdbcDaoTest.view.xml文件中添加一个name为dataTypeDemoUser的DataType,并设置creationType属性为com.bstek.demo.model.DemoUser。再在视图view节点下添加一个id为dataSetDemoUser的DataSet,并设置dataType属性为我们刚才添加的name为dataTypeDemoUser的DataType,选择DataType时,勾选Collection选项。然后,在视图view节点下添加一个id为gridDemoUser的DataGrid。接下来,在JdbcDaoTest.java中添加一个DemoUserRowMapper类,其代码如下:
class DemoUserRowMapper implements RowMapper<DemoUser>{
public DemoUser mapRow(ResultSet rs, int rowNum) throws SQLException {
DemoUser d=new DemoUser();
d.setUsername(rs.getString("USERNAME_"));
d.setMale(rs.getBoolean("MALE_"));
d.setBirthday(rs.getDate("BIRTHDAY_"));
d.setMobile(rs.getString("MOBILE_"));
d.setAddress(rs.getString("ADDRESS_"));
d.setEmail(rs.getString("EMAIL_"));
return d;
}
}
最后,在dorado-home文件夹下,找到context.xml,添加如下配置:
<bean id="jdbcDaoTest" class="com.bstek.demo.jdbcDao.JdbcDaoTest">
</bean>
1.2.使用JdbcDao实现增、删、改
首先,在视图文件的view节点添加id为updateActionDemoUser的UpdateAction,将其dataResolver属性设为hibernateDaoTest#saveDemoUser,并将为其添加一个属性dataSet为dataSetDemoUser的UpdateItem子项。然后,在view节点添加一个ToolBar,并为其添加三个按钮ToolBarBotton,分别是添加按钮、删除按钮和保存按钮,其中,在添加按钮的onClick事件中添加如下代码:
var data=view.get("#dataSetDemoUser.data");
data.insert();
在删除按钮的onClick事件中添加如下代码:
var entity=view.get("#dataSetDemoUser.data:#");
var updateActionDemoUser=view.get("#updateActionDemoUser");
if(entity){
entity.remove();
}else{
dorado.MessageBox.alert("必须选中一行记录!");
}
在保存按钮的onClick事件中添加如下代码:
var updateActionDemoUser=view.get("#updateActionDemoUser");
updateActionDemoUser.execute();
最后,我们需要完成后台服务方法的编写,就是在HibernateDaoTest类中添加如下代码:
@DataResolver
public void saveDemoUsers(Collection<DemoUser> users){
for (DemoUser user : users) {
SqlParameterSource paramSource =new BeanPropertySqlParameterSource(user);
EntityState state = EntityUtils.getState(user);
if (state.equals(EntityState.NEW)) {
this.getNamedParameterJdbcTemplate().update("INSERT INTO Demo_USER
(USERNAME_,MALE_,BIRTHDAY_,MOBILE_,ADDRESS_,EMAIL_)VALUES(:username,:male,:birthday,:mobile
,:address,:email)", paramSource);
} else if (state.equals(EntityState.MODIFIED)) {
this.getNamedParameterJdbcTemplate().update("UPDATE Demo_USER SET
MALE_=:male,BIRTHDAY_=:birthday,MOBILE_=:mobile,ADDRESS_=:address,EMAIL_=:email WHERE
USERNAME_=:username", paramSource);
} else if (state.equals(EntityState.DELETED)) {
this.getNamedParameterJdbcTemplate().update("DELETE FROM Demo_USER WHERE
USERNAME_=:username", paramSource);
}
}
}
这样,我们就完成了对数据的增删改了。
1.3.使用JdbcDao实现各种查询
1.3.1.无查询条件的查询
将dataSetDemoUser的dataProvider属性设置为jdbcDaoTest#query10。接下来,在JdbcDaoTest类里添加如下方法:
@DataProvider
public Collection<DemoUser> query10(){
String sql="SELECT D.USERNAME_,D.MALE_,D.BIRTHDAY_,D.MOBILE_,D.ADDRESS_,D.EMAIL_ FROM
Demo_USER D";
return this.getJdbcTemplate().query(sql, new DemoUserRowMapper());
}
1.3.2.带Map参数的NamedParameterJdbcTemplate条件查询
首先,在JdbcDaoTest.view.xml视图中,添加一个id为将textUsername的TextEditor和一个查询按钮,并在查询按钮的onClick事件中添加如下代码:
var username=view.get("#textUsername.value");
var dataSetDemoUser=view.get("#dataSetDemoUser");
if(username){
dataSetDemoUser.set("parameter",{username:username}).flushAsync();
}
dataSetDemoUser的dataProvider属性设置为jdbcDaoTest#query11。接下来,在JdbcDaoTest类里添加如下方法:
@DataProvider
public Collection<DomeUser> query11(String username){
Map<String,Object> map =new HashMap<String,Object>();
String sql="SELECT D.USERNAME_,D.MALE_,D.BIRTHDAY_,D.MOBILE_,D.ADDRESS_,D.EMAIL_ FROM
DOME_USER D ";
if(username!=null&&!"".equals(username)){
map.put("username", "%"+username+"%");
sql+="WHERE D.USERNAME_ LIKE :username";
}
return this.getNamedParameterJdbcTemplate().query(sql, map, new DomeUserRowMapper());
}
1.3.3.无查询条件的分页查询
将dataSetDemoUser的dataProvider属性设置为jdbcDaoTest#query12,并将dataSetDemoUser的pageSize设置为10,再添加一个分页工具DataPilot,并设置dataSet属性为dataSetDemoUser,接下来,在JdbcDaoTest类里添加如下方法:
@DataProvider
public Collection<DemoUser> query12(){
String sql="SELECT D.USERNAME_,D.MALE_,D.BIRTHDAY_,D.MOBILE_,D.ADDRESS_,D.EMAIL_ FROM
Demo_USER D";
return this.getJdbcTemplate().query(sql, new DemoUserRowMapper());
}
1.3.4.带Map参数的条件分页查询
dataSetDemoUser的dataProvider属性设置为jdbcDaoTest#query13。接下来,在JdbcDaoTest类里添加如下方法:
@DataProvider
public void query13(Page<DemoUser> page,String username){
Map<String,Object> map =new HashMap<String,Object>();
String sql="SELECT D.USERNAME_,D.MALE_,D.BIRTHDAY_,D.MOBILE_,D.ADDRESS_,D.EMAIL_ FROM
DOME_USER D ";
if(username!=null&&!"".equals(username)){
map.put("username", username);
sql+=" WHERE D.USERNAME_=:username";
}
this.pagingQuery(page, sql, new DomeUserRowMapper(),map);
}
代码说明:JdbcDao对象的pagingQuery(Page<?>page,Stringsql,RowMapper<?>mapper,Map<String,Object>parameters)方法,可以实现带参数的查询,参数放到Map集合当中,可以放入多查询参数。
1.3.5.带数组参数的条件分页查询
将dataSetDemoUser的dataProvider属性设置为jdbcDaoTest#query14。接下来,在JdbcDaoTest类里添加如下方法:
@DataProvider
public void query14(Page<DemoUser> page,String username){
String sql="SELECT D.USERNAME_,D.MALE_,D.BIRTHDAY_,D.MOBILE_,D.ADDRESS_,D.EMAIL_ FROM
DOME_USER D ";
if(username!=null&&!"".equals(username)){
sql+=" WHERE D.USERNAME_=?";
this.pagingQuery(page, sql,new Object[]{username},new DomeUserRowMapper());
}else{
this.pagingQuery(page, sql,new DomeUserRowMapper());
}
}
代码说明:此段代码的功能和上一节代码的功能是一样的,只是这里传递查询参数是通过Object数组来实现。但是这种方式对查询参数的顺序有严格的要求,不推荐使用。
1.3.6. 结合DataGrid的过滤工具栏实现分页查询
将dataSetDemoUser的dataProvider属性设置为jdbcDaoTest#query15,并将gridDemoUser的filterMode和showFilterBar属性分别设置为serverSide和true。接下来,在 JdbcDaoTest类里添加如下方法:
@DataProvider
public void query15(Page<DemoUser> page,Criteria criteria){
String sql="SELECT D.USERNAME_,D.MALE_,D.BIRTHDAY_,D.MOBILE_,D.ADDRESS_,D.EMAIL_ FROM
Demo_USER D ";
ParseResult result=this.parseCriteria(criteria,false,"D");
if(result!=null){
StringBuffer sb=result.getAssemblySql();
Map<String,Object> valueMap=result.getValueMap();
sql+=" WHERE "+sb.toString();
this.pagingQuery(page,sql,valueMap.values().toArray(),new DemoUserRowMapper());
}else{
this.pagingQuery(page,sql,new DemoUserRowMapper());
}
}
@Override
protected String buildFieldName(String name) {
if(name==null)return name;
StringBuffer sb=new StringBuffer();
for(char ch:name.toCharArray()){
boolean upper=Character.isUpperCase(ch);
sb.append(Character.toUpperCase(ch));
if(upper){
sb.append("_");
}
}
sb.append("_");
return sb.toString();
}
代码说明:parseCriteria方法的作用是将Criteria对象的相应成分映射到ParseResult的assemblySql和valueMap属性中,以方便我们使用JdbcDao的相关API,其中assemblySql属性是查询语句的where子句部分,且不包括where关键字。而valueMap则是对应的查询参数。buildFieldName方法是对父类AbstractDao中的buildFieldName模板方法的重写,此模板方法是parseCriteria方法内部在拼凑查询语句的where子句时调用的,作用是根据实体类的属性名生成对应的数据库字段名,默认实现是生成的数据库字段名和属性名相同,通过在子类对其重写,可以实现自定义的从实体属性名到数据库字段名的映射。