OA项目知识总结

struts文件配置

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

配置c3po链接池

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

配置内部bean

 1     <!-- 配置sessionFactory -->
 2     <bean id="sessionFactory"
 3         class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
 4         <property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
 5         <!-- 配置c3p0链接池 因为该datasource只有该工厂使用  所以可以配置一个内部bean-->
 6         <property name="dataSource">
 7             <!-- 内部使用的bean 不需要id属性 -->
 8             <bean class="com.mchange.v2.c3p0.ComboPooledDataSource">
 9                 <!-- 必要属性 引入外部的properties文件 使用其中配置的值-->
10                 <property name="jdbcUrl" value="${jdbcUrl}"></property>
11                 <property name="driverClass" value="${driverClass}"></property>
12                 <property name="user" value="${user}"></property>
13                 <property name="password" value="${password}"></property>
14                 <!-- 其他属性配置 -->
15                 <!-- 初始化时获取3个链接 取值应在minPoolSize和maxPoolSize之间  default=3 -->
16                 <property name="initialPoolSize" value="3"></property>
17                 <!-- 连接池中保留的最小链接数  default=3-->
18                 <property name="minPoolSize" value="3"></property>
19                 <!-- 连接池中保留的最大链接数 default=15-->
20                 <property name="maxPoolSize" value="5"></property>
21                 <!-- 当连接池中的连接耗尽的时候 c3p0一次同时获取的连接数  default=3-->
22                 <property name="acquireIncrement" value="3"></property>
23                 <!-- 控制数据源内加载的PreparedStatement数量。如果maxStatement与maxStetementsPerConnection均为0,则缓存关闭。default=0 -->
24                 <property name="maxStatements" value="8"></property>
25                 <!-- maxStatemPerConnection定义了连接池内单个链接所拥有的最大缓存statements数。default=0 -->
26                 <property name="maxStatementsPerConnection" value="5"></property>
27                 <!-- 最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。default=0 -->
28                 <property name="maxIdleTime" value="1800"></property>
29             </bean>
30         </property>
31     </bean>

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

使用注解的方式管理bean对象  注入或者装配

 

首先在spring核心中开启扫描(注意和不是事务扫描)

 

在类中的使用方式

 1 package test;
 2 
 3 import javax.annotation.Resource;
 4 
 5 import org.hibernate.Session;
 6 import org.hibernate.SessionFactory;
 7 import org.junit.Test;
 8 import org.model.User;
 9 import org.springframework.context.ApplicationContext;
10 import org.springframework.context.support.ClassPathXmlApplicationContext;
11 import org.springframework.stereotype.Controller;
12 import org.springframework.stereotype.Service;
13 import org.springframework.transaction.annotation.Transactional;
14 //如果想注入容器中的对象sessionFactory 当前的类必须在容器中 spring不能给 不在容器中的对象注入属性
15 //(例如配置方式中 先配置action 然后配置service action中才能注入配置的service 因为他们在一个容器中  spring配置文件中管理生成的对象都是在容器中的)
16 //所以声明一个bean对象在容器中 名字默认为对象的名称SaveTwoUser
17 //@Service("saveTwoUser")效果和@Service一样 注意类名的第一个字母是小写的
18 @Service
19 public class SaveTwoUser {
20     //sessionFactory已经配置好了  在容器中  使用时 采使用注解的方式进行注入 则不用在配置set方法了  如果采用配置的方式
21     //那么这里声明sessionFactory之后 创建set方法  在配置文件中进行注入<property name="sessionFactory" ref=""></property>
22     //注入bean资源使用@Resource 先按照"sessionFactory"去spring配置文件中去找  找不到 再按照类型去找
23     @Resource
24     private SessionFactory sessionFactory;
25     //private ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
26     
27     //加注解  开启事务
28     @Transactional
29     @Test
30     public void save(){
31         //这里只能使用getCurrentSession而不能使用opensession,opensession得到的是一个新的session 没有事务
32         //而getCurrentSession得到的是外边已经管理好事务的session
33         if(sessionFactory!=null){
34             Session session=sessionFactory.getCurrentSession();
35             if(session!=null){
36                 session.save(new User());
37                 //int i=10/0;
38                 session.save(new User());
39             }
40         }else{
41             System.out.println("sessionfactory为空。。。。");
42         }
43     
44 
45     }
46 
47 }

装配bean实例(action对象)到spring容器中 以及对该action注入其他类的对象  并且调用期中的方法

然后从容器中获取

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

日志级别设置(设置为error时,只有出现错误或者出现严重错误的时候才会打印信息,否则不打印)

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

 BaseDao的抽取思路

 

第一次抽取  因为实体对应的dao操作类 除了自己独有的方法外 基本的增删改查操作是相同的 不同的是对应的类型不同  例如保存操作  UserDao和RoleDao保存时  都是调用session.save()参数为user 和role

如下图

所以把这些公共的方法抽取出来(创建一个BaseDao接口 定义公共方法  UserDao和RoleDao继承BaseDao  那么UserDao和BaseDao中就相当于也定义了这些方法(方法未实现))

当然 存在接口 那么就必须有人来实现接口

创建UserDaoImpl以及RoleDaoImpl实现类

两个实现类实现了接口 当然要实现接口中的方法  不要忘记了  UserDao接口以及RoleDao接口中都继承了BaseDao接口(接口之间可以继承)  所以BaseDao接口中定义的未实现的六个方法  在UserDao和RoleDao中也是存在的 

即在UserDao和RoleDao接口中存在继承来的6个未实现的方法  所以在它们对应的实现类实现该接口的时候  会提示实现没有实现的方法  出现了上面所示的提示

那么当然不能在各自的实现类中去实现它们 ,那样BaseDao的抽取就没有意义了,

如下图

 

我们思考,如果让这两个实现类 在继承一个类A(拥有类A中的方法)    而类A中把这些方法都给实现了  那么不就相当于这两个实现类中实现了父类中需要实现的方法吗

(方法的实现   自己定义的或者继承过来的 都叫做实现 比如 A类中存在一个未实现的方法save ()  第一种实现  A类自己写出save()方法的实现代码  第二种  A类继承了B类  B类中有一个实现了的save()方法  那么A类自然就对未实现的方法进行了实现  因为A类中此时有从B类中继承过来的save()方法)  

所以进行第二次抽取   定义BaseDaoImpl来实现BaseDao中未实现的方法  同样也指定泛型  泛型的类型由继承的类确定  即将来某个类继承了BaseDaoImpl 时需要指定泛型  class A extends BaseDaoImpl<A> 

接下来,让那两个实现类继承该实现类

 

这样就完成了抽取工作,下面进行方法的实现(接下来就只用关注实现类BaseDaoImpl即可了,如果该类把增删改查的代码实现成功,那么其他继承该类的类中自然有这些已经实现的方法,直接调用即可)

对方法的实现需要通过sessionFactory得到session  然后调用其中的方法进行数据库操作

子类上边使用注解把该类对象设置进入容器中,那么父类对象即使不在容器内  依然可以注入容器中的sessionFactory对象(否则  一个类如果想要注入容器中的bean实例  前提是该类设置进容器中)

 

 

继承时只会继承非私有的属性和方法,子类当然有自己的方法 也需要获得session  那么子类也需要进行注入sessionFactory  所以修改如下

为子类提供一个方法,使其得到session ,设置为protected  子类也可访问该方法  所以可以得到session   子类就不需要在注入sessionFactory了

这样就为子类提供了便捷的方式  得到了session ,如果不嫌麻烦 在子类中注入sessionFactory当然也可以  。

接下来继续把重点放在方法的实现上

package org.base;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
//子类放进容器中  这里父类不需要放进容器 依然能够完成sessionFactory的注入
public class BaseDaoImpl<T> implements BaseDao<T> {
    //使用注解 把spring容器中的sessionFactory注入到该类中  但是这个类需设置进容器中 
    //但是问题又来了  为了代码的简洁性  思考:BaseDaoImpl这个bean实例有操作的实体吗  ?没有  那么注入进容器中似乎没有意义
    //但是为了解决sessionFactory注入到该类中的问题  可以有另外一种解决办法
    //那就是把继承该类的子实现类注入到容器中即可  子类注入到容器中很有必要  因为需要操作这些实现类完成对应实体的操作
    @Resource
    private SessionFactory sessionFactory;
    //得到session 这个session必须是currentsession 只有这样才能进行事务管理
    protected Session getSession(){
        return this.sessionFactory.getCurrentSession();
    }
    private Class<T> clazz=null;
    public BaseDaoImpl(){
        //使用反射技术得到真实的类型
        //获取当前new的对象的 泛型的父类 类型
        ParameterizedType pz=(ParameterizedType) this.getClass().getGenericSuperclass();
        this.clazz=(Class<T>) pz.getActualTypeArguments()[0];
    }
    
    public void save(T entry) {
        //通过sessionFactory得到session
        getSession().save(entry);
    }

    public void delete(Long id) {
        //先得到  
        Object obj=getById(id);
        //再删除
        if(obj!=null){
            getSession().delete(obj);
        }
    }
    public void update(T entry) {
        getSession().update(entry);
    }

    public T getById(Long id) {
        return getSession().get(clazz,id);
    }

    public List<T> getByIds(Long[] ids) {
        return getSession().createQuery("from "+clazz.getSimpleName()+" where ids in(:ids)")
        .setParameterList("ids",ids)
        .list();
    }
    public List<T> findAll() {
        return getSession().createQuery("from "+clazz.getSimpleName())
        .list();
    }
}

到此就完成了抽取工作

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

项目的资源分类

配置文件单独创建了一个包 与src同级  所以更放在src的根目录中是一样的  这样的目录设计使项目结构更加的清晰

 

 

jsp页面放在web-inf下

项目部署 服务器启动之后
放在webroot中的jsp页面 可以直接访问
放在web-INF文件夹下的jsp页面 不能直接访问到页面
最好的方式是 先访问action(准备数据) 然后转发给jsp(进行数据的显示)
所以把jsp页面都统一放在web-inf文件夹中 先访问action 然后转发给jsp页面

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

超链接中使用οnclick="return confirm('确定删除吗')"进行确认提交,单击确定  就根据href中的地址 进行提交  否则 什么也不做

<a href="  "   οnclick="return confirm('确定删除吗')">删除</a>

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

动态的提交,执行action中的不同方法

添加页面和修改页面基本显示一样,提交执行action中的方法不同  通过jstl表达式判断内容是否为空(修改的时候先进行了数据查询,然后到修改页面,而添加的时候只是到添加页面)  

当执行添加的时候,就执行action中 的add方法  否则执行edit方法

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

基本操作配置

 

因为添加页面和修改页面通用一个页面  所以这里都返回saveUI  跳入同一个页面  如果页面有区别  不能共用  那么就按照上面的进行配置

    //1.列表
    public String list() throws Exception {
        return "list";
    }
    //2.删除
    public String delete() throws Exception {
        return "toList";
    }
    //3.到添加页面
    public String addUI() throws Exception {
        return "saveUI";
    }
    //4.执行添加
    public String add() throws Exception {
        return "toList";
    }
    //5.到修改页面
    public String editUI() throws Exception {
        return "saveUI";
    }
    //6.执行修改
    public String edit() throws Exception {
        return "toList";
    }
        <!-- 部门管理 -->
        <action name="department_*" class="departmentAction" method="{1}">
            <result name="list">/WEB-INF/jsp/departmentAction/list.jsp</result>
            <result name="toList" type="redirectAction">department_list.action</result>
            <result name="saveUI">/WEB-INF/jsp/departmentAction/saveUI.jsp</result>
        </action>

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

 

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

创建的model中使用set集合出现的问题

HashSet集合是无序集合,每次查询的内容放入到该集合中后,在前端页面显示的时候就会出现每次显示的内容顺序都不是固定的

例如 再检索所有部门信息的时候

刷新

内容是正确的  但是就是顺序每次刷新都会发生变化

最好的解决办法 

在配置对应属性的set标签时  加入order-by属性  该属性指定的是sql的orderby子句内容

这里是按照id升序排列  查询的时候就按照这种方式进行查询  然后因为set集合还是无序的  所以  如果配置了该属性  那么框架自动会生成一个有序的集合实现类  并且把内容存入到其中

这样每次查询的时候  都可以保证每次输出的内容是一致的

 -----

按照升序 排列  无论刷新多少次

-----

按照降序排列 无论刷新多少次

 

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

创建公共文件(多数页面因为样式的代码基本一样  把他们放在一个文件中  然后 使用的时候  直接引入该文件)

创建一个单独的文件  存放这些共用代码 该文件后缀可以是.jsp

使用时  直接引入

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

 

转载于:https://www.cnblogs.com/Joke-Jay/p/7188677.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值