精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (6)
|
|
---|---|
作者 | 正文 |
发表时间:2010-04-02
有办法,根据javabean的规则,生成相应的java字符串,然后用compiler编译成字节码放到当前classloader的查找路径下,用classLoader装载进来,但这样生成的instance只能用反射方式获取属性值。就入像其他人说的,如果解决这个问题的话根本不需要动态生成javaBean。map最适合这个工作
|
|
返回顶楼 | |
发表时间:2010-04-02
aaa5131421 写道
181054867 写道
aaa5131421 写道
你这种编码的随意性就太大了,开发前就不需要完整的实体模型设计,开发者想用什么字段整合成一个对象都可以,让后期其他人怎么去维护呢?
这样的情况好hibernate做的比较好,开发前有个固定的模型设计,你查出来的都是固定结构化了对象,更何况你要是在一对多的情况下你怎么生成一个bean呢?难道还要查出多个不同的对象出来?本来通过hibernate的关系就可以用。导航出来的东西,你会多出好多的代码 您不能理解随意性,我认为,为数据库的每个表写一个JavaBean,在执行select sql后,还要写代码new这个Bean,然后在ResultSet中getString(XX),把值一个一个地赋给Bean,这样属于硬编码。 事实是,一些以显示为主的网站,对ResultSet结果集的操作只是单纯的显示出来,所以,我相信可能通过优化,避免我前面说的:写很多很多枯燥无用的代码,通过对ResultSet进行封装,产生一个Bean,然后在页面通过column name直接获得值,这样我们要写的代码会大大减少,缩短我们的开发时间,也让我们觉得,现在做的只是为了写代码更方便,当作一种享受,不要重复发明轮子而已。 至于你说的什么一对多,请不要把Hibernate的理念搬到这里回复,因为我并不使用Hibernate,也不存在什么一对多,这个Bean的产生,只是跟你写的sql有关系,你sql怎么写,你返回什么字段,这个Bean就生成相应字段的Get方法,sql你已经确定,至于什么一对多,多对多,是在你写sql前的事 我这样做是为了写更少的代码 可是最普遍的表结构都是一对多的关系,你不用hibernate只要使用数据库也肯定会碰到一对多关系。怎么可能会没有呢? 例子:界面需求就是简单的将一个一对多的数据展现出来,可是你的简单的键值对的bean无法满足这个要求,最简单的例子,班级表和学生表,界面上要展示出班级名称和对应学生s的名称,用你的方法,怎么用一条sql查询出来然后整合到一个bean中去呢?你是不是要拆开来用两个方法去查呢,分别得到班级名称和学生数据集合呢? 而hibernate直接可以简单写一个查出班级的代码,之后直接在界面导航出学生列表。 你觉得哪个省代码呢?想要省代码应该先从宏观上,上层上去考虑。
有两张表: create table test_class ( `class_id` int(11) auto_increment primary key, `class_name` varchar(50) NOT NULL default '', `class_level` varchar(50) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=gbk; create table test_student ( `student_id` int(11) auto_increment primary key, `class_id` int(11) not null default '0', `student_name` varchar(50) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=gbk;
假设你要显示班级及其学生,需要执行两条sql: select class_id, class_name, class_level from test_class;
select student_id, student_name from test_student where class_id = ${class_id}
第一句,查出class,系统自动封装出一个List,list里保存了这样一个JavaBean,这个JavaBean包含班级的信息,代码类似这样(这个类是动态的,不是硬编码写出来的): class Record{ public String getClass_id(){} public String getClass_name(){} public String getClass_level(){} } 假设这个List保存在request,名字为list,那么,我在页面上如此遍历它: <c:foreach item="${requestScope.list}" var="item"> <h1>班级名:${item.class_name}<h1> <h1>班级级别:${item.class_level}<h1> <table> <tr> <th>学生编号</th> <th>学生姓名</th> </tr> <%-- 这里执行第二条sql,根据class_id查到所有学生,假设保存在request,名字为stulist,遍历这个list,显示所有学生 --%> <c:foreach item="${requestScope.stulist}" var="stu"> <tr> <td>${item.student_id}</t> <td>${item.student_name}</t> </tr> </c:foreach> </table> </c:foreach> Hibernate同样会执行这两条sql,只是不用你手动去调用而已。 而我说的问题是:怎么样实现我上面的显示效果,直接用列名访问数据. 你的sql甚至可以这样写: select test_class.class_name, test_class.class_level, test_student.student_id, test_student.student_name from test_class, test_student where test_class.class_id = test_student.class_id 只要最后能让我用上面的格式来显示结果就可以了。 至于数据类型,你可以在显示时再转换成跟数据库一样的类型,再进行特别的处理,这也属于显示问题了。 我只是想减轻显示时的代码量,不涉及到其他表的对应关系 |
|
返回顶楼 | |
发表时间:2010-04-03
181054867 写道
aaa5131421 写道
181054867 写道
aaa5131421 写道
你这种编码的随意性就太大了,开发前就不需要完整的实体模型设计,开发者想用什么字段整合成一个对象都可以,让后期其他人怎么去维护呢?
这样的情况好hibernate做的比较好,开发前有个固定的模型设计,你查出来的都是固定结构化了对象,更何况你要是在一对多的情况下你怎么生成一个bean呢?难道还要查出多个不同的对象出来?本来通过hibernate的关系就可以用。导航出来的东西,你会多出好多的代码 您不能理解随意性,我认为,为数据库的每个表写一个JavaBean,在执行select sql后,还要写代码new这个Bean,然后在ResultSet中getString(XX),把值一个一个地赋给Bean,这样属于硬编码。 事实是,一些以显示为主的网站,对ResultSet结果集的操作只是单纯的显示出来,所以,我相信可能通过优化,避免我前面说的:写很多很多枯燥无用的代码,通过对ResultSet进行封装,产生一个Bean,然后在页面通过column name直接获得值,这样我们要写的代码会大大减少,缩短我们的开发时间,也让我们觉得,现在做的只是为了写代码更方便,当作一种享受,不要重复发明轮子而已。 至于你说的什么一对多,请不要把Hibernate的理念搬到这里回复,因为我并不使用Hibernate,也不存在什么一对多,这个Bean的产生,只是跟你写的sql有关系,你sql怎么写,你返回什么字段,这个Bean就生成相应字段的Get方法,sql你已经确定,至于什么一对多,多对多,是在你写sql前的事 我这样做是为了写更少的代码 可是最普遍的表结构都是一对多的关系,你不用hibernate只要使用数据库也肯定会碰到一对多关系。怎么可能会没有呢? 例子:界面需求就是简单的将一个一对多的数据展现出来,可是你的简单的键值对的bean无法满足这个要求,最简单的例子,班级表和学生表,界面上要展示出班级名称和对应学生s的名称,用你的方法,怎么用一条sql查询出来然后整合到一个bean中去呢?你是不是要拆开来用两个方法去查呢,分别得到班级名称和学生数据集合呢? 而hibernate直接可以简单写一个查出班级的代码,之后直接在界面导航出学生列表。 你觉得哪个省代码呢?想要省代码应该先从宏观上,上层上去考虑。
有两张表: create table test_class ( `class_id` int(11) auto_increment primary key, `class_name` varchar(50) NOT NULL default '', `class_level` varchar(50) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=gbk; create table test_student ( `student_id` int(11) auto_increment primary key, `class_id` int(11) not null default '0', `student_name` varchar(50) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=gbk;
假设你要显示班级及其学生,需要执行两条sql: select class_id, class_name, class_level from test_class;
select student_id, student_name from test_student where class_id = ${class_id}
第一句,查出class,系统自动封装出一个List,list里保存了这样一个JavaBean,这个JavaBean包含班级的信息,代码类似这样(这个类是动态的,不是硬编码写出来的): class Record{ public String getClass_id(){} public String getClass_name(){} public String getClass_level(){} } 假设这个List保存在request,名字为list,那么,我在页面上如此遍历它: <c:foreach item="${requestScope.list}" var="item"> <h1>班级名:${item.class_name}<h1> <h1>班级级别:${item.class_level}<h1> <table> <tr> <th>学生编号</th> <th>学生姓名</th> </tr> <%-- 这里执行第二条sql,根据class_id查到所有学生,假设保存在request,名字为stulist,遍历这个list,显示所有学生 --%> <c:foreach item="${requestScope.stulist}" var="stu"> <tr> <td>${item.student_id}</t> <td>${item.student_name}</t> </tr> </c:foreach> </table> </c:foreach> Hibernate同样会执行这两条sql,只是不用你手动去调用而已。 而我说的问题是:怎么样实现我上面的显示效果,直接用列名访问数据. 你的sql甚至可以这样写: select test_class.class_name, test_class.class_level, test_student.student_id, test_student.student_name from test_class, test_student where test_class.class_id = test_student.class_id 只要最后能让我用上面的格式来显示结果就可以了。 至于数据类型,你可以在显示时再转换成跟数据库一样的类型,再进行特别的处理,这也属于显示问题了。 我只是想减轻显示时的代码量,不涉及到其他表的对应关系
1、Hibernate同样会执行这两条sql,只是不用你手动去调用而已。 2、我只是想减轻显示时的代码量,不涉及到其他表的对应关系
3、而我说的问题是:怎么样实现我上面的显示效果,直接用列名访问数据. 你的这种方法怎么做大家都有回答,直接map就可以,而我回这么多的目的是想告诉你你确实可以简单的、局部的省些代码,可是从总体上,宏观上考虑,你的这个省代码是以没有复杂需求的情况下才成立,没有表的关系在里面的时候才成立,可是这是实际项目中不可能的。遇到普遍的一对多关系就需要写两个sql,放在两个业务逻辑方法里面,从总体上来说代码并没有省。 突然发现,例子中你居然mvc都没有使用,界面展示到半道才又去数据库中取数据,或许也只有这样你才能查到特定班级的特定学生列表吧,如果用mvc呢,你的界面逻辑还会这么简单吗? 到此为止吧,呵呵,我只是想说的是省代码应该从宏观上考虑,开发前首先要有固定的领域模型,简单的键值对的形式会增加代码维护成本,而且更不容易适应需求的变化,省代码并是不少写几行代码那么简单,应该从面向对象上,封装、复用上去考虑,如果你暂时省了几行代码,可是没几天需求变了,你的键值对的代码改动面积相对于hibernate大的多,应该就不算是省代码了吧。 我只是想表达这个意思,没有别的意思哈,你的这个创意不错,呵呵,我只是想将你的兴趣转移到对项目整体有利的方向上去,哈哈,见笑~
|
|
返回顶楼 | |
发表时间:2010-04-03
感谢aaa5131421,非常感谢!!
|
|
返回顶楼 | |
发表时间:2010-05-12
看这各个朋友滔滔不绝呀,我现在写了一个查询分页的标签,准备前台是用jstl的c标签和el表达式来取值的。大体上是这样的,
提供一个工具类,用户给定包名,类名,一个查询的sql语句,然后根据这些查询的sql语句的表字段来生成一个javabean对象,也就是说,这个javabean的字段就是数据库表的字段,类型也一致,页面上取值也就和LZ你说的一样了。 |
|
返回顶楼 | |
发表时间:2010-05-12
aaa5131421 写道 你这种编码的随意性就太大了,开发前就不需要完整的实体模型设计,开发者想用什么字段整合成一个对象都可以,让后期其他人怎么去维护呢?
这样的情况好hibernate做的比较好,开发前有个固定的模型设计,你查出来的都是固定结构化了对象,更何况你要是在一对多的情况下你怎么生成一个bean呢?难道还要查出多个不同的对象出来?本来通过hibernate的关系就可以用。导航出来的东西,你会多出好多的代码 我比较同意以上的观点。你查询出来的一个MAP封装你想要的数据,你觉得非常cool,设想一下,当下一位维护者来维护这套代码的时候真的是连死的心都有,可以想到,他会慢慢敲开MAP的门,然后悄悄的问:“嘿,你这个MAP里装的是什么呀”,MAP回答:“你自己看查询sql噻”。而如果采用实体bean,直接查看bean他就能清楚知道查询返回了什么 对大量使用MAP返回数据的人严重鄙视。这是一种不负责的做法 |
|
返回顶楼 | |
发表时间:2010-05-15
回楼上,首先说一下我的实现方法: select username, password from users 通过对ResultSet封装,产生类似这样一个Map: List<Map> results = new ArrayList<Map>(2); Map map = new HashMap(2); map.put("userName", "abc"); map.put("passWord", "cba"); results.add(map); map = new HashMap(2); map.put("userName", "efg"); map.put("passWord", "gfe"); results.add(map); 然后我在页面上如此显示结果: <c:foreach item="${list}" var="user"> <h1>UserName:${user.userName}</h1> <h1>Password:${user.passWord}</h1> </c:foreach> 如果使用JavaBean,那行先写个Bean Class: public class User { private String userName; private String passWord; get...; set...; get.......; set.......; } 在执行完sql后,手动编码封装结果进JavaBean,要写这样的代码: List<User> userList; foreach resultset { User user = new User(); user.setUserName(username); user.setPassWord(password); userList.add(user); } 最后页面显示跟上面一样。 在我接触的一些产品项目中,JavaBean是很单纯的,就一些get set方法,set完后就在页面get出来显示就完了,最多就在页面上处理一下,不会有很多复杂的操作,每一次做一张新表,都有以下步骤: 1、写一个很难看的JavaBean(我认为很难看),就只有get set方法; 2、调用完sql后,手动编码来封装成一个JavaBean,返回List到页面; 3、在页面上调用显示出来;
我想说的是,无论如何,开发者都会清楚,这里返回的结果,是执行了什么sql得到的,也就是用户会直观看到甚至直接参与sql语句的编写维护工作,假设:现在新的开发者在users表加了一个字段(login_time),他想要显示出来,按我的方法,两步,1:改sql语句,2:改显示的JSP页面,按传统的做法:1、在JavaBean加上get set方法,2、改sql语句,并手动再添加上封装loginTime的结果到JavaBean,3、改显示的JSP页面;
开发者还是要知道,里面执行了什么sql语句,并且,用传统的方法,要写让人感到无比重复厌烦的JavaBean代码,我个人深恶痛绝这样的编码方式(当然,你用Hibernate就没得说了)。 可以想到,他会慢慢敲开MAP的门,然后悄悄的问:“嘿,你这个MAP里装的是什么呀”,MAP回答:“你自己看查询sql噻”,而如果采用实体bean,直接查看bean他就能清楚知道查询返回了什么 在新的开发者维护这些代码前,返回的JavaBean里只有username跟password,这时,他看到JaveBean里有一个getLoginTime()方法,他马上就在页面上写:
<h1>LoginTime:${user.loginTime}</h1>
这样行吗,一定不行,因为sql可能只返回了两个字段:username and password,这样他就要改sql语句了,那他就一定得去看执行的那句sql,他就清楚要怎么做才能得到他想要的结果。 既然避免不了要维护sql,为什么不做得更简单一点呢,而且我也没看到有什么不负责任的东西在里面,这就是我的想法! |
|
返回顶楼 | |
发表时间:2010-05-15
使用Hibernate的朋友不要再把Hibernate的一套搬出来回复我,我暂时没看到它的好处!
|
|
返回顶楼 | |
发表时间:2010-05-15
呵呵,对于我刚才的那些做法,有什么不同想法的,请回复一下指正,感激感激!!
|
|
返回顶楼 | |
发表时间:2010-05-15
最后修改:2010-05-15
引用 在我接触的一些产品项目中,JavaBean是[color]很单纯的[/color],就一些get set方法,set完后就在页面get出来显示就完了,最多就在页面上处理一下,不会有很多复杂的操作,每一次做一张新表,都有以下步骤:
public class Z{ private Date t = null; set...... public String getTime(){ return DateFormater(t).pase("hh:mi"); } public int getWeekDay(){ return Clender(t).weekDay(); } public Date[] getStarEnd(){ Date[] se = new Date[2]; ............. return se; } } 还有国际化。。。。。 还有返回Enum 还有连接式树节点。 我承认大多数BEAN没逻辑,也没必要存在。 但还是有那么一些需要逻辑处理的。 |
|
返回顶楼 | |