zoukankan      html  css  js  c++  java
  • srm开发(基于ssh)(4)

    1 input处理内容补充

    -在struts2里面有错误处理机制,当上传文件超过默认的大小,自动返回结果input

    -在struts.xml中配置input的返回结果

    <!-- 配置input结果 -->
    <result name="input">/jsp/error.jsp</result>

    (2)当struts2自动返回input结果,出现错误,在配置input的页面中可以查看错误信息

    -在配置的错误页面中,使用struts2标签可以查看错误信息

    要求使用struts2标签库,添加如下所示:

    <s:actionerror/>

    客户拜访管理模块

    1 什么是客户拜访

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

    -比如传智播客的客户 有百度、阿里巴巴、新浪

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

    2 用户和客户关系

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

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

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

    客户:百度、新浪

    用户:小王、小宋

    *小王 可以 拜访 百度、可以拜访新浪

    *百度可以被小王拜访,可以被小宋拜访

    (3)多对多建表

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

    3 之前在hibernate阶段学过多对多配置

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

    4 把多对多拆分成两个一对多实现

    (1)用户、客户、拜访

    (2)用户和拜访是一对多

    配置和客户的关系

    public class Visit {
        private Integer vid;
        private String vaddress;//拜访地址
        private String vcontent;//拜访内容

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

    (1)用户和拜访一对多

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

    //表示所属用户
        private User user;
        
        public User getUser() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }

    第三步 配置映射关系

    (1)一个实体类对应映射文件,创建三个映射文件

    <class name="cn.itcast.entity.Visit" table="t_visit">
            <id name="vid" column="vid">
                <generator class="native">
                </generator>
            </id>
            <property name="vaddress" column="vaddress"></property>
            <property name="vcontent" column="vcontent"></property>
    </class>

    (2)用户和拜访一对多

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

    (3)客户和拜访一对多

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

    <!-- 表示所有拜访记录 -->
            <set name="setCustVisit">
                <key column="cvid"></key>
                <one-to-many class="cn.itcast.entity.Visit"/>
            </set>

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

    <!-- 拜访记录所属客户 -->
            <many-to-one name="customer" class="cn.itcast.entity.Customer" column="cvid"></many-to-one>

    第四步 把映射文件引入到核心配置文件中

    数据库的建表语句如下所示:

    CREATE TABLE `t_visit` (
      `vid` int(11) NOT NULL AUTO_INCREMENT,
      `vaddress` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
      `vcontent` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
      `uvid` int(11) DEFAULT NULL,
      `cvid` int(11) DEFAULT NULL,
      PRIMARY KEY (`vid`),
      KEY `FKneag8njjijyk0mt952k3leyiu` (`uvid`),
      KEY `FKfq1vs5t876wufr6l5tctnopps` (`cvid`),
      CONSTRAINT `FKfq1vs5t876wufr6l5tctnopps` FOREIGN KEY (`cvid`) REFERENCES `t_customer` (`cid`),
      CONSTRAINT `FKneag8njjijyk0mt952k3leyiu` FOREIGN KEY (`uvid`) REFERENCES `t_customer` (`cid`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

    新增客户拜访

    1 点击超链接,到新增用户拜访页面中,

    (1)有两个下拉框,选择用户,选择客户

     在写完之后一定不要忘记写注解。

    客户拜访列表

    1 查询拜访列表所有记录(类似于联系人列表)

    (1)不显示id值,显示id对应名称

    2 核心代码

    <c:forEach items="${list }" var="visit">
    <TR
    style="FONT-WEIGHT: normal; FONT-STYLE: normal; BACKGROUND-COLOR: white; TEXT-DECORATION: none">
    <TD>${visit.user.username }</TD>
    <TD>${visit.customer.custName }</TD>
    <TD>${visit.vaddress}</TD>
    <TD>${visit.vcontent }</TD>
    </TR>
    </c:forEach>

    3 有 no session问题

    抽取BaseDao

    Code Review

    系统的概念实现了,但是可能会比较乱,难于维护。

    有他人审查代码,并提出解决方案。

    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接口,使用泛型方式

    在接口里面定义操作的方法crud方法

    public interface BaseDao<T> {
        
        //添加
        void add(T t);
        
        //修改
        void update(T t);
        
        //删除
        void delete(T t);
        
        //根据id查询
        T findOne(int id);
        
        //查询所有
        List<T> findAll();
        
    }

    2 创建BaseDao接口实现类

    import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
    
    public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
    
        //添加
        public void add(T t) {
            this.getHibernateTemplate().save(t);
        }
    
        //修改
        public void update(T t) {
            this.getHibernateTemplate().update(t);
        }
    
        //删除
        public void delete(T t) {
            this.getHibernateTemplate().delete(t);
        }
    
        //根据id查询
        public T findOne(int id) {
            //不能写T.class
            //this.getHibernateTemplate().get(T.class, id);
            return null;
        }
    
        @Override
        public List<T> findAll() {
            //this.getHibernateTemplate().find("from"+T);
            return null;
        }
    
    }

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

    public interface CustomerDao extends BaseDao<Customer>{

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

    /*public void add(Customer customer);
    
        public List<Customer> findAll();
    
        public Customer findOne(int cid);
    
        public void delete(Customer c);
    
        public void update(Customer customer);*/

     4 让真正功能的实现类继承BaseDao实现类

    (1)在真正的实现类,不需要继承hibernateDaoSupport

    public class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao {

    5 上面操作实现基本概念,有两个查询没有实现

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

    (2)查询所有

    6 当customerdaoImpl实现类创建对象,父类的构造执行

    public class CustomerDaoImpl extends BaseDaoImpl<Customer>

    (1)在BaseDaoImpl的构造方法中得到传递对象的class

    (2)得到BaseDaoImpl泛型里面Customer的class

    7 具体实现

    代码实现

    private Class pClass;
        
        //构造方法
        public BaseDaoImpl(){
            //第一步 得到当前运行的Class
            Class clazz = this.getClass();
            System.out.println("****************************"+clazz);
            
            //第二步 得到运行类的 父类的参数化类型BaseDaoImpl<Customer>
            //Type getGenericInterfaces() 
            Type type = clazz.getGenericSuperclass();
            //使用Type子接口ParameterizedType
            ParameterizedType ptype = (ParameterizedType)type;
            //得到的ptype是BaseDaoImpl<Customer>这个整体部分
            System.out.println("*****************************"+ptype);
            
            //第三步 得到实际类型参数<Customer>里面的Customer
            //Type[] getActualTypeArguments()
            //为什么返回的是数据,可能是map
            Type[] types = ptype.getActualTypeArguments();
            //Type接口实现类Class
            Class tclass = (Class)types[0];
            System.out.println("########################"+tclass);
            this.pClass = tclass;
        }
        
        //根据id查询
            @SuppressWarnings("all")
            public T findOne(int id) {
                //不能写T.class
                //this.getHibernateTemplate().get(T.class, id);
                return (T) this.getHibernateTemplate().get(pClass, id);
            }
    
            @SuppressWarnings("all")
            public List<T> findAll() {
                //this.getHibernateTemplate().find("from"+T);
                //使用Class里面getSimpleName()得到类名称
                return (List<T>) this.getHibernateTemplate().find("from "+pClass.getSimpleName());
                //这里要加空格
            }
        
        //添加
        public void add(T t) {
            this.getHibernateTemplate().save(t);
        }
    
        //修改
        public void update(T t) {
            this.getHibernateTemplate().update(t);
        }
    
        //删除
        public void delete(T t) {
            this.getHibernateTemplate().delete(t);
        }

    多条件组合查询

    第一种 写底层hibernate代码实现

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

    -写hql语句实现

    //多条件组合查询
        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语句时要加空格,不然是错的
                hql += " and custName=?";
                //把值设置到List里面
                p.add(customer.getCustName());
            }
            
            if(customer.getCustLevel()!=null && !"".contentEquals(customer.getCustLevel())){
                hql += " and custLevel=?";
                p.add(customer.getCustLevel());
            }
            
            if(customer.getCustSource()!=null && !"".contentEquals(customer.getCustSource())){
                hql += " and custSource=?";
                p.add(customer.getCustSource());
            }
            
            return (List<Customer>) this.getHibernateTemplate().find(hql, p.toArray());
        }

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

  • 相关阅读:
    C# 文件类的操作---删除
    C#实现Zip压缩解压实例
    UVALIVE 2431 Binary Stirling Numbers
    UVA 10570 meeting with aliens
    UVA 306 Cipher
    UVA 10994 Simple Addition
    UVA 696 How Many Knights
    UVA 10205 Stack 'em Up
    UVA 11125 Arrange Some Marbles
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/liaoxiaolao/p/9955740.html
Copyright © 2011-2022 走看看