@sqzrcc
2015-05-13T06:52:04.000000Z
字数 5498
阅读 1756
目前使用的Imode,没办法在一个service方法上加锁,正常的事务锁情况:
// 此处加锁,如果有其他线程要操作,必须以下这些方法执行完后
xxx.insert(xxx);
xxxx.update(xxxx);
xxxxx.delete(xxxxx);
// 如果没有错误,则提交,如果有错误回滚
正常的请求和恶意的请求:
修改Imodel源码,但具体要怎么做,不清楚,对orm框架的源码还没做过了解
目前项目中大量的表格都是通过itable来请求Json接口来进行读取数据展示,涉及到几个问题
运行流程:
itable 初始化流程:
定义好一个table,在code处指定要执行的sql代码(在后台配置),itable初始化时去Json接口读取数据来进行展示
在随诊处,读取当前医生的所有随诊:
<table id="followup_table" class="table table-striped"
model="PhrFollowUp" code="phrFollowUp" search="true" refresh="true"
edit="true" remove="true" pageSize=10>
<thead>
<tr>
<th field="id" style="display: none;">ID</th>
<th field="personName">姓名</th>
<th field="diagnosis">诊断</th>
<th field="startdate">发起时间</th>
<th field="status" select="true">完成状态</th>
<th field="enddate">完成时间</th>
<th type="render" render="contentTemName">随诊内容</th>
<th type="render" render="programTemName">指导方案</th>
<th field="followupTime">随诊频率</th>
<th field="tipss">提醒方式</th>
<th type="edit">操作</th>
</tr>
</thead>
</table>
然后通过js去初始化这个table:
var followup_table = new iTables("#followup_table", {
doctorId: loginId // 传入当前登陆的用户
}, function () {
});
对应的会去搜索在后台配置的code为phrFollowUp
的sql语句:
select t.*,to_char(trunc (t.start_date),'yyyy-mm-dd') as startdate,to_char(trunc (t.end_date),'yyyy-mm-dd') as enddate,e.name as doctor_name,p.name as
person_name,m1.name as content_tem_name,m2.name as program_tem_name
from phr_follow_up t
left join md_employee e on e.id = t.doctor_id
left join md_person p on p.id = t.md_person_id
left join emr_template m1 on m1.id = t.content_tem_id
left join emr_template m2 on m2.id = t.program_tem_id
where t.doctor_id != '0'
然后会自动拼接条件:
where t.doctor_id = 4 // js中传入进来的id
存在的问题:
由于大部分操作都在js中去操作,js又是运行在用户游览器上的,用户可以任意去修改代码,或者抓包查看itable的请求来达到读取任意医生的信息:
一个正常合法的接口请求:
http://www.oijiankang.com//crud/json!query?config.sqlCode=phrPersonAction&doctorId=4
用户可以任意修改doctorId的值来达到获取任意医生的信息
一个非法的请求
http://www.oijiankang.com//crud/json!query?config.sqlCode=phrPersonAction&doctorId=5 // 或者 6 7 8 9 就可以读取对应医生的随诊信息
等等...
由于是统一接口,甚至可以未登陆就进行接口的请求,或者一个居民的权限,也能进行请求.
由于在curd/json中有些参数还可以自己传sql过去执行,导致一个sql注入的问题,正常的sql:
select * from md_person where id = 4 //(where id = 4)是由前台传过来的
//如果传过来的是(where id = 4 union select password from admin)
更多的gbk宽字符注入... utf-8注入等..
/crud/json!query?config.sqlcode=getPatients&doctorId=5
),这样就拿到医生id为5的病人了.用户可以任意的去修改doctorid的值),如果交给action中,通过REST API GET /patients
在Action中再去读取当前登陆的医生id,但存在的问题:
类似这样的代码,非常多,会导致sql注入,在Imodel中有提供更好的方式进行sql语句的参数化处理,但是目前项目看来基本没用
对所有类似拼接sql的代码都进行更改,工程量也非常的大
itable -> 本地js验证 -> 接口 -> 提交数据库
中间没有服务器端的验证,这样我们可以任意的修改任何东西:
修改http请求的数据:
很容易就把前端验证给绕过了
将所有的请求不仅在js验证,还要在后端验证,目前项目中也没有成熟的统一验证框架,在某些需要验证的地方代码:
if (authService.getMemberCountByMobile(mobile) > 0) {
jsonInfo.put("flag", false);
jsonInfo.put("message", "手机号已被注册,请重输入");
jsonInfo.put("field", "mobile");
this.renderJson(jsonInfo);
return;
}
if (username.length() < 4 || username.length() > 16) {
jsonInfo.put("flag", false);
jsonInfo.put("message", "用户名长度错误,请输入大于4位小于16位的字符");
jsonInfo.put("field", "username");
this.renderJson(jsonInfo);
return;
}
if (!RegexUtils.checkUsername(member.getUsername())) {
jsonInfo.put("flag", false);
jsonInfo.put("message", "用户名只能包括中文字、英文字母、数字和下划线");
jsonInfo.put("field", "username");
this.renderJson(jsonInfo);
return;
}
代码很繁琐,如果是使用验证框架:
@Length(max=20)
@NotNull
public String getCountry() {
return country;
}
@Length(max=5, message="{long}")
@Pattern(regex="[0-9]+")
@NotNull
public String getZip() {
return zip;
}
在model的层面做验证,不用每个需要的地方都去请求
在hibernate里处理关联关系只需要在model中定义好相关的字段,并把需要关联的字段修改为对象,配置好配置文件,即可很方便的进行关联查询,关于效率方便 还有更多的lazy load ,二级缓存等..
和hibernate一样,都是基于model来进行orm的,如果你需要返回的json字符串中不包含在数据库中(假如请求一个团队,返回的json串中会多一个团队总人数的字段,然而这个字段并不存在在数据库中,也就不会在model里),那么就需要去自定义一个model来做,这样的开发效率会比较低,代码量很大,据我了解,目前医生phr中病人列表就使用了这个做法
使用ActiveRecord模式来进行的关联查询:
public void relation() {
String sql = "select b.*, u.user_name from blog b inner
join user u on b.user_id=u.id where b.id=?";
Blog blog = Blog.dao.findFirst(sql, 123);
String name = blog.getStr("user_name");
}
获取基于model:
public class Blog extends Model<Blog>{
public static final Blog dao = new Blog();
public User getUser() {
return User.dao.findById(get("user_id"));
}
}
public class User extends Model<User>{
public static final User dao = new User();
public List<Blog> getBlogs() {
return Blog.dao.find("select * from blog where user_id=?",
get("id"));
}
}
将model里设置属性的方式改为通过key/value的方式,这样就会非常灵活的去增删字段,如果使用model设置属性的方式,要想使用动态添加属性,则需要动态代码生成[1],使用asm或者javassist库支持。
偶尔会出现一直建立连接池的状况,导致项目非常慢,频繁建立连接,对oracle的消耗也是非常严重的。
目前已经有很多连接池解决方案了,java中比较出名的连接池:Druid,来自阿里巴巴开源的连接池,自称是Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。
.但目前公司没人能做进行连接池的替换。
优点:
大家都会用,用户量大,文档支持多
缺点:
开发繁琐 效率低
优点:
自带orm功能,插件灵活,能很灵活的处理好关联关系,支持Db + Record模式,拥有strtus2绝大部分功能 开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful
缺点:
个人作品,作者可能随时不进行维护
优点:
灵活 开发效率快 用户量大 有spring支持
缺点:
学习成本比较高