【Java】SSH项目I笔记

目录

1.配置SSH

1.1 导入jar包

1.2 搭建struts2环境

1.3 搭建hibernate环境

1.4 搭建spring环境

1.5 struts2和spring的整合

1.6 spring和hibernate的整合

1.7 互相的注入关系

1.8 bean.xml中配置事务

1.9 property属性中value和ref的不同

2.分页管理

2.1 PageBean实体类

2.2 -->页面

2.3 -->Action

2.4 -->Service(封装PageBean对象)

2.5 -->Dao(两种方式)

3.文件上传到服务器

3.0 原理

3.1上传表单页面的要求

3.2 Action得到上传文件名称和上传文件

3.3 在Action的方法中上传服务器

3.4 文件大小限制以及input结果定义

4.级联查询NO SESSION

4.0 情景

4.1 原因

4.2 解决

5.级联删除

5.0 情景

5.1 原理

5.2 实现

6.多对多的实现

6.0 核心思想

6.1 情景

6.2 具体实现

6.3 图分析

6.4 ①②比较的优点

7.抽取BaseDao

8.多条件组合查询

8.1 底层sql实现(复杂的sql hibernate实现不了的时候)

8.2 hibernate模板里面的find方法实现

8.3 离线对象criteria和hibernate模板里面方法

9.数据字典表(码表)

9.0 什么是数据字典表(码表)

9.1 数据字典表的实体类创建以及配置


1.配置SSH


1.1 导入jar包

网站:

1.2 搭建struts2环境

1)创建action,创建struts.xml配置文件,配置action

2)配置struts2的过滤器

<filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

1.3 搭建hibernate环境

1)创建实体类

2)配置实体类和数据库表映射关系

3)创建hibernate核心配置文件  -  引入映射配置文件

<hibernate-configuration>
	<session-factory>
		
		<!-- hibernate信息 可选 -->
			<property name="hibernate.show_sql">true</property>
			<property name="hibernate.format_sql">true</property>
			<property name="hibernate.hbm2ddl.auto">update</property>
			<property name="hibernate.hbm2ddl.auto">update</property>
			<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<!-- session与本地线程绑定 -->
			<!-- <property name="hibernate.current_session_context_class">thread</property> -->
		<!-- 将映射文件放到核心配置文件中 -->
			<mapping resource="com/entity/User.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

1.4 搭建spring环境

1)创建spring核心配置文件

2)引入映射配置文件

3)让spring配置文件在服务器启动时候加载(web.xml)

- 配置监听器

 <listener>
    	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

- 指定spring配置文件位置

 <context-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:bean.xml</param-value>
  	</context-param>

1.5 struts2和spring的整合

1)把action在spring配置(action多实例的)

2)在struts.xml中action标签class属性里面写 bean的id值

 

1.6 spring和hibernate的整合

1)把hibernate核心配置文件中数据库配置,在spring里面配置

2)把hibernate的sessionFactory在spring配置

<!-- 配置c3p0连接池 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        	<!-- 数据库信息 必须-->
			<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
			<property name="jdbcUrl" value="jdbc:mysql:///ssh_crm?useUnicode=true&amp;characterEncoding=UTF-8"></property>
			<property name="user" value="root"></property>
			<property name="password" value="532077936"></property>
        </bean>
        
        <!-- sessionfactory创建 -->
        <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        	<property name="dataSource" ref="dataSource"></property>
        	<property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
        </bean>

1.7 互相的注入关系

Action注入Service

Service注入Dao实现类

Dao实现类(继承HibernateDaoSupport)注入HibernateTemplate(注入sessionFactory)

*继承的话就不用在配置文件再写HibernateTemplate的对象(通过注入sessionFactory会设置HibernateTemplate)了

<bean id="userAction" class="com.tencent.action.UserAction" scope="prototype">
        	<property name="userService" ref="userService"></property>
        </bean>
        <bean id="userService" class="com.tencent.service.UserService">
        	<property name="userDao" ref="userDaoImpl"></property>
        </bean>
        <bean id="userDaoImpl" class="com.tencent.dao.UserDaoImpl">
        	<!-- <property name="hibernateTemplate" ref="hibernateTemplate"></property> -->
        	<property name="sessionFactory" ref="sessionFactory"></property>
        </bean>

1.8 bean.xml中配置事务

<!-- 事务管理器 -->
        <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        	<property name="sessionFactory" ref="sessionFactory"></property>
        </bean>
        <!-- 开启注解 指定事务管理器 -->
        <tx:annotation-driven transaction-manager="transactionManager"/>

 

1.9 property属性中value和ref的不同

>>>ref指向的是一个bean的id
>>>value=一个java类

 

2.分页管理


2.1 PageBean实体类

//当前页
private Integer currentPage;
	
//总记录数
private Integer totalCount;

//总页数
private Integer totalPage;
	
//一页几条记录
private Integer pageSize;
	
//开始位置
private Integer begin;
	
//每页记录的集合
private List<Customer> list;

//......get/set方法.......//

2.2 -->页面

从页面中获取currentPage值,

点击列表时(传currentPage=1),点击下一页(currentPage+=1),点击上一页(currentPage-=1)

 

2.3 -->Action

public String pagelist() {
	PageBean pagebean = customerService.listpage(currentPage);
	ServletActionContext.getRequest().setAttribute("pageBean", pagebean);
	return "pagelist";
}

2.4 -->Service(封装PageBean对象)

public PageBean listpage(Integer currentPage) {

		PageBean pageBean = new PageBean();
		
		//设置当前页
		pageBean.setCurrentPage(currentPage.intValue());
		
		//设置总记录数
		int totalCount = customerDao.findCount();
		pageBean.setTotalCount(totalCount);
		
		//设置一页最多要显示的记录数
		int pageSize = 5;
		
		//设置总页数
		int totalPage = 0;
		if(totalCount % pageSize == 0) {
			totalPage = totalCount/pageSize;
		}else {
			totalPage = totalCount/pageSize+1;
		}
		pageBean.setTotalPage(totalPage);
		
		//设置开始位置,从第几条记录开始查询
		int begin = (currentPage-1)*pageSize;
		
		List<Customer> list = customerDao.findPage(begin,pageSize);
		pageBean.setList(list);
		
		return pageBean;
		
		
		
	}

 

2.5 -->Dao(两种方式)

public List<Customer> findPage(int begin, int pageSize) {
		/*
		 * 第一种方法 使用hibernate底层代码实现
		 */
//		SessionFactory sessionFactory = this.getHibernateTemplate().getSessionFactory();
//		Session session = sessionFactory.getCurrentSession();
//		Query query = session.createQuery("from Customer");
//		query.setFirstResult(begin);
//		query.setMaxResults(pageSize);
//		List<Customer> list = query.list();
		
		/*
		 * 第二种 使用离线对象和hibernateTemplate的方法实现
		 */
		DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
		List<Customer> list = 
				(List<Customer>)this.getHibernateTemplate().findByCriteria(criteria, begin, pageSize);
		
		
		return list;
	}

 

3.文件上传到服务器


 

3.0 原理

Struts2使用拦截器对FileUpload进行了封装

 

3.1上传表单页面的要求

①表单提交方式post

②form标签里面有属性enctype,值为multipart/form-data

③表单里面有上传项<input type="file" name="upload"/>   name要同Action里面的File对象同名

 

3.2 Action得到上传文件名称和上传文件

①定义两个变量(属性封装),分别代表文件以及文件名,文件名命名要同File名一样(upload) 再加 FileName

private File upload;
private String uploadFileName;	
	
	public File getUpload() {
		return upload;
	}


	public void setUpload(File upload) {
		this.upload = upload;
	}


	public String getUploadFileName() {
		return uploadFileName;
	}


	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

3.3 在Action的方法中上传服务器

①在服务器里面创建文件

②把上传得到的文件复制到服务器文件里面

if(upload != null) {
			//在服务器文件夹里面创建文件
			File serverFile = new File("D:\\sshtest"+"/"+uploadFileName);
			//把上传的文件复制到服务器文件中
			FileUtils.copyFile(upload, serverFile);
		}

3.4 文件大小限制以及input结果定义

文件上传大小超出限制&input输出未定义:

①默认限制大小2M,可以在struts.xml里面配置常量struts.multipart.maxSize=最大字节数

②超过限制的话,自动返回结果,即return "input"

所以可以配置<result name="input"> .... </result>在出错时到所需的页面

在input转发到的页面中可以用标签Struts的标签<s:actionerror/> 看到具体错误

 

4.级联查询NO SESSION


 

4.0 情景

eg:关系:联系人  (用户

现需要查询联系人下的用户的名称

如果传入的是list中的linkMan

以linkMan.customer.custName来获取值就会报No Session

 

4.1 原因

用的是hibernate框架,主要靠的是session来进行对数据的crud

而hibernate默认在Dao层操作完之后就关闭session

在action中发现有需要linkMan关联的customer的属性(除作为外键的主键cid)就需要重返dao层查询数据

而此时已经没有session了,所以报错了

 

4.2 解决

- 让session操作之后不会马上关闭,在action操作之后进行关闭

- 封装实现方式:让session延迟关闭

 

封装过滤器,只需要配置封装的过滤器就可以了

配置到struts2过滤器前面 (不是覆盖 而是之后的不执行?)

<filter>
    	<filter-name>openSessionInViewFilter</filter-name>
    	<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
    </filter>
    
    <filter-mapping>
    	<filter-name>openSessionInViewFilter</filter-name>
    	<url-pattern>/*</url-pattern>
    </filter-mapping> 

 

5.级联删除


 

5.0 情景

eg:关系:联系人  (用户

要删除用户,需求有两种:

①把用户对应的多个联系人都删了

②用户的外键设置为NULL

 

5.1 原理

hibernate的外键双向维护

封装的属性

 

5.2 实现

需求①:在用户的配置文件中的联系人 设置<set name="linkMan" inverse="true" cascade="delete">...</set>

表示(一)用户放弃了外键维护,并启动了级联删除

需求②:inverse和cascade都不配置,默认效果

ps:如果只设置了inverse=true 会出现异常

 

 

 

6.多对多的实现


 

6.0 核心思想

多对多 的 拆分 两个 一对多

 

6.1 情景

两个表 User、Customer

需求是,一个User可以Visit多个Customer,一个Customer可以被多个User Visit

 

6.2 具体实现

①直接使用多对多建立关系(不建议使用)

直接用外键互相关联两个表的主键

具体实现事例可看https://blog.csdn.net/TypantK/article/details/82974956

 

②拆分成两个一对多,建立多一个实体类来建立关系

将(User)多对多(Customer)转换成      (User)一 对 (Visit)多(Visit) 对  一(Customer)

具体逻辑:一个User可以有多个Visit记录,一个Customer可以有多个被Visit记录,一个Visit记录只能有一个User和一个Customer

 

6.3 图分析

 

6.4 ①②比较的优点

①方式可以减少一张表

②方式可以多几个表字段,比如Visit记录下,Visit的内容,Visit的时间,Visit的地址等

 

 

7.抽取BaseDao


对重复的代码(只是参数上传的类型不同)方法等,进行抽取,通过泛型来简化代码

 

得到类Class方式

>> Class.forName(...)

>> 类名.class

>> 对象.getClass() ;

this.getClass() ;

>> getClass方法是Object类的方法

 

对于需要获取类型的class的方法(没有T.class这种写法),通过反射来获得类型名称

public BaseDaoImpl() {
		//1 获取当前运行对象的class
		//比如运行customerDao实现类,得到customerDao实现类class
		Class clazz = this.getClass();
		
		//2 获取运行类的父类的参数化类型
		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;
	}

 

8.多条件组合查询


8.1 底层sql实现(复杂的sql hibernate实现不了的时候)

1)得到sessionFactory对象,得到session对象

2)调用session里面的方法创建SQLQuery对象

3)返回结果的结果转换

使用sqlQuery.list()返回的list中都是数组的形式

可以通过此方法转换成MAP形式,如果只有两个字段

 

 

8.2 hibernate模板里面的find方法实现

//使用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());
		}

return (List<Customer>) this.getHibernateTemplate().find(hql, p.toArray());

8.3 离线对象criteria和hibernate模板里面方法

//1 创建离线对象,指定对哪个实体类进行操作
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
		//2 判断条件值是否为空,设置值
		if(customer.getCustName()!=null && !"".equals(customer.getCustName())) {
			//调用方法实现
			//调用add方法,表示设置条件值
			//add方法里面使用Restrictions类里面静态的方法实现
			detachedCriteria.add(Restrictions.eq("custName", customer.getCustName()));
		}
		if(customer.getCustLevel()!=null && !"".equals(customer.getCustLevel())) {
			detachedCriteria.add(Restrictions.eq("custLevel", customer.getCustLevel()));
		}

	//3执行离线对象
		//调用hibernate模板里面的方法实现
		List<Customer> list = 
				(List<Customer>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
		return list;

 

9.数据字典表(码表)


 

9.0 什么是数据字典表(码表)

存储一些基本的数据,可以通过主键来查询更详细的信息

比如客户的级别,1 代表 普通用户、2 代表 会员、3 代表 管理员 等 这种

数据字典表(级别表)                 】  用到数据字典表的表(用户表)

 

9.1 数据字典表的实体类创建以及配置

创建就同一般的实体类一样,

一个id作为主键,

另一个作为更详细信息的数据(比如String dname,存储普通用户、会员等)

 

**配置方面在需要用到数据字典表的表(用户表)的配置文件中要配置 数据字典表的信息

<many-to-one name="dictUserLevel" class="cn.entity.dist" >

**而数据字典表中不用配置 需要用到数据字典表(用户表)的信息

不用配置<one-to-many  ...../>

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值