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模板里面方法

  • 相关阅读:
    Eclipse打jar包的方法
    Eclipse中SVN插件的安装
    无法远程访问 MySql Server
    TCP(Socket基础编程)
    安装淘宝镜像cnpm时出现问题及解决方案
    搭建vue脚手架---vue-cli
    padding和margin设置成百分比
    响应式布局
    响应式网页:用em,rem设置网页字体大小自适应
    url两次编码
  • 原文地址:https://www.cnblogs.com/liaoxiaolao/p/9955740.html
Copyright © 2011-2022 走看看