`

《研磨struts2》第十二章 CRUD综合运用 之 12.2 实现域对象和数据层

 
阅读更多

12.2  实现域对象和数据层

12.2.1  建表和域对象

在示例中只需要管理用户的基本信息,用户编号(userId)、姓名(name)、性别(sex)、年龄(age)即可,在mysql中,可以用下面的语句建表:

 

java代码:
  1. create table tbl_user(  
  2.        userId int primary key,  
  3.        name varchar(20),  
  4.        sex varchar(10),  
  5.        age int  
  6. ) character set =gb2312;  

在上面的语句中,建立了一张表叫tbl_user,分别有4个字段:

  • userId:整数类型,是这张表的主键。
  • name:字符类型。注意:varchar后面的20表示这个字段最大可以接受20个字节。
  • sex:字符类型。
  • age:整数类型。

建表语句后面的“character set =gb2312”,是用来设置该表的字符集,使其能够支持中文,跟在后面连接数据库连接语句里面设置的字符集相对应。

建表之后,就可以建立与它相对应的域对象了。在建立域对象的时候,通常的实现方式是:表对应域对象的类,表的每个字段对应类中的一个属性并且为这个属性配备相应的getter/setter方法,表中的主键字段要用来生成hashCode方法和equals方法。域对象的示例代码为:

 

java代码:
  1. public class UserModel {  
  2.     private int userId;  
  3.     private String name;  
  4.     private String sex;  
  5.     private int age;  
  6.       
  7.     public int getUserId() {  
  8.         return userId;  
  9.     }  
  10.     public void setUserId(int userId) {  
  11.         this.userId = userId;  
  12.     }  
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.     public void setName(String name) {  
  17.         this.name = name;  
  18.     }  
  19.     public String getSex() {  
  20.         return sex;  
  21.     }  
  22.     public void setSex(String sex) {  
  23.         this.sex = sex;  
  24.     }  
  25.     public int getAge() {  
  26.         return age;  
  27.     }  
  28.     public void setAge(int age) {  
  29.         this.age = age;  
  30.     }  
  31.       
  32.     public int hashCode() {  
  33.         final int prime = 31;  
  34.         int result = 1;  
  35.         result = prime * result + userId;  
  36.         return result;  
  37.     }  
  38.       
  39.     public boolean equals(Object obj) {  
  40.         if (this == obj)  
  41.             return true;  
  42.         if (obj == null)  
  43.             return false;  
  44.         if (getClass() != obj.getClass())  
  45.             return false;  
  46.         final UserModel other = (UserModel) obj;  
  47.         if (userId != other.userId)  
  48.             return false;  
  49.         return true;  
  50.     }     
  51. }  

12.2.2  建立条件组合对象

在查询的时候,通常需要实现用户可以自由组合查询条件的功呢,也就是用户自由组合使用多个查询条件中的一项或某几项。

比如,在查询用户信息的时候,可以指定如下查询条件:按照用户编号精确查询;按照姓名模糊查询(输入“李”可以查出所有名字中带有“李”字的用户);按性别精确查询;按年龄的范围查询,如15到20之间,或者大于25岁的。

这些条件用户可能都填了,也可能只填其中的某几项,也可能都不填写。那么在做查询的时候,就要去处理用户填写条件的各种组合情况,并把那些符合所有这些条件的记录查询出来。

先不要着急想怎么实现组合查询,第一个问题是用一个什么样的对象来存放这样一组条件呢?

按照上面描述的组合条件,这个对象要包含一个编号(用于精确查询)、一个姓名(用于模糊查询)、一个性别(用于模糊查询)和两个年龄(一个用于存范围的最大值,另一个用于存范围的最小值)。有朋友马上就想到了使用UserModel,但是这里有一个小小的问题,UserModel可以存一个编号、一个姓名、一个性别和一个年龄,可是还少一个年龄属性。

可以简单的如下来实现,做一个UserQueryModel,让它继承UserModel,在UserQueryModel中只写出UserModel缺少的属性(一个年龄),当然它的名字不能叫age,可以叫做age2,这样在查询的时候就使用UserQueryModel,示例代码如下:

 

java代码:
  1. public class UserQueryModel extends UserModel {  
  2.     private int age2;  
  3.     public int getAge2() {  
  4.         return age2;  
  5.     }  
  6.     public void setAge2(int age2) {  
  7.         this.age2 = age2;  
  8.     }  
  9. }  

12.2.3  实现数据层

使用JDBC作为这次示例的数据层,但是JDBC并不是本书的介绍重点。因此,这里只是简单的给出其实现,如果读者没有JDBC基础,请查阅JDBC的相关资料。

       为了实现最终的增删改查的目标,数据层必须实现以下功能:

  • 增:添加一条新的记录。
  • 改:按照主键修改一条已有记录。
  • 删:按照主键删除一条已有记录。
  • 查一条:按照主键查询出一条已有记录。
  • 查全部:查出所有已有记录。
  • 按条件查:按照组合条件查出所有符合条件的记录。

要实现数据层首先就要获得数据库的连接,这里用的是apache的简单数据源BasicDataSource实现,只需要指定驱动类、数据库的地址、用户名和密码即可,最终返回一个DataSource对象,示例代码如下:

 

java代码:
  1. public class DataSourceHolder {  
  2.     private BasicDataSource ds = new BasicDataSource();  
  3.        
  4.     private DataSourceHolder(){  
  5.         ds.setDriverClassName("org.gjt.mm.mysql.Driver");  
  6.         ds.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gb2312");  
  7.         ds.setUsername("root");  
  8.         ds.setPassword("");  
  9.     }  
  10.     private static class SingletonHolder{  
  11.         private static DataSourceHolder instance = new DataSourceHolder();  
  12.     }     
  13.     public static  DataSourceHolder getInstance(){  
  14.         return SingletonHolder.instance;  
  15.     }  
  16.     public  DataSource getDataSource(){  
  17.         return ds;  
  18.     }  
  19. }  

上面的DataSourceHolder实现成了一个单例,这里用的是“Lazy initialization holder class模式”来实现的单例,不了解的朋友可以参见拙著《研磨设计模式》的单例模式一章,或者是参阅其他的相关资料。

接下来,开始正式实现数据层的各个方法:

1:实现添加一条新的记录,示例代码如下:

 

java代码:
  1. public void create(UserModel user){  
  2.     Connection conn = null;  
  3.     try {  
  4.         conn = DataSourceHolder.getInstance().getDataSource().getConnection();  
  5.         final String sql = "insert into tbl_user(userId,name,sex,age) values(?,?,?,?)";  
  6.         PreparedStatement ps = conn.prepareStatement(sql);  
  7.         int count = 1;  
  8.         ps.setInt(count++, user.getUserId());  
  9.         ps.setString(count++, user.getName());  
  10.         ps.setString(count++, user.getSex());  
  11.         ps.setInt(count++, user.getAge());  
  12.         ps.execute();  
  13.           
  14.         ps.close();  
  15.     } catch (Exception e) {  
  16.         e.printStackTrace();  
  17.     } finally {  
  18.         try {  
  19.             conn.close();  
  20.         } catch (SQLException e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.     }         
  24. }  

2:实现按照主键修改一条已有记录,示例代码如下:

 

java代码:
  1. public void update(UserModel user){  
  2.     Connection conn = null;  
  3.     try {  
  4.         conn = DataSourceHolder.getInstance().getDataSource().getConnection();  
  5.         final String sql = "update tbl_user set name=?,sex=?,age=? where userId=?";  
  6.         PreparedStatement ps = conn.prepareStatement(sql);  
  7.         int count = 1;  
  8.         ps.setString(count++, user.getName());  
  9.         ps.setString(count++, user.getSex());  
  10.         ps.setInt(count++, user.getAge());  
  11.         ps.setInt(count++, user.getUserId());  
  12.         ps.execute();  
  13.           
  14.         ps.close();  
  15.     } catch (Exception e) {  
  16.         e.printStackTrace();  
  17.     } finally {  
  18.         try {  
  19.             conn.close();  
  20.         } catch (SQLException e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.     }         
  24. }  

3:实现按照主键删除一条已有记录,示例代码如下:

 

java代码:
  1. public void delete(int userId){  
  2.     Connection conn = null;  
  3.     try {  
  4.         conn = DataSourceHolder.getInstance().getDataSource().getConnection();  
  5.         final String sql = "delete from tbl_user where userId=?";  
  6.         PreparedStatement ps = conn.prepareStatement(sql);  
  7.         ps.setInt(1, userId);  
  8.         ps.execute();  
  9.           
  10.         ps.close();  
  11.     } catch (Exception e) {  
  12.         e.printStackTrace();  
  13.     } finally {  
  14.         try {  
  15.             conn.close();  
  16.         } catch (SQLException e) {  
  17.             e.printStackTrace();  
  18.         }  
  19.     }         
  20. }  

4:事先按照主键查询出一条已有记录的功能,示例代码如下:

 

java代码:
  1. public UserModel getSingle(int userId){  
  2.     UserModel user = null;  
  3.     Connection conn = null;  
  4.     try {  
  5.         conn = DataSourceHolder.getInstance().getDataSource().getConnection();  
  6.         final String sql = "select * from tbl_user where userId=?";  
  7.         PreparedStatement ps = conn.prepareStatement(sql);  
  8.         ps.setInt(1, userId);  
  9.         ResultSet rs = ps.executeQuery();  
  10.         if(rs.next()){  
  11.             user = this.rs2model(rs);  
  12.         }  
  13.           
  14.         rs.close();  
  15.         ps.close();  
  16.     } catch (Exception e) {  
  17.         e.printStackTrace();  
  18.     } finally {  
  19.         try {  
  20.             conn.close();  
  21.         } catch (SQLException e) {  
  22.             e.printStackTrace();  
  23.         }  
  24.     }         
  25.     return user;  
  26. }  
  27. private UserModel rs2model(ResultSet rs) throws Exception{  
  28.     UserModel user = new UserModel();  
  29.     user.setUserId(rs.getInt("userId"));  
  30.     user.setName(rs.getString("name"));  
  31.     user.setSex(rs.getString("sex"));  
  32.     user.setAge(rs.getInt("age"));  
  33.     return user;  
  34. }  

在里面实现了一个私有方法rs2model,用来把从数据库获取的一条记录,转换成为一个UserModel的对象。这是个多个方法公用的方法,因此把这些公共的功能提出来实现成为私有方法。

5:实现查出所有已有记录的功能,示例如下:

 

java代码:
  1. public List<UserModel> getAll(){  
  2.     List<UserModel> list = new ArrayList<UserModel>();  
  3.     Connection conn = null;  
  4.     try {  
  5.         conn = DataSourceHolder.getInstance().getDataSource().getConnection();  
  6.         final String sql = "select * from tbl_user order by userId";  
  7.         PreparedStatement ps = conn.prepareStatement(sql);  
  8.         ResultSet rs = ps.executeQuery();  
  9.         while (rs.next()){  
  10.             UserModel user = this.rs2model( rs);  
  11.             list.add(user);  
  12.         }  
  13.           
  14.         rs.close();  
  15.         ps.close();  
  16.     } catch (Exception e) {  
  17.         e.printStackTrace();  
  18.     } finally {  
  19.         try {  
  20.             conn.close();  
  21.         } catch (SQLException e) {  
  22.             e.printStackTrace();  
  23.         }  
  24.     }         
  25.     return list;  
  26. }  

6:实现按照组合条件查出所有符合条件的记录。实现这个功能会稍微麻烦一点,首要的问题就是用户输入的条件是不确定的,因此查询用的sql也就不能确定了,那么怎么实现呢?

方法是动态的拼接sql,根据用户输入的条件来拼接sql,如果用户输入了某个条件值,那么就在sql上拼接该条件,如果用户没有输入,那么就不用在sql上拼接这个条件。具体的实现请参看generateWhere方法。示例代码如下:

 

java代码:
  1. /** 
  2.  * 根据UserQueryModel中的数据情况动态生成对应的条件语句 
  3.  * @param uqm 封装查询条件数据的模型 
  4.  * @return 按照查询条件数据来动态生成的条件语句 
  5.  */  
  6. private String generateWhere(UserQueryModel uqm){  
  7.     StringBuffer buffer = new StringBuffer();  
  8.     //用户是否选用用户编号作为条件  
  9.     if (uqm.getUserId()>0){  
  10.         buffer.append(" and userId = ?");  
  11.     }  
  12.     //用户是否选用用户姓名作为条件  
  13.     if (uqm.getName()!=null&&uqm.getName().trim().length()>0){  
  14.         buffer.append(" and name like ?");  
  15.     }  
  16.     //用户是否选用性别作为条件  
  17.     if (uqm.getSex()!=null&&uqm.getSex().trim().length()>0){  
  18.         buffer.append(" and sex = ?");  
  19.     }  
  20.     //用户是否选用年龄范围最小值作为条件  
  21.     if (uqm.getAge()>0){  
  22.         buffer.append(" and age >= ?");  
  23.     }  
  24.     //用户是否选用年龄范围最大值作为条件  
  25.     if (uqm.getAge2()>0){  
  26.         buffer.append(" and age <= ?");  
  27.     }  
  28.     return buffer.toString();  
  29. }  

另外一个问题,由于sql是动态拼接出来的,那么向sql传入参数的过程也不能固定,同样按照动态拼接sql的方式,来动态的设置sql的参数。具体的实现请参看preparePs方法。示例代码如下:

 

java代码:
  1. /** 
  2.  * 向sql语句中的"?" 设置参数值 
  3.  * @param uqm 封装查询条件数据的模型 
  4.  * @param ps PreparedStatement 对象 
  5.  */  
  6. private void preparePs(UserQueryModel uqm,PreparedStatement ps) throws SQLException{  
  7.     int count = 1;  
  8.     if (uqm.getUserId()>0){  
  9.         ps.setInt(count++, uqm.getUserId());  
  10.     }  
  11.     if (uqm.getName()!=null&&uqm.getName().trim().length()>0){  
  12.         ps.setString(count++, "%"+uqm.getName()+"%");  
  13.     }  
  14.     if (uqm.getSex()!=null&&uqm.getSex().trim().length()>0){  
  15.         ps.setString(count++, uqm.getSex());  
  16.     }  
  17.     if (uqm.getAge()>0){  
  18.         ps.setInt(count++, uqm.getAge());  
  19.     }  
  20.     if (uqm.getAge2()>0){  
  21.         ps.setInt(count++, uqm.getAge2());  
  22.     }  
  23. }  

再来看看按条件查询功能的实现,示例代码如下:

 

java代码:
  1. public List<UserModel> getByCondition(UserQueryModel uqm){  
  2.     List<UserModel> list = new ArrayList<UserModel>();  
  3.     Connection conn = null;  
  4.       
  5.     try {  
  6.         conn = DataSourceHolder.getInstance().getDataSource().getConnection();  
  7.         //调用前面定义的生成where语句的方法  
  8.            //由于不知道UserQueryModel中属性值的情况  
  9.            //所以必须在sql语句的主题中添上恒成立条件1=1  
  10.         final String sql = "select * from tbl_user where 1=1 " + this.generateWhere(uqm) + " order by userId";  
  11.         PreparedStatement ps = conn.prepareStatement(sql);  
  12.         //调用前面定义的向PrepareStatment赋值的方法  
  13.         this.preparePs(uqm, ps);  
  14.         ResultSet rs = ps.executeQuery();  
  15.         while (rs.next()){  
  16.             UserModel user = this.rs2model(rs);  
  17.             list.add(user);  
  18.         }  
  19.         rs.close();  
  20.         ps.close();  
  21.     } catch (Exception e) {  
  22.         e.printStackTrace();  
  23.     } finally {  
  24.         try {  
  25.             conn.close();  
  26.         } catch (SQLException e) {  
  27.             e.printStackTrace();  
  28.         }  
  29.     }  
  30.     return list;  
  31. }  

 

私塾在线网站原创《研磨struts2》系列

转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4101.html

欢迎访问http://sishuok.com获取更多内容

6
5
分享到:
评论

相关推荐

    在Struts 2中实现CRUD

    ### Struts 2中实现CRUD操作详解 #### 一、引言 CRUD操作是软件开发中最常见的数据处理方式之一,它代表了对数据进行的四种基本操作:创建(Create)、读取(Read)、更新(Update)与删除(Delete)。在企业级应用开发中,...

    Java Struts2 实现CRUD

    Struts2是Java Web开发中一个非常流行的MVC框架,它极大地简化了Web应用程序的构建,特别是对于实现CRUD(创建、读取、更新、删除)操作。在本篇文章中,我们将深入探讨如何使用Java Struts2框架来完成这些基本的...

    带struts2和hibernate的crud小demo

    这个"带Struts2和Hibernate的CRUD小Demo"是一个实用的学习资源,它演示了如何将这两个框架集成以实现数据的创建、读取、更新和删除(CRUD)操作。 首先,Struts2是一个开源的MVC(Model-View-Controller)框架,它...

    Struts2-Crud+JdbcDemo最简单的Struts2+jdbc学习曾删改查程序

    这个"Struts2-Crud+JdbcDemo"项目是一个基础的学习示例,涵盖了如何使用Struts2和JDBC进行基本的CRUD(创建、读取、更新和删除)操作。 首先,我们来详细了解一下Struts2的核心概念: 1. **Action类**:在Struts2...

    struts2与hibernate的整合实现数据的crud

    Struts2和Hibernate是两种非常流行的Java开源框架,它们分别用于MVC(Model-View-Controller)架构的控制层和持久层的管理。Struts2提供了强大的动作调度和页面渲染能力,而Hibernate则是面向对象的数据库映射工具,...

    Struts2整合Spring Hibernate的CRUD实例

    在"Struts2整合Spring Hibernate的CRUD实例"中,我们将探讨如何将这三个框架无缝集成,实现对数据库的数据创建(Create)、读取(Read)、更新(Update)和删除(Delete)操作。下面将详细介绍这个实例中的关键知识...

    struts2CRUD

    Struts2 CRUD是一个基于Apache Struts2框架实现的创建、读取、更新和删除(Create, Read, Update, Delete)操作的示例项目。这个项目主要用于演示如何在Web应用程序中使用Struts2来处理基本的数据操作。Struts2是...

    Struts实现CRUD操作

    在Struts框架中,CRUD操作的实现往往涉及到视图(JSP)、控制(Action)和服务(Business Logic)三层的协作。Struts提供的强大配置和拦截器机制使得这些操作的实现变得简单且易于维护。Struts_CRUD_Test压缩包可能...

    struts2 CRUD

    Struts2 CRUD是一个典型的Java Web开发中的概念,它涉及到Model-View-Controller(MVC)设计模式的应用,以及使用Struts2框架实现对单一数据库表的创建(Create)、读取(Retrieve)、更新(Update)和删除(Delete)功能。...

    Spring4-Struts2-Hibernate4 CRUD Demo_5

    【Spring4-Struts2-Hibernate4 CRUD Demo_5】是一个综合性的开发示例,它展示了如何在Java Web应用程序中整合三大主流框架:Spring 4、Struts2和Hibernate4,进行基本的数据创建(Create)、读取(Read)、更新...

    strutsCRUD1.rar_crud struts_struts1 crud_strutsCRUD1

    在本示例中,"strutsCRUD1.rar" 是一个包含Struts1实现CRUD操作的项目压缩包。CRUD代表创建(Create)、读取(Retrieve)、更新(Update)和删除(Delete),这是数据库操作的基本功能。 首先,让我们讨论一下Struts1的核心...

    Spring4-Struts2-Hibernate4 CRUD Demo_3

    【Spring4-Struts2-Hibernate4 CRUD Demo_3】是一个综合性的开发示例,它展示了如何在Java Web应用程序中整合三大主流框架:Spring 4、Struts 2和Hibernate 4来实现CRUD(创建、读取、更新、删除)操作。这个Demo...

    使用Struts2和jQuery EasyUI实现简单CRUD系统

    在本文中,我们将探讨如何使用Struts2和jQuery EasyUI框架创建一个简单的CRUD(创建、读取、更新、删除)系统。首先,我们需要理解这两个技术的基础概念。 Struts2是一个基于MVC(Model-View-Controller)架构的...

    Struts2实现CRUD(增删改查)Maven版

    Struts2实现CRUD(增 删 改 查) Maven版; eclipse直接导入使用; 教程地址:http://blog.csdn.net/sky_zhangfan/article/details/1896842

    ext3+struts2+hibernate+spring的CRUD+分页

    "ext3+struts2+hibernate+spring的CRUD+分页"是一个典型的Java Web开发组合,用于实现全面的数据管理功能。这个组合充分利用了各个框架的优势,提供了一个强大的后端数据处理和前端展示的解决方案。 首先,EXT3是一...

    Struts2_CRUD.rar_Struts2_CRUD_Struts2的增改删查 操作 示例_struts2_struts2

    综上所述,"Struts2_CRUD"示例涵盖了使用Struts2框架进行基本数据操作的核心概念和实践。通过学习这个示例,初学者可以理解如何在Struts2中组织Action、Form、Interceptor、配置文件和视图,以及如何实现CRUD操作和...

    struts2+hibernate原理写的CRUD

    本项目“struts2+hibernate原理写的CRUD”是一个基于这两个框架实现的简单但完整的数据操作示例,包括创建(Create)、读取(Retrieve)、更新(Update)和删除(Delete)功能,同时具备了分页和分页跳转功能,适用于部门...

    使用Struts2实现的销售单CRUD

    在这个"使用Struts2实现的销售单CRUD"项目中,我们将深入探讨如何利用Struts2进行创建(Create)、读取(Retrieve)、更新(Update)和删除(Delete)操作,即常说的CRUD操作,针对销售单数据。 首先,理解CRUD操作的基本...

    struts2+hibernate 实现的CRUD

    在实现CRUD操作时,通常会结合Struts2的Action类和Hibernate的Session。例如,创建新记录时,Action类接收前端传来的参数,调用SessionFactory创建Session,然后通过Session的save()方法将对象保存到数据库。读取...

Global site tag (gtag.js) - Google Analytics