• SSH框架整合截图(二)


    客户拜访管理

    1 什么是客户拜访

    (1)客户:与公司有业务往来的

    (2)用户:可以使用系统的人

    2 用户和客户关系

    (1)用户和客户之间是拜访的关系

    (2)用户 和 客户 是 多对多关系

    ** 一个用户可以拜访多个客户,一个客户可以被多个用户拜访

    (3)多对多建表:

    - 创建第三张表,使用外键维护关系

    3 多对多配置

    (1)缺陷:第三张表只有两个字段(两个id值)

    4 把多对多拆分成两个一对多实现
    (1)用户、客户、拜访
    (2)用户 和 拜访是一对多

    (3)客户和拜访是一对多

     

    配置用户和客户关系

    (传统多对多中 是不需要创建中间实体类的  而是在配置文件中  相互表示 然后自动建中间表 这里因为要在中间表中增加额外的属性值,所以不使用之前的方式,创建中间实体类的同时,增加一些其他属性(拜访地址,拜访内容等等),同时使该实体类和user和customer互相表示,即把多对多 拆分为两个一对多,客户和拜访  一对多 , 用户和拜访  一对多  配置时  类比这客户、联系人的关系 一对多  进行配置)

    第一步 创建三个实体类

    第二步 实体类之间互相表示

    (1)用户和拜访一对多

    - 在用户实体类表示所有拜访记录,使用set集合

     

    - 在拜访实体类里面表示所属用户,使用对象

    (2)客户和拜访一对多

    - 在客户实体类表示所有拜访记录,使用set集合

    - 在拜访实体类表示所属客户,使用对象

    第三步  配置映射关系

    (1)拜访实体类visit  基本属性配置

    (2)用户和拜访一对多

    - 在用户映射文件中表示所有拜访记录,使用set标签

    - 在拜访映射文件中表示所属用户

    (3)客户和拜访一对多

    - 客户映射文件中表示所有拜访

    - 在拜访映射文件中表示所属客户

    最后把映射配置文件在核心配置文件中做引入

    代码实践截图:

    拜访实体类visit

    user实体类

    customer实体类

    visit.hbm.xml

    user.hbm.xml

    customer.hbm.xml

     

    在核心配置文件中引入映射文件之后,启动服务器  然后自动建表

    总结:在多对多映射配置中,推荐使用此方式,因为中间表中一般都不只是两个外键组成的,还拥有自己的私有属性,传统的简单多对多配置只有两个外键,而这里将多对多拆分成了两个一对多来进行配置,配置的时候可以类比多对一(联系人和客户)的思路进行配置

    visit和user(多对一)   visit和customer(多对一)  

    ----------------------------------------------------------------------------------------

    添加页面:

     1         <TABLE cellSpacing=0 cellPadding=0 width="98%" border=0>
     2             <TBODY>
     3                 <TR>
     4                     <TD width=15 background=${pageContext.request.contextPath }/images/new_022.jpg><IMG
     5                         src="${pageContext.request.contextPath }/images/new_022.jpg" border=0></TD>
     6                     <TD vAlign=top width="100%" bgColor=#ffffff>
     7                         <TABLE cellSpacing=0 cellPadding=5 width="100%" border=0>
     8                             <TR>
     9                                 <TD class=manageHead>当前位置:客户拜访管理 &gt; 添加拜访</TD>
    10                             </TR>
    11                             <TR>
    12                                 <TD height=2></TD>
    13                             </TR>
    14                         </TABLE>
    15                         <TABLE cellSpacing=0 cellPadding=5  border=0>
    16                             <tr>
    17                                 <td>客户:</td>
    18                                 <!-- 应该用下拉列表显示所有的客户   而不是让用户输入  所有就需要在到达该页面之前在域对象中保存所有客户的记录 用于在这里显示 -->
    19                                 <td colspan="3">
    20                                 <!--<input type="text" name="custId" style="WIDTH: 180px"/>
    21                                 -->
    22                                     <select name="customer.cid">
    23                                         <c:forEach items="${listCustomer}" var="customer">
    24                                             <option value="${customer.cid}">${customer.custName}</option>
    25                                         </c:forEach>
    26                                     </select>
    27                                 </td>
    28                             </tr>
    29                             
    30                           <tr>
    31                                 <td>用户:</td>
    32                                 <!-- 应该用下拉列表显示所有的客户   而不是让用户输入  所有就需要在到达该页面之前在域对象中保存所有客户的记录 用于在这里显示 -->
    33                                 <td colspan="3">
    34                                 <!--<input type="text" name="custId" style="WIDTH: 180px"/>
    35                                 -->
    36                                     <select name="user.id">
    37                                     <c:forEach items="${listUser}" var="user">
    38                                             <option value="${user.id}">${user.name}</option>
    39                                         </c:forEach>
    40                                     </select>
    41                                 </td>
    42                             </tr>
    43                             
    44                             <TR>
    45                                 <td>拜访地址:</td>
    46                                 <td>
    47                                 <INPUT class=textbox id=sChannel2
    48                                                         style="WIDTH: 180px" maxLength=50 name="vaddress">
    49                                 </td>
    50                                 <td>拜访内容:</td>
    51                                 <td>
    52                                 <INPUT class=textbox id=sChannel2
    53                                                         style="WIDTH: 180px" maxLength=50 name="vcontent">
    54                                 </td>
    55                             </TR>
    56                             
    57                             <tr>
    58                                 <td rowspan=2>
    59                                 <INPUT class=button id=sButton2 type=submit
    60                                                         value="保存 " name=sButton2>
    61                                 </td>
    62                             </tr>
    63                         </TABLE>

    运行界面:

    在action中使用模型驱动

    点击提交数据库中就保存了一条记录:

    操作和一对多都一样,只是配置关系时  需要把多对多 拆分为两个一对多

    ------------------------------------------------------------------------------------

    抽取BaseDao

    内容介绍
    1 代码review

    2 抽取basedao代码重构方式
    (1)在dao层,做操作最基本crud操作
    (2)做crud操作时候,调用hibernate模板的方法都一样
    (3)不同的是参数不同,
    比如操作客户,传递客户对象,比如操作联系人,传递联系人对象
    (4)抽取basedao,减少dao层大量重复的代码

    3 使用反射+泛型实现抽取
    (1)反射得到类的.class文件内容
    - 得到类Class方式
    -- Class.forName(...)
    -- 类名.class
    -- 对象.getClass() ;
    this.getClass() ;
    -- getClass方法是Object类的方法

    (2)泛型术语
    List<User> :
    - <> :读成 typeof
    - List<User> :整体部分读成 参数化类型
    - <User> : <>中的User,读成 实际类型参数

    具体实现
    1 创建basedao接口,使用泛型方式
    在接口里面定义操作的方法curd方法

    2 创建BaseDao接口实现类

    3 在真正功能的接口,继承basedao接口

    (1)把实现crud操作的方法去掉了

    4 让真正功能的实现类继承BaseDao实现类
    (1)在真正的实现类,不需要继承hibernateDaoSupport,因为baseDaoImpl类继承了hibernateDaoSupport  所以不需要重复继承,所以customerdaoimpl对象中仍然需要注入sessionfactory对象

    5 上面操作实现基本功能,有两个查询没有实现(需要得到当前操作的对象才能实现,比如findAll查询的时候,需要传递查询的实体类名,而这些操作需要在父类basedaoimpl的构造函数中进行 )

    (1)根据id查询,返回对象
    (2)查询所有

    6 当customerdaoimpl实现类的对象创建的时候,父类的构造执行,即先执行basedaoimpl的构造方法,在这个方法中需要得到操作类的名称,结束之后才会调用custoemrdaoimpl类的构造方法

    (1)在BaseDaoImpl的构造方法中得到传递对象的class
    (2)得到BaseDaoImpl泛型里面Customer的class

    7 具体实现
    (1)得到运行类的class

    (2)得到customerdaoimpl父类内容

    (3)得到父类的参数化类型

    (4)获取实际类型参数

    (5)代码实现
    private Class clazzType;
    public BaseDaoImpl() {
    //1 获取当前运行对象的class
    //比如运行customerDao实现类,得到customerDao实现类class
    Class clazz = this.getClass();

    //2 获取运行类的父类的参数化类型BaseDaoImpl<Customer>   现在customerdaoimpl的父类是basedaoimpl 因为该类继承了basedaoimpl
    Type type = clazz.getGenericSuperclass();

    //3 转换成子接口ParameterizedType
    ParameterizedType ptype = (ParameterizedType) type;

    //4 获取实际类型参数
    //比如 Map<key,value>
    Type[] types = ptype.getActualTypeArguments();

    //5 把Type变成class
    Class clazzParameter = (Class) types[0];
    this.clazzType = clazzParameter;
    }

    注意hql语句中,from后面是需要空格的

    ----------------------------------------------

    代码实现,以customer为例

    这里只有customerdaoimpl类继承了basedaoimpl  代码的执行顺序是:在创建custoemrdoaimpl对象之前,因为该类继承了basedaoimpl  ,则,basedaoimpl就是customerdaoimpl的父类,那么在创建customerdaoimpl对象的时候,会先执行basedaoimpl

    类的构造方法,然后才执行customerdaoimpl类的构造方法,可通过反射方式,在父类的构造方法中得到当前运行的类的名称

     basedao接口:

     1 package org.dao;
     2 
     3 import java.util.List;
     4 
     5 public interface BaseDao<T> {
     6     //修改
     7     public void update(T t);
     8     //添加
     9     public void add(T t);
    10     //删除
    11     public void delete(T t);
    12     //查找所有
    13     public List<T> findAll();
    14     //根据id值 进行查找  一条记录
    15     public T findOne(int id);
    16 }

     basedaoimpl:

     1 package org.dao;
     2 
     3 import java.lang.reflect.ParameterizedType;
     4 import java.lang.reflect.Type;
     5 import java.util.List;
     6 
     7 import org.model.Customer;
     8 import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
     9 
    10 public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T>{
    11     //这里只抽取最基本的方法  即增删改查
    12     private Class classType=null;
    13     public BaseDaoImpl() {
    14         super();
    15         //得到当前运行类的Class
    16         Class clazz=this.getClass();
    17         //得到运行类  的父类参数化类型  例如当前运行类是customer  CustomerDaoImpl extends BaseDaoImpl<Customer>
    18         //那么basedaoimpl是customerdaoimpl的父类,  最终得到的结果就是BaseDaoImpl<Customer>
    19         Type type=clazz.getGenericSuperclass();
    20         //强转 子接口
    21         ParameterizedType ptype=(ParameterizedType) type;
    22         //使用子接口中的方法 得到实际类型参数  即<>中的内容
    23         Type[] types=ptype.getActualTypeArguments();
    24         Class clazzParameter=(Class) types[0];
    25         this.classType=clazzParameter;
    26     }
    27 
    28     public void add(T t) {
    29         this.getHibernateTemplate().save(t);
    30     }
    31 
    32     public void delete(T t) {
    33         this.getHibernateTemplate().delete(t);
    34     }
    35 
    36     public void update(T t) {
    37         this.getHibernateTemplate().update(t);
    38     }
    39 
    40     public List<T> findAll() {//classType
    41         //"from Customer"
    42         return (List<T>)this.getHibernateTemplate().find("from "+classType.getSimpleName());
    43     }
    44     public T findOne(int id) {
    45         //(Customer.class,id)
    46         return (T) this.getHibernateTemplate().get(classType, id);
    47     }
    48 
    49 }

     customerdao:

     1 package org.dao;
     2 
     3 import java.util.List;
     4 
     5 import org.model.Customer;
     6 //接口之间也可以进行继承
     7 public interface CustomerDao extends BaseDao<Customer>{//因为在basedao中已经存在了增删改查的方法,所以这里注释掉自己定义的方法
     8 //T 真正实体类的名称 这里是customer  
     9     //void add(Customer customer);
    10 
    11     //List<Customer> findAll();
    12 
    13     //Customer findOne(int id);
    14 
    15     //void delete(Customer c);
    16 
    17     //void update(Customer customer);
    18 
    19     int findCount();
    20 
    21     List<Customer> findPage(int begin, int pageSize);
    22 
    23     List<Customer> findCondition(Customer customer);
    24 
    25 
    26 
    27 }

    customerdaoimpl:

      1 package org.dao;
      2 
      3 import java.util.List;
      4 
      5 import org.hibernate.Query;
      6 import org.hibernate.Session;
      7 import org.hibernate.SessionFactory;
      8 import org.hibernate.criterion.DetachedCriteria;
      9 import org.hibernate.criterion.Restrictions;
     10 import org.model.Customer;
     11 import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
     12 //该类继承HibernateDaoSupport类  不需要注入HibernateTemplate对象了  只用在配置文件中注入sessionfactory对象
     13 //而做basedao抽取的时候  需要继承baseDao的实现类  因为该实现类继承了hibernateDaoSupport  所以这里就
     14 //不需c复继承了  但是在spring配置文件中  CustomerDaoImpl中还是需要注入sessionfactory类的  
     15 //因为该类虽然没有直接继承hibernateDaoSupport 但是因为basedaoimpl继承了  本类又继承了 basedaoimpl 
     16 //所以这个类就继承了hibernateDaoSupport
     17 //另外在继承basedaoimpl时 需要明确泛型的类型  把泛型替换为具体的对象类型
     18 public class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao {
     19     
     20 //    public CustomerDaoImpl() {
     21 //        super();
     22 //        System.out.println("customerdaoimpl......构造函数执行");
     23 //    }
     24     /*
     25      * 因为在basedaoimpl中已经做了抽取  把基本的增删改查操作都做了实现  而且继承了basedaoimpl  直接在service中调用即可
     26      * 
     27      * 
     28     //向t_customer表中保存一条记录
     29     public void add(Customer customer) {
     30         //得到模板对象  使用方法进行数据的保存
     31         this.getHibernateTemplate().save(customer);
     32     }
     33     //查询t_customer表中的所有记录
     34     public List<Customer> findAll() {
     35         // TODO Auto-generated method stub
     36         return (List<Customer>) this.getHibernateTemplate().find("from Customer");
     37     }
     38     //根据id  查询对象
     39     public Customer findOne(int id) {
     40         // TODO Auto-generated method stub
     41         return this.getHibernateTemplate().get(Customer.class,id);
     42     }
     43     //删除对象
     44     public void delete(Customer c) {
     45         // TODO Auto-generated method stub
     46         this.getHibernateTemplate().delete(c);
     47     }
     48     //修改操作
     49     public void update(Customer customer) {
     50         // TODO Auto-generated method stub
     51         this.getHibernateTemplate().update(customer);
     52     }
     53     */
     54     //查询总的记录数
     55     public int findCount() {
     56         // TODO Auto-generated method stub
     57         //使用模板中的find方法来完成查询总记录数  查询出来的不是一个个的对象的集合  
     58         //而是一个数值  但是该方法反回的的是一个list集合  所以仍然需要使用list集合进行接收
     59         List<Object>list=(List<Object>) this.getHibernateTemplate().find("select count(*) from Customer");
     60         //从list中把值得到
     61         if(list!=null&&list.size()!=0){
     62             //变成int类型  
     63             Object obj=list.get(0);
     64             //直接变是不行的  需要先变成Long型(long的包装类)  在转为int性
     65             Long lobj=(Long) obj;
     66             int count=lobj.intValue();
     67             return count;
     68         }
     69         return 0;
     70     }
     71     //分页操作
     72     public List<Customer> findPage(int begin, int pageSize) {
     73         // TODO Auto-generated method stub
     74         //创建离线DetachedCriteria对象 指明是对那个实体类进行操作
     75         DetachedCriteria criteria=DetachedCriteria.forClass(Customer.class);
     76         //第一个参数是离线对象      第二个  :起始位置           第三个  每页的大小(记录数)
     77         List<Customer> list=(List<Customer>) this.getHibernateTemplate().findByCriteria(criteria,begin,pageSize);
     78         return list;
     79     }
     80     //条件查询  输入的内容不为空
     81     public List<Customer> findCondition(Customer customer) {
     82         // TODO Auto-generated method stub
     83         //第一种方式:
     84 //        SessionFactory sessionFactory=this.getHibernateTemplate().getSessionFactory();//得到sessionfactory对象
     85 //        Session session=sessionFactory.getCurrentSession();//得到session 这里的session对象和web阶段的HttpSession不是同一个概念
     86 //        Query query=session.createQuery("from Customer where custName like ?");
     87 //        query.setParameter(0,customer.getCustName());
     88 //        List<Customer> list=query.list();
     89         
     90         
     91         //第二种方式: 单一条件查询的时候 这种比较简单  但是多条件查询的时候  使用第三中方式最简单
     92 //        List<Customer> list=(List<Customer>) this.getHibernateTemplate().find("from Customer where custName like ?","%"+customer.getCustName()+"%");
     93         
     94         
     95         //第三种方式:
     96         //创建离线对象,表示对那个实体类进行操作
     97         DetachedCriteria criteria=DetachedCriteria.forClass(Customer.class);
     98         //设置对实体类中的那个属性进行条件查询   如果对多个字段进行条件查询  那么只需要调用add方法即可 
     99         criteria.add(Restrictions.like("custName","%"+customer.getCustName()+"%"));
    100         //调用模板中的方法  得到集合
    101         List<Customer> list=(List<Customer>) this.getHibernateTemplate().findByCriteria(criteria);
    102         return list;
    103     }    
    104 
    105 }

    如果该实现类不注入sessionfactory,那么就会报错:

    service中部分代码:因为继承了basedaoimpl 所以这里调用的方法  都是basedaoimpl中的方法

     1 // 添加客户
     2     public void add(Customer customer) {
     3         // TODO Auto-generated method stub
     4         customerDao.add(customer);
     5     }
     6 
     7     // 客户列表
     8     public List<Customer> findAll() {
     9         // TODO Auto-generated method stub
    10         return customerDao.findAll();
    11     }
    12 
    13     // 根据id查询对象
    14     public Customer findOne(int id) {
    15         return customerDao.findOne(id);
    16     }
    17 
    18     // 删除对象
    19     public void delete(Customer c) {
    20         // TODO Auto-generated method stub
    21         customerDao.delete(c);
    22     }
    23 
    24     // 修改操作
    25     public void update(Customer customer) {
    26         // TODO Auto-generated method stub
    27         customerDao.update(customer);
    28     }

    这样统一的功能就由basedao进行实现,继承basedaoimpl类,就可以使用基本的增删改查操作,从而减少了大量的代码

    --------------------------------

    当customerdaoimpl和linkmandaoimpl两个实现类继承basedaoimpl的时候,服务器的启动截图:

    说明创建对象之前会先调用父类中的构造方法,而在核心配置文件中是先引入的customer.xml文件,后引入的linkman.xml文件,所以加载配置文件的顺序就是先customer.xml后linkman.xml,所以在服务器启动的时候 先创建customer对象,后创建linkman对象,而创建这两个对象之前都会先调用其父类的构造方法。

    -----------------------------------------------------------------------------------

    多条件组合查询
    第一种 写底层hibernate代码实现

    第二种 使用hibernate模板里面find方法实现

    - 写hql语句实现
    //多条件组合查询
    @SuppressWarnings("all")
    public List<Customer> findMoreCondition(Customer customer) {
    //使用hibernate模板里面find方法实现
    //拼接hql语句
    String hql = "from Customer where 1=1 ";
    //创建list集合,如果值不为空,把值设置到list里面
    List<Object> p = new ArrayList<Object>();
    //判断条件值是否为空,如果不为空拼接hql语句
    if(customer.getCustName()!=null && !"".equals(customer.getCustName())) {
    //拼接hql
    hql += " and custName=?";
    //把值设置到list里面
    p.add(customer.getCustName());
    }
    if(customer.getCustLevel()!=null && !"".equals(customer.getCustLevel())) {
    hql += " and custLevel=?";
    p.add(customer.getCustLevel());
    }
    if(customer.getCustSource()!=null && !"".equals(customer.getCustSource())) {
    hql += " and custSource=?";
    p.add(customer.getCustSource());
    }
    //    System.out.println("hql: "+hql);
    //    System.out.println("list: "+p);
    return (List<Customer>) this.getHibernateTemplate().find(hql, p.toArray());
    }

    第三种 使用离线对象和hibernate模板里面方法

    第二种方式代码实现:

    表单提交之后,把数据提交给action,因为action中使用了模型驱动,所以可以得到数据,如果没有输入任何东西,那么action中封装的模型对象中的数据就是为null,但是这不影响数据的检索,

    action中直接调用service中的方法,service调用dao中的方法

    下面是daoimpl中的方法:

     1     //多条件查询
     2     public List<Customer> moreCondition(Customer customer) {
     3         List<Object> p=new ArrayList<Object>();
     4         String hql="from Customer where 1=1";
     5         //下面进行验证是否为空  并拼接hql字符串
     6         if(customer.getCustName()!=null&&!"".equals(customer.getCustName())){
     7             hql=hql+" and custName=?";
     8             p.add(customer.getCustName());//如果值不为空  就把该值设置进list集合中
     9         }
    10         if(customer.getCustLevel()!=null&&!"".equals(customer.getCustLevel())){
    11             hql += " and custLevel=?";
    12             p.add(customer.getCustLevel());
    13         }
    14         if(customer.getCustSource()!=null&&!"".equals(customer.getCustSource())){
    15             hql += " and custSource=?";
    16             p.add(customer.getCustSource());
    17         }
    18         //第二个参数是一个可变参数(就是一种数组的形式)  需要把list集合变为数组
    19         return (List<Customer>) this.getHibernateTemplate().find(hql,p.toArray());
    20     }    

    在这方法中,我们采用的是字符串拼接的方式来构造hql语句,因为用户可能什么也没用输入,所以就需要判断是否为空,如果为空,那么if语句就都没有执行,所以hql语句就变为:

    String hql="from Customer where 1=1";
    当然是查询所有了
    所以通过字符串拼接的方式,就能够完成多条件的查询操作

    第三种方式代码实现:
    daoimpl代码:
     1     //多条件查询
     2     public List<Customer> moreCondition(Customer customer) {
     3         //第二种方式:使用离线对象
     4         DetachedCriteria c=DetachedCriteria.forClass(Customer.class);//DetachedCriteria离线查询
     5         //仍然需要验证是否为空  如果不为空  就像离线对象中插入限制条件  并且设置值
     6         if(customer.getCustName()!=null&&!"".equals(customer.getCustName())){
     7             c.add(Restrictions.eq("custName",customer.getCustName()));
     8         }
     9         if(customer.getCustLevel()!=null&&!"".equals(customer.getCustLevel())){
    10             c.add(Restrictions.eq("custLevel",customer.getCustLevel()));
    11         }
    12         if(customer.getCustSource()!=null&&!"".equals(customer.getCustSource())){
    13             c.add(Restrictions.eq("custSource",customer.getCustSource()));
    14         }
    15         //调用方法  执行查询
    16         return (List<Customer>) this.getHibernateTemplate().findByCriteria(c);
    17     }    
    DetachedCriteria--离线查询
    Restrictions--条件限制



  • 相关阅读:
    JavaScript作用域闭包(你不知道的JavaScript)
    Python笔记---错误笔记
    Go语言核心之美 1.5-作用域
    Android经常使用自己定义控件(二)
    Java开发者最经常使用19个Linux命令
    Python: scikit-image binary descriptor
    android 自己定义状态栏和导航栏分析与实现
    程序猿增加新团队的那些坑
    LeetCode 06 ZigZag Conversion
    【UWP通用应用开发】控件、应用栏
  • 原文地址:https://www.cnblogs.com/Joke-Jay/p/6648768.html
Copyright © 2020-2023  润新知