- 浏览: 302963 次
最新评论
-
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
nucleus:
为什么都是没有图的。。。。。。。求图片啊
《研磨struts2》第七章 值栈和OGNL 之 7.4 ActionContext和ServletActionContext -
hunanjun000:
《研磨struts2》第四章 Action 之 4.5 Action的其它重要知识
12.2 实现域对象和数据层
12.2.1 建表和域对象
在示例中只需要管理用户的基本信息,用户编号(userId)、姓名(name)、性别(sex)、年龄(age)即可,在mysql中,可以用下面的语句建表:
在上面的语句中,建立了一张表叫tbl_user,分别有4个字段:
- userId:整数类型,是这张表的主键。
- name:字符类型。注意:varchar后面的20表示这个字段最大可以接受20个字节。
- sex:字符类型。
- age:整数类型。
建表语句后面的“character set =gb2312”,是用来设置该表的字符集,使其能够支持中文,跟在后面连接数据库连接语句里面设置的字符集相对应。
建表之后,就可以建立与它相对应的域对象了。在建立域对象的时候,通常的实现方式是:表对应域对象的类,表的每个字段对应类中的一个属性并且为这个属性配备相应的getter/setter方法,表中的主键字段要用来生成hashCode方法和equals方法。域对象的示例代码为:
- public class UserModel {
- private int userId;
- private String name;
- private String sex;
- private int age;
- public int getUserId() {
- return userId;
- }
- public void setUserId(int userId) {
- this.userId = userId;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getSex() {
- return sex;
- }
- public void setSex(String sex) {
- this.sex = sex;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + userId;
- return result;
- }
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final UserModel other = (UserModel) obj;
- if (userId != other.userId)
- return false;
- return true;
- }
- }
12.2.2 建立条件组合对象
在查询的时候,通常需要实现用户可以自由组合查询条件的功呢,也就是用户自由组合使用多个查询条件中的一项或某几项。
比如,在查询用户信息的时候,可以指定如下查询条件:按照用户编号精确查询;按照姓名模糊查询(输入“李”可以查出所有名字中带有“李”字的用户);按性别精确查询;按年龄的范围查询,如15到20之间,或者大于25岁的。
这些条件用户可能都填了,也可能只填其中的某几项,也可能都不填写。那么在做查询的时候,就要去处理用户填写条件的各种组合情况,并把那些符合所有这些条件的记录查询出来。
先不要着急想怎么实现组合查询,第一个问题是用一个什么样的对象来存放这样一组条件呢?
按照上面描述的组合条件,这个对象要包含一个编号(用于精确查询)、一个姓名(用于模糊查询)、一个性别(用于模糊查询)和两个年龄(一个用于存范围的最大值,另一个用于存范围的最小值)。有朋友马上就想到了使用UserModel,但是这里有一个小小的问题,UserModel可以存一个编号、一个姓名、一个性别和一个年龄,可是还少一个年龄属性。
可以简单的如下来实现,做一个UserQueryModel,让它继承UserModel,在UserQueryModel中只写出UserModel缺少的属性(一个年龄),当然它的名字不能叫age,可以叫做age2,这样在查询的时候就使用UserQueryModel,示例代码如下:
12.2.3 实现数据层
使用JDBC作为这次示例的数据层,但是JDBC并不是本书的介绍重点。因此,这里只是简单的给出其实现,如果读者没有JDBC基础,请查阅JDBC的相关资料。
为了实现最终的增删改查的目标,数据层必须实现以下功能:
- 增:添加一条新的记录。
- 改:按照主键修改一条已有记录。
- 删:按照主键删除一条已有记录。
- 查一条:按照主键查询出一条已有记录。
- 查全部:查出所有已有记录。
- 按条件查:按照组合条件查出所有符合条件的记录。
要实现数据层首先就要获得数据库的连接,这里用的是apache的简单数据源BasicDataSource实现,只需要指定驱动类、数据库的地址、用户名和密码即可,最终返回一个DataSource对象,示例代码如下:
- public class DataSourceHolder {
- private BasicDataSource ds = new BasicDataSource();
- private DataSourceHolder(){
- ds.setDriverClassName("org.gjt.mm.mysql.Driver");
- ds.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gb2312");
- ds.setUsername("root");
- ds.setPassword("");
- }
- private static class SingletonHolder{
- private static DataSourceHolder instance = new DataSourceHolder();
- }
- public static DataSourceHolder getInstance(){
- return SingletonHolder.instance;
- }
- public DataSource getDataSource(){
- return ds;
- }
- }
上面的DataSourceHolder实现成了一个单例,这里用的是“Lazy initialization holder class模式”来实现的单例,不了解的朋友可以参见拙著《研磨设计模式》的单例模式一章,或者是参阅其他的相关资料。
接下来,开始正式实现数据层的各个方法:
1:实现添加一条新的记录,示例代码如下:
- public void create(UserModel user){
- Connection conn = null;
- try {
- conn = DataSourceHolder.getInstance().getDataSource().getConnection();
- final String sql = "insert into tbl_user(userId,name,sex,age) values(?,?,?,?)";
- PreparedStatement ps = conn.prepareStatement(sql);
- int count = 1;
- ps.setInt(count++, user.getUserId());
- ps.setString(count++, user.getName());
- ps.setString(count++, user.getSex());
- ps.setInt(count++, user.getAge());
- ps.execute();
- ps.close();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
2:实现按照主键修改一条已有记录,示例代码如下:
- public void update(UserModel user){
- Connection conn = null;
- try {
- conn = DataSourceHolder.getInstance().getDataSource().getConnection();
- final String sql = "update tbl_user set name=?,sex=?,age=? where userId=?";
- PreparedStatement ps = conn.prepareStatement(sql);
- int count = 1;
- ps.setString(count++, user.getName());
- ps.setString(count++, user.getSex());
- ps.setInt(count++, user.getAge());
- ps.setInt(count++, user.getUserId());
- ps.execute();
- ps.close();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
3:实现按照主键删除一条已有记录,示例代码如下:
- public void delete(int userId){
- Connection conn = null;
- try {
- conn = DataSourceHolder.getInstance().getDataSource().getConnection();
- final String sql = "delete from tbl_user where userId=?";
- PreparedStatement ps = conn.prepareStatement(sql);
- ps.setInt(1, userId);
- ps.execute();
- ps.close();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
4:事先按照主键查询出一条已有记录的功能,示例代码如下:
- public UserModel getSingle(int userId){
- UserModel user = null;
- Connection conn = null;
- try {
- conn = DataSourceHolder.getInstance().getDataSource().getConnection();
- final String sql = "select * from tbl_user where userId=?";
- PreparedStatement ps = conn.prepareStatement(sql);
- ps.setInt(1, userId);
- ResultSet rs = ps.executeQuery();
- if(rs.next()){
- user = this.rs2model(rs);
- }
- rs.close();
- ps.close();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- return user;
- }
- private UserModel rs2model(ResultSet rs) throws Exception{
- UserModel user = new UserModel();
- user.setUserId(rs.getInt("userId"));
- user.setName(rs.getString("name"));
- user.setSex(rs.getString("sex"));
- user.setAge(rs.getInt("age"));
- return user;
- }
在里面实现了一个私有方法rs2model,用来把从数据库获取的一条记录,转换成为一个UserModel的对象。这是个多个方法公用的方法,因此把这些公共的功能提出来实现成为私有方法。
5:实现查出所有已有记录的功能,示例如下:
- public List<UserModel> getAll(){
- List<UserModel> list = new ArrayList<UserModel>();
- Connection conn = null;
- try {
- conn = DataSourceHolder.getInstance().getDataSource().getConnection();
- final String sql = "select * from tbl_user order by userId";
- PreparedStatement ps = conn.prepareStatement(sql);
- ResultSet rs = ps.executeQuery();
- while (rs.next()){
- UserModel user = this.rs2model( rs);
- list.add(user);
- }
- rs.close();
- ps.close();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- return list;
- }
6:实现按照组合条件查出所有符合条件的记录。实现这个功能会稍微麻烦一点,首要的问题就是用户输入的条件是不确定的,因此查询用的sql也就不能确定了,那么怎么实现呢?
方法是动态的拼接sql,根据用户输入的条件来拼接sql,如果用户输入了某个条件值,那么就在sql上拼接该条件,如果用户没有输入,那么就不用在sql上拼接这个条件。具体的实现请参看generateWhere方法。示例代码如下:
- /**
- * 根据UserQueryModel中的数据情况动态生成对应的条件语句
- * @param uqm 封装查询条件数据的模型
- * @return 按照查询条件数据来动态生成的条件语句
- */
- private String generateWhere(UserQueryModel uqm){
- StringBuffer buffer = new StringBuffer();
- //用户是否选用用户编号作为条件
- if (uqm.getUserId()>0){
- buffer.append(" and userId = ?");
- }
- //用户是否选用用户姓名作为条件
- if (uqm.getName()!=null&&uqm.getName().trim().length()>0){
- buffer.append(" and name like ?");
- }
- //用户是否选用性别作为条件
- if (uqm.getSex()!=null&&uqm.getSex().trim().length()>0){
- buffer.append(" and sex = ?");
- }
- //用户是否选用年龄范围最小值作为条件
- if (uqm.getAge()>0){
- buffer.append(" and age >= ?");
- }
- //用户是否选用年龄范围最大值作为条件
- if (uqm.getAge2()>0){
- buffer.append(" and age <= ?");
- }
- return buffer.toString();
- }
另外一个问题,由于sql是动态拼接出来的,那么向sql传入参数的过程也不能固定,同样按照动态拼接sql的方式,来动态的设置sql的参数。具体的实现请参看preparePs方法。示例代码如下:
- /**
- * 向sql语句中的"?" 设置参数值
- * @param uqm 封装查询条件数据的模型
- * @param ps PreparedStatement 对象
- */
- private void preparePs(UserQueryModel uqm,PreparedStatement ps) throws SQLException{
- int count = 1;
- if (uqm.getUserId()>0){
- ps.setInt(count++, uqm.getUserId());
- }
- if (uqm.getName()!=null&&uqm.getName().trim().length()>0){
- ps.setString(count++, "%"+uqm.getName()+"%");
- }
- if (uqm.getSex()!=null&&uqm.getSex().trim().length()>0){
- ps.setString(count++, uqm.getSex());
- }
- if (uqm.getAge()>0){
- ps.setInt(count++, uqm.getAge());
- }
- if (uqm.getAge2()>0){
- ps.setInt(count++, uqm.getAge2());
- }
- }
再来看看按条件查询功能的实现,示例代码如下:
- public List<UserModel> getByCondition(UserQueryModel uqm){
- List<UserModel> list = new ArrayList<UserModel>();
- Connection conn = null;
- try {
- conn = DataSourceHolder.getInstance().getDataSource().getConnection();
- //调用前面定义的生成where语句的方法
- //由于不知道UserQueryModel中属性值的情况
- //所以必须在sql语句的主题中添上恒成立条件1=1
- final String sql = "select * from tbl_user where 1=1 " + this.generateWhere(uqm) + " order by userId";
- PreparedStatement ps = conn.prepareStatement(sql);
- //调用前面定义的向PrepareStatment赋值的方法
- this.preparePs(uqm, ps);
- ResultSet rs = ps.executeQuery();
- while (rs.next()){
- UserModel user = this.rs2model(rs);
- list.add(user);
- }
- rs.close();
- ps.close();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- return list;
- }
私塾在线网站原创《研磨struts2》系列
转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4101.html】
欢迎访问http://sishuok.com获取更多内容
发表评论
-
研磨struts2 目录贴
2012-08-24 12:12 162561.1 《研磨struts2》 第一章 Struts2 ... -
跟着cc学设计 之 研磨设计模式 视频教程 出炉了
2012-08-15 07:16 2研磨设计模式——跟着CC学设计系列精品课程,上线了! ... -
研磨struts2 目录
2012-07-30 21:15 2471.1 《研磨struts2》 第一章 Strut ... -
研磨struts2 目录
2012-07-30 16:54 361.1 《研磨struts2》 第一章 Stru ... -
《研磨struts2》A.2 struts.properties的配置 之 A.2.1 概述
2012-07-09 12:10 2985A.2.1 概述 如果我们希望覆盖在 ... -
《研磨struts2》附录A Struts2的配置 之 A.1 struts.xml的配置
2012-07-09 12:10 2669A.1 struts.xml的配置 A.1.1 ... -
《研磨struts2》第二十一章 零配置 之 21.3 通过注解来实现零配置
2012-07-06 08:07 282221.3 通过注解来实现零配置 21.3.1 ... -
《研磨struts2》第二十一章 零配置 之 21.2 约定大于配置
2012-07-05 10:44 238021.2 约定大于配置 21.2.1 约定 ... -
《研磨struts2》第二十一章 零配置 之 21.1 概述
2012-07-05 10:44 221621.1 概述 21.1.1 零配置概述 在 ... -
《研磨struts2》第二十章 整合SiteMesh 之 20.3 整合Struts2与SiteMesh
2012-07-04 08:15 1991在Struts2中使用SiteMesh ... -
《研磨struts2》第二十章 整合SiteMesh 之 20.2 单独使用SiteMesh
2012-07-03 08:00 199420.2 单独使用SiteMesh 20. ... -
《研磨struts2》第二十章 整合SiteMesh 之 20.1 调整应用的风格
2012-07-03 07:59 179920.1 调整应用的风 ... -
《研磨struts2》19.2 使用execAndWait拦截器模拟进度条 之 19.2.1 模拟长时间运行的Action
2012-07-02 12:24 207619.2.1模拟长时间运行的Action ... -
《研磨struts2》第十九章 进度条 之 19.1 使用“进度条”告知用户进度
2012-07-02 12:23 206419.1 使用“进度条”告知用户进度 ... -
《研磨struts2》第十八章 结合JFreeChart 之 18.3 Struts2结合JFreeChart
2012-06-28 12:12 193218.3 Struts2结合JFreeChart ... -
《研磨struts2》第十八章 结合JFreeChart 之 18.2 Struts2插件概述
2012-06-28 12:11 1960Struts2并没有求大求全,企图把所有 ... -
《研磨struts2》第十八章 结合JFreeChart 之 18.1 JFreeChart使用
2012-06-20 15:48 218818.1 JFreeChart使用 18.1.1概 ... -
研磨struts2(1-10章)电子书下载
2012-06-19 07:30 5970研磨struts2的博客文章 私塾在线学习网 《研 ... -
《研磨struts2》第十七章 防止重复提交 之 17.3 更强大的tokenSession拦截器
2012-06-18 13:46 201117.3 更强大的tokenSession拦截器 ... -
《研磨struts2》第十七章 防止重复提交 之 17.2 使用标签
2012-06-18 13:45 229017.2 使用<s:token/>标签 ...
相关推荐
Java Struts2 实现CRUD,供大家一起共同分享学习。
在Struts 2中实现CRUD.pdf
结合hibernate和struts2写的crud小demo
Struts2整合Spring Hibernate的CRUD实例Struts2整合Spring Hibernate的CRUD实例
Struts2-Crud+JdbcDemo最简单的Struts2+jdbc学习曾删改查程序,适合初学Struts2的朋友们
struts2CRUD
Struts2实现CRUD(增 删 改 查) Maven版; eclipse直接导入使用; 教程地址:http://blog.csdn.net/sky_zhangfan/article/details/1896842
struts2与hibernate的整合实现数据的crud操作,还有复选框删除的实例,运用了Jquery的技术。 里面有使用需知,欢迎大家下载。
使用Struts2和jQuery EasyUI实现简单CRUD系统
Spring4-Struts2-Hibernate4 CRUD Demo
Spring4-Struts2-Hibernate4 CRUD Demo_2
struts的crud sample demo(struts-crud.war) 可以直接解压查看代码,或者放到工程中运行
使用Struts2实现的销售单CRUD
基于mvc模型 利用struts2 实现对单表的CRUD操作
Struts2实现CRUD 实用的例子借助Struts2框架开发Web应用会减少大量的代码量
Hibernate+Spring+Struts2+ExtJS开发CRUD功能
通过Struts配置实现增删改查操作,让你了解struts的真正意义!
利用ext3+struts2+hibernate+spring的CRUD+分页这四个框架实现crud,详细说明grid的用法,