- spring概述
- spring框架主要用于实现开闭原则(对系统的升级和维护开放,对系统的源代码修改关闭)
- 主要用到的设计模式是工厂方法。
将使用者和创建者进行分离。
-
- spring主要应用于业务层的构建,让我们关于系统业务的实现和变更为维护。
- Spring中重要的概念
- Ioc控制反转(依赖注入)
控制反转指调用者依赖的对象创建的权利由代码转移到spring容器,由spring容器创建调用者依赖的对象。对象创建权利的转移,称为控制反转(依赖注入)。
-
-
- AOP面向切面的编程
-
将非业务的公共组件提取出来,服务于整个系统的组件定义为一个公共的模块,用于处理系统的事务、安全、异常和日志。
- Spring构成
正在上传…重新上传取消
- spring的开发步骤
3.1.在IDEA中新建项目,引入spring的组件库.
正在上传…重新上传取消
点击create选择spring的组件包
正在上传…重新上传取消
正在上传…重新上传取消
引入完成以后的目录结构
正在上传…重新上传取消
3.2.编写业务接口和接口的实现类
编写UsbBiz接口类
package com.biz; public interface UsbBiz { public void service(); } |
UsbBiz的实现类
Usb移动硬盘
UsbDisk.java
package com.biz; public class UsbDisk implements UsbBiz { private String usbDev; public String getUsbDev() { return usbDev; } public void setUsbDev(String usbDev) { this.usbDev = usbDev; } @Override public void service() { System.out.println(usbDev+"正在拷贝数据....."); } } |
定义UsbMouse类
package com.biz; public class UsbMouse implements UsbBiz { private String usbDev; public String getUsbDev() { return usbDev; } public void setUsbDev(String usbDev) { this.usbDev = usbDev; } @Override public void service() { System.out.println(usbDev+"正在选择要复制的文件....."); } } |
定义UsbFin类
package com.biz; public class UsbFine implements UsbBiz { private String usbDev; public String getUsbDev() { return usbDev; } public void setUsbDev(String usbDev) { this.usbDev = usbDev; } @Override public void service() { System.out.println(usbDev+"正在给电脑降温....."); } } |
3.3.在spring的配置文件spring-config.xml中注入(配置)接口的实现类
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 注入Usb的设备实现类 使用bean节点实现注入 id="注入类的对象标识名称"等同于UsbDisk usbBiz=Class.forName("com.biz.UsbDisk"); property子节点表示给注入类的属性usbDev属性赋值 usbBiz.setUsbDev("金士顿U盘") --> <bean id="usbBiz" class="com.biz.UsbDisk"> <property name="usbDev" value="金士顿U盘"/> </bean> </beans> |
3.4.在测试类中使用spring的上下文关系对象获取注入的实现类对象为接口对象赋值。
package com.test; import com.biz.*; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UseTest1 { public static void main(String[] args) { //获取spring容器的上下文关系对象,并加载配置文件spring-config.xml ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); //定义UsbBiz的接口对象,从容器获取实现类对象为接口对象赋值 UsbBiz ubiz= (UsbBiz) ctx.getBean("usbBiz"); ubiz.service(); } } |
正在上传…重新上传取消
修改配置文件注入不同的子类,查看效果。
- 业务逻辑在子类中进行实现,调用者(测试类)只需要依赖接口对象。
- 通过spring容器创建业务实现类的对象,负责给业务接口赋值
- 调用者通过spring的上线文关系对象获取注入的实现类对象为接口对象赋值。
- 业务实现类可以随时被切换为不同的实现类。则,业务就会随着不同的实现类变更业务的实现方式。不用在调用者类中去创建实现类的对象,只要需要通过spring融合器获取实现类的对象。
- Spring核心组件
- 配置文件spring-config.xml文件
主要用于注入系统依赖的实现类。并为实现类的属性赋值。
-
- spring的上下文关系组件ApplicationContext接口类,主要用于从spring容器中获取注入类的对象。为依赖组件的接口赋值(接口注入)。
ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml");
-
- 代理接口ProxyFactoryBean(代理Bean工厂),主要用于代理实现类的对象,为接口口对象准备资源。
- spring的注入方式
5.1.接口注入
接口注入指spring容器使用注入的实现类为依赖类的接口对象进行赋值的方式。(上例即为接口注入的方式)
5.2.set注入
Spring容器调用注入类的set方法为注入类的属性进行赋值的方式.上例中使用
<property>节点实现注入类属性的赋值。
<bean id="usbBiz" class="com.biz.UsbFine"> |
5.3.集合属性的注入
5.3.1.为注入类的List集合属性进行赋值的方式
示例如下:
编写ListBiz类
package com.biz; import java.util.*; public class ListBiz { private List<String> mylist; public List<String> getMylist() { return mylist; } public void setMylist(List<String> mylist) { this.mylist = mylist; } } |
配置文件如下:
<!-- 注入List属性的类 --> <bean id="listbiz" class="com.biz.ListBiz"> <property name="mylist"> <list> <value>张飞</value> <value>马超</value> <value>关羽</value> <value>赵云</value> <value>黄忠</value> </list> </property> </bean> |
测试:
package com.test; import com.biz.ListBiz; import com.biz.UsbBiz; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; public class ListBizTest { public static void main(String[] args) { //获取spring容器的上下文关系对象,并加载配置文件spring-config.xml ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); ListBiz lsbiz= (ListBiz) ctx.getBean("listbiz"); List<String> lsstr=lsbiz.getMylist(); lsstr.forEach(str->{ System.out.println(str); }); } } |
正在上传…重新上传取消
5.3.2.Set集合属性的注入
SetBiz.java
package com.biz; import java.util.List; import java.util.Set; public class SetBiz { private Set<String> myset; public Set<String> getMyset() { return myset; } public void setMyset(Set<String> myset) { this.myset = myset; } } |
在spring-config.xml文件中注入SetBiz
<!-- 注入Set属性的类 --> <bean id="setbiz" class="com.biz.SetBiz"> <property name="myset"> <set> <value>张飞</value> <value>马超</value> <value>关羽</value> <value>赵云</value> <value>黄忠</value> <value>马超</value> </set> </property> </bean> |
SerBizTest.java
package com.test; import com.biz.ListBiz; import com.biz.SetBiz; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; import java.util.Set; public class SetBizTest { public static void main(String[] args) { //获取spring容器的上下文关系对象,并加载配置文件spring-config.xml ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); SetBiz setBiz= (SetBiz) ctx.getBean("setbiz"); Set<String> myset=setBiz.getMyset(); myset.forEach(str->{ System.out.println(str); }); } } |
正在上传…重新上传取消
5.3.3.Map集合属性的注入
MapBiz.java
package com.biz; import java.util.*; public class MapBiz { private Map<String,Object> mymap; public Map<String, Object> getMymap() { return mymap; } public void setMymap(Map<String, Object> mymap) { this.mymap = mymap; } } |
注入MapBiz
<!-- 注入Map集合属性的类 --> <bean id="mapbiz" class="com.biz.MapBiz"> <property name="mymap"> <map> <entry key="CN" value="中国"/> <entry key="US" value="美国"/> <entry key="FR" value="法国"/> <entry key="RU" value="俄罗斯"/> <entry key="EN" value="英国"/> </map> </property> </bean> |
MapBziTest.java
package com.test; import com.biz.MapBiz; import com.biz.SetBiz; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.Map; import java.util.Set; public class MapBizTest { public static void main(String[] args) { //获取spring容器的上下文关系对象,并加载配置文件spring-config.xml ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); MapBiz mbiz= (MapBiz) ctx.getBean("mapbiz"); Map<String,Object> map=mbiz.getMymap(); Set<String> keys=map.keySet();//获取键集 keys.forEach(key->{//通过主键获取Map集合的值对象 System.out.println(key+":"+map.get(key)); }); } } |
正在上传…重新上传取消
5.3.4.Properties属性集合的注入(Map的子类)
PropertiesBiz.java
package com.biz; import java.util.Map; import java.util.Properties; public class PropertiesBiz { private Properties myprop; public Properties getMyprop() { return myprop; } public void setMyprop(Properties myprop) { this.myprop = myprop; } } |
注入:
<!-- 注入Properties集合属性的类 --> <bean id="propbiz" class="com.biz.PropertiesBiz"> <property name="myprop"> <props> <prop key="CN">中国</prop> <prop key="US">美国</prop> <prop key="FR">法国</prop> <prop key="RU">俄罗斯</prop> <prop key="EN">英国</prop> </props> </property> </bean> |
测试:
package com.test; import com.biz.MapBiz; import com.biz.PropertiesBiz; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.Map; import java.util.Properties; import java.util.Set; public class PropertiesBizTest { public static void main(String[] args) { //获取spring容器的上下文关系对象,并加载配置文件spring-config.xml ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); PropertiesBiz pbiz= (PropertiesBiz) ctx.getBean("propbiz"); Properties prop= pbiz.getMyprop(); Set<Object> keys=prop.keySet(); keys.forEach(key->{ System.out.println(key+":"+prop.get(key)); }); } } |
正在上传…重新上传取消
5.4.bean的依赖关系注入
依赖的类和被依赖的类都注入到spring容器,则使用关联依赖进行注入
<bean id=”被依赖类标识” class=”被依赖类的路径”/>
<bean id=”依赖类标识” class=”依赖类的路径”>
<property name=”关系属性名称” ref=”被依赖类标识”/>
</bean>
示例如下:
UsersDao.java
package com.dao; public class UsersDao { public void save(){ System.out.println("dao正在保存数据....."); } public void findAll(){ System.out.println("dao正在查询数据....."); } } |
UsersBiz.java
package com.dao; public class UsersDao { public void save(){ System.out.println("dao正在保存数据....."); } public void findAll(){ System.out.println("dao正在查询数据....."); } }package com.biz; import com.dao.*; public class UsersBiz { private UsersDao usersDao; public UsersDao getUsersDao() { return usersDao; } public void setUsersDao(UsersDao usersDao) { this.usersDao = usersDao; } public void save(){ System.out.println("biz正在保存数据....."); usersDao.save(); } public void findAll(){ System.out.println("biz正在查询数据....."); usersDao.findAll(); } } |
配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 正在上传…重新上传取消 <bean id="udao" class="com.dao.UsersDao"/> <bean id="ubiz" class="com.biz.UsersBiz"> <!-- 使用ref实现注入类的引用关联 --> <property name="usersDao" ref="udao"/> </bean> </beans> |
spring容器会自动将udao对象设置到Usersbiz的usersDao属性中。
5.5.自动注入的方式(一般用于注解注入)
5.5.1.byName模式的注入
根据注入类的属性名称为注入类的属性赋值,此种注入方式为精确注入。
5.5.2.byType模式的注入
根据注入类的属性类型为注入类的属性赋值。
5.5.3.构造器注入
根据注入类的构造方法为注入类的属性赋值。
package com.biz; import com.dao.*; public class UsersBiz { private UsersDao usersDao; private String uname; private String passwd; public UsersBiz() { } public UsersBiz(String uname,String passwd) { this.uname = uname; this.passwd=passwd; } public UsersDao getUsersDao() { return usersDao; } public void setUsersDao(UsersDao usersDao) { this.usersDao = usersDao; } public void save(){ System.out.println("uname--->"+uname); System.out.println("passwd--->"+passwd); System.out.println("biz正在保存数据....."); usersDao.save(); } public void findAll(){ System.out.println("biz正在查询数据....."); usersDao.findAll(); } } |
配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="udao" class="com.dao.UsersDao"/> <bean id="ubiz" class="com.biz.UsersBiz"> <!-- 使用ref实现注入类的引用关联 --> <property name="usersDao" ref="udao"/> <!-- 使用构造方法为属性赋值 index的值描述参数的索引位置 index="n"表示第n个参数索引位置n的值从0开始 --> <constructor-arg index="0" value="张飞"/> <constructor-arg index="1" value="112233"/> </bean> </beans> |
正在上传…重新上传取消
5.5.4.自动装配(主要用于注解的配置@Autowrite实现)
Spring容器自动根据注入类的构造函数给属性赋值,如果没有构造方法,则使用byType模式为属性赋值。
- springAOP实现的原理
6.1.spring使用ProxyFactoryBean代理注入的接口实现类
当调用者需要从spring容器获取依赖的注入类对象时,通过代理工厂获取,而不是直接获取。
示例如下:
UserDao.java接口:
package com.dao; public interface UsersDao { public void save(); public void update(); public void delById(); public void findById(); public void findAll(); } |
实现类如下:
package com.dao; public class UsersDaoImp implements UsersDao { @Override public void save() { //System.out.println("事务处理...."); System.out.println("dao正在保存数据..."); //System.out.println("结束事务处理....."); } @Override public void update() { System.out.println("dao正在更新数据..."); } @Override public void delById() { System.out.println("dao正在删除数据..."); } @Override public void findById() { System.out.println("dao正在查找数据..."); } @Override public void findAll() { System.out.println("dao正在显示数据..."); } } |
在spring配置文件中注入实现类
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--注入接口的实现类--> <bean id="udao" class="com.dao.UsersDaoImp"></bean> <!--注入spring的代理bean工厂--> <bean id="daoproxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 指定要代理的接口 --> <property name="proxyInterfaces" value="com.dao.UsersDao"></property> <!-- 要指定代理接口的实现 --> <property name="target" ref="udao"/> </bean> </beans> |
TestProxyBean.java 测试:
package com.test; import com.dao.UsersDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestProxyBean { public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); //通过代理工厂获取接口对象 UsersDao usersDao= (UsersDao) ctx.getBean("daoproxy"); usersDao.save(); usersDao.update(); usersDao.delById(); usersDao.findById(); usersDao.findAll(); } } |
正在上传…重新上传取消
6.2.使用CGLIB代理实现ProxyFactotyBean的代理
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--注入接口的实现类--> <bean id="udao" class="com.dao.UsersDaoImp"></bean> <!--注入spring的代理bean工厂--> <bean id="daoproxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 指定要代理的接口 --> <property name="proxyInterfaces" value="com.dao.UsersDao"></property> <!-- 要指定代理接口的实现 --> <property name="target" ref="udao"/> </bean> <!--注入spring的代理bean工厂使用CGLIB实现代理--> <bean id="cglibdaoproxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 指定要代理的接口 --> <property name="proxyTargetClass" value="true"/> <!-- 要指定代理接口的实现 --> <property name="target" ref="udao"/> </bean> </beans> |
package com.test; import com.dao.UsersDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestProxyBean { public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); //通过代理工厂获取接口对象 UsersDao usersDao= (UsersDao) ctx.getBean("cglibdaoproxy"); usersDao.save(); usersDao.update(); usersDao.delById(); usersDao.findById(); usersDao.findAll(); } } |
正在上传…重新上传取消
6.3.使用中断通知机制,在代理工厂中拦截调用者依赖的类对象,为调用的方法提供服务(日志、安全、事务和异常)。
使用aop联盟的MethodInterceptor拦截组件实现Aop的处理支持。
- 编写方法拦截器,需要实现MethodInterceptor接口
DaoMethodInterceptor.java
package com.interceptor; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class DaoMethodInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("开始事务处理....."); System.out.println("开始日志处理....."); System.out.println("开始安全处理....."); System.out.println("开始异常处理....."); System.out.println("============================"); System.out.println("正在调用"+methodInvocation.getMethod().getName()+"方法....."); Object obj=methodInvocation.proceed();//开始执行要调用的方法 System.out.println("============================="); System.out.println("提交并结束事务处理....."); System.out.println("结束日志处理....."); System.out.println("结束安全处理....."); System.out.println("结束异常处理....."); return null; } } |
- 在spring-config.xml中配置中断拦截器类
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--注入接口的实现类--> <bean id="udao" class="com.dao.UsersDaoImp"></bean> <!-- 注入中断拦截器 --> <bean id="daointerceptor" class="com.interceptor.DaoMethodInterceptor"/> <!--注入spring的代理bean工厂--> <bean id="daoproxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 指定要代理的接口 --> <property name="proxyInterfaces" value="com.dao.UsersDao"></property> <!-- 要指定代理接口的实现 --> <property name="target" ref="udao"/> </bean> <!--注入spring的代理bean工厂使用CGLIB实现代理--> <bean id="cglibdaoproxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 指定要代理的接口 --> <property name="proxyTargetClass" value="true"/> <!-- 要指定代理接口的实现 --> <property name="target" ref="udao"/> <!--指定拦截器组件--> <property name="interceptorNames" value="daointerceptor"/> </bean> </beans> |
- 在代理工厂中指定拦截器组件,对调用者依赖的对象进行拦截处理
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--注入接口的实现类--> <bean id="udao" class="com.dao.UsersDaoImp"></bean> <!-- 注入中断拦截器 --> 正在上传…重新上传取消 <bean id="daointerceptor" class="com.interceptor.DaoMethodInterceptor"/> <!--注入spring的代理bean工厂--> <bean id="daoproxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 指定要代理的接口 --> <property name="proxyInterfaces" value="com.dao.UsersDao"></property> <!-- 要指定代理接口的实现 --> <property name="target" ref="udao"/> </bean> <!--注入spring的代理bean工厂使用CGLIB实现代理--> <bean id="cglibdaoproxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 指定要代理的接口 --> <property name="proxyTargetClass" value="true"/> <!-- 要指定代理接口的实现 --> <property name="target" ref="udao"/> <!--指定拦截器组件--> <property name="interceptorNames" value="daointerceptor"/> </bean> </beans> |
测试类:
package com.test; import com.dao.UsersDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestProxyBean { public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); //通过代理工厂获取接口对象 UsersDao usersDao= (UsersDao) ctx.getBean("cglibdaoproxy"); usersDao.save(); System.out.println("=================================="); usersDao.update(); System.out.println("=================================="); usersDao.delById(); System.out.println("=================================="); usersDao.findById(); System.out.println("=================================="); usersDao.findAll(); } } |
正在上传…重新上传取消
- spring的事务管理器(AOP组件的使用)
7.1.事务管理的分类
1.编程式事务---使用代码实现事务处理
2.声明式事务--在spring配置文件中声明事务管理的描述,由spring容器负责处理事务
7.2.spring的事务组件
1.JDBC的事务管理器DataSourceTransactionManager
DataSourceTransactionManager
2.Hibernate的事务管理器HibernateTransactionManager
3.Jta的事务管理器JtaTransactionManager(SpringData)
7.3.spring中事务管理配置描述(需要配置spring配置文件的头信息,指定事务tx、上下文关系context、aop的命名空间)
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> |
7.3.1.配置数据源,由spring容器管理数据库的访问
<!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/epdb"/> <property name="username" value="root"/> <property name="password" value="java"/> </bean> |
7.3.2.配置jdbc的事务管理器,使用spring容器管理jdbc的事务
<!-- 配置jdbc的事务管理器DataSourceTransactionManager,事务管理器需要依赖数据源 --> <bean id="txmanager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> |
7.3.3.配置事务通知,由spring容器负责对业务逻辑中的事务处理进行管理,配置事务的传播机制,也就是描述事务应用在哪些方法中。
<!-- 配置事务通知,指定哪些方法需要使用事务管理 --> <tx:advice id="txavd" transaction-manager="txmanager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="del*" propagation="REQUIRED"/> <tx:method name="find*" propagation="NOT_SUPPORTED"/> </tx:attributes> </tx:advice> |
7.3.4.配置事务的切入点,指定事务应用在哪个包的哪些类中。
<!-- 配置事务的切入点,指定那个包以及包中的类需要使用到事务通知 --> <aop:config> <aop:pointcut id="bizpoint" expression="execution(* com.biz.*.* (..))"/> <aop:advisor advice-ref="txavd" pointcut-ref="bizpoint"/> </aop:config> |
7.5.使用spring容器提供的JDBCTemplate类实现CRUD操作(需要注入在spring-config.xml中)
<!--注入jdbc的模板类--> <bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> |
7.6编写dao类和业务类
实体类如下:
Emp.java
package com.enrity; import java.io.Serializable; public class Emp implements Serializable { private Long eid; private String ename; private String passwd; private String sex; private Long depid; private String wids; private String photo; public Emp() { } public Emp(Long eid, String ename, String passwd, String sex, Long depid, String wids, String photo) { this.eid = eid; this.ename = ename; this.passwd = passwd; this.sex = sex; this.depid = depid; this.wids = wids; this.photo = photo; } public Emp(String ename, String passwd, String sex, Long depid, String wids, String photo) { this.ename = ename; this.passwd = passwd; this.sex = sex; this.depid = depid; this.wids = wids; this.photo = photo; } public Long getEid() { return eid; } public void setEid(Long eid) { this.eid = eid; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Long getDepid() { return depid; } public void setDepid(Long depid) { this.depid = depid; } public String getWids() { return wids; } public void setWids(String wids) { this.wids = wids; } public String getPhoto() { return photo; } public void setPhoto(String photo) { this.photo = photo; } } |
EmpDao.java
package com.dao; import com.enrity.*; import org.springframework.jdbc.core.JdbcTemplate; import java.util.*; public class EmpDao { private JdbcTemplate jdbcTemplate; public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public int save(Emp emp){ String sql="insert into emp(ename,passwd,sex,depid,wids,photo) " + " values(?,?,?,?,?,?)"; int code=jdbcTemplate.update(sql,new Object[]{ emp.getEname(), emp.getPasswd(), emp.getSex(), emp.getDepid(), emp.getWids(), emp.getPhoto() }); return code; } public List<Emp> findAll(){ String sql="select * from emp"; List<Map<String,Object>> lsmap=jdbcTemplate.queryForList(sql); List<Emp> lsemp=new ArrayList<>(); for(Map<String,Object> map:lsmap){ Emp emp=new Emp(); emp.setEid((Long)map.get("eid"));; emp.setEname((String)map.get("ename"));; emp.setPasswd((String)map.get("passwd"));; emp.setSex((String)map.get("sex"));; emp.setWids((String) map.get("wids"));; emp.setPhoto((String) map.get("photo"));; emp.setDepid((Long)map.get("depid"));; } return lsemp; } } |
在spring-config.xml中配置DAO和Biz
<!--注入EmpDao--> <bean id="edao" class="com.dao.EmpDao"> <property name="jdbcTemplate" ref="jt"/> </bean> <!--注入biz--> <bean id="ebiz" class="com.biz.EmpBiz"> <property name="empDao" ref="edao"/> </bean> |
测试类:
package com.test; import com.biz.EmpBiz; import com.enrity.Emp; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestEmpBiz { public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); EmpBiz empBiz= (EmpBiz) ctx.getBean("ebiz"); Emp emp=new Emp("蒋干","112233","男",2L,"1,2,3","default.jpg"); int code=empBiz.save(emp); if(code>0){ System.out.println("保存成功!"); }else{ System.out.println("保存失败!"); } } } |
7.7.使用注解,替代配置文件中注入的组件
7.7.1.@Servic或者@Compoent替代bean的注入方式
@Service(“id标识名称”)
public class Xxx{
...
}
替代<bean id=”标识名称” class=”....”/>
示例:
package com.dao; import com.enrity.*; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.*; @Service("edao") public class EmpDao { @Resource(name = "jt") private JdbcTemplate jdbcTemplate; public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public int save(Emp emp){ String sql="insert into emp(ename,passwd,sex,depid,wids,photo) " + " values(?,?,?,?,?,?)"; int code=jdbcTemplate.update(sql,new Object[]{ emp.getEname(), emp.getPasswd(), emp.getSex(), emp.getDepid(), emp.getWids(), emp.getPhoto() }); return code; } public List<Emp> findAll(){ String sql="select * from emp"; List<Map<String,Object>> lsmap=jdbcTemplate.queryForList(sql); List<Emp> lsemp=new ArrayList<>(); for(Map<String,Object> map:lsmap){ Emp emp=new Emp(); emp.setEid((Long)map.get("eid"));; emp.setEname((String)map.get("ename"));; emp.setPasswd((String)map.get("passwd"));; emp.setSex((String)map.get("sex"));; emp.setWids((String) map.get("wids"));; emp.setPhoto((String) map.get("photo"));; emp.setDepid((Long)map.get("depid"));; } return lsemp; } } |
7.7.2使用@Resource或者@Autowrite替代property的依赖关联注入
@Resource替代如下配置:
<!--注入jdbc的模板类--> <bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!--注入EmpDao <bean id="edao" class="com.dao.EmpDao"> <property name="jdbcTemplate" ref="jt"/> </bean> |
7.7.3.使用@Transactional注解事务声明,在配置文件中需要修改tx的通知配置声明为以下方式
<tx:annotation-driven transaction-manager="txmanager"/> |
修改EmpBiz的事务注解如下:
package com.biz; import com.enrity.*; import java.util.*; import com.dao.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service("ebiz") @Transactional //声明事务注解,表示该类受事务管理 public class EmpBiz { @Resource(name ="edao" ) private EmpDao empDao; public EmpDao getEmpDao() { return empDao; } public void setEmpDao(EmpDao empDao) { this.empDao = empDao; } public int save(Emp emp){ int code=empDao.save(emp); return code; } public List<Emp> findAll(){ return empDao.findAll(); } } |
7.7.4.修改spring-config.xml文件,让spring容器支持注解声明,并配置注解扫描器,扫描注解类所在的包
<!-- 配置注解支持 --> <context:annotation-config></context:annotation-config> <!-- 配置注解扫描器,扫描注解类所在的包 --> <context:component-scan base-package="com.dao"/> <context:component-scan base-package="com.biz"/> |
测试类:
package com.test; import com.biz.EmpBiz; import com.enrity.Emp; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestEmpBiz { public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("/spring-config.xml"); EmpBiz empBiz= (EmpBiz) ctx.getBean("ebiz"); Emp emp=new Emp("蒋干","112233","男",12L,"1,2,3","default.jpg"); int code= 0; try { code = empBiz.save(emp); } catch (Exception e) { System.out.println("出现异常!"); } if(code>0){ System.out.println("保存成功!"); }else{ System.out.println("保存失败!"); } } } |
Spring-config.xml完整支持注解的配置如下(项目中常用):
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <!-- 配置注解支持 --> <context:annotation-config></context:annotation-config> <!-- 配置注解扫描器,扫描注解类所在的包 --> <context:component-scan base-package="com.dao"/> <context:component-scan base-package="com.biz"/> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/epdb"/> <property name="username" value="root"/> <property name="password" value="java"/> </bean> <!-- 配置jdbc的事务管理器DataSourceTransactionManager,事务管理器需要依赖数据源 --> <bean id="txmanager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 注入注解事务通知,指定哪些方法需要使用事务,需要配合@Transactional 使用 --> <tx:annotation-driven transaction-manager="txmanager"/>
<!--注入jdbc的模板类--> <bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> </beans> |
- spring整合hibernate
8.1.将hibernate的SessionFactory和Session由spring容器进行管理,事务使用spring容器提供的Hibernate事务管理器管理.
8.2.spring整合Hibernate的步骤
需要首先在项目中导入spring和hibernate的组件包
1.导入spring组件包
正在上传…重新上传取消
- 导入hibernate组件包和数据区驱动包
正在上传…重新上传取消
- 导入mysql数据库驱动包
正在上传…重新上传取消
正在上传…重新上传取消
4.配置数据源
正在上传…重新上传取消
8.2.1.修改配置如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <context:annotation-config></context:annotation-config> <context:component-scan base-package="com.dao"/> <context:component-scan base-package="com.biz"/> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/epdb"/> <property name="username" value="root"/> <property name="password" value="java"/> </bean> <!-- 注入Hibernate的session工厂 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mappingLocations" value="com/entity/*.hbm.xml"/> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.connection.autocommit">true</prop> </props> </property> </bean> <!-- 注入hibernate的事务管理器 --> <bean id="txmanager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="dataSource" ref="dataSource"/> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 注入事务注解支持 --> <tx:annotation-driven transaction-manager="txmanager"/> </beans> |
8.2.2.配置注解支持和数据源
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/epdb"/>
<property name="username" value="root"/>
<property name="password" value="java"/>
</bean>
8.2.3.配置hibernate的Sessionfactory注入
<!-- 注入hibernate的事务管理器 -->
<bean id="txmanager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="dataSource" ref="dataSource"/>
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 注入事务注解支持 -->
<tx:annotation-driven transaction-manager="txmanager"/>
8.2.4.编写Dao类
package com.dao; import com.entity.Emp; import java.util.List; public interface EmpDao { public int save(Emp emp); public List<Emp> findAll(); } |
DaoImp
package com.dao; import com.entity.Emp; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.springframework.dao.support.DaoSupport; import org.springframework.orm.hibernate5.HibernateTemplate; import org.springframework.orm.hibernate5.support.HibernateDaoSupport; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; @Service("empDao") @Transactional public class EmpDaoImp implements EmpDao { @Resource(name = "sessionFactory") private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public int save(Emp emp) { Session session=sessionFactory.getCurrentSession(); try { session.save(emp); return 1; } catch (Exception e) { e.printStackTrace(); } return 0; } @Override public List<Emp> findAll() { Session session=sessionFactory.openSession(); return session.createQuery("from Emp").list(); } } |
Hibernate: select dep_.depid, dep_.depname as depname2_0_ from dep dep_ where dep_.depid=?
Hibernate: insert into emp (ename, passwd, sex, wids, photo, depid, eid) values (?, ?, ?, ?, ?, ?, ?)
保存成功!
正在上传…重新上传取消
- 使用ssh(struts2+spring+hibernate)构建员工管理系统
9.1.新建项目引入ssh组件包和数据库组件包,并建立数据库环境
正在上传…重新上传取消
正在上传…重新上传取消
正在上传…重新上传取消
正在上传…重新上传取消
9.2.生成实体类和映射文件,修改实体类将页面的属性和实体类的属性对应
首先在applicationContext.xml文件中配置hibernate的sessionFactory,然后生成实体类和映射文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <context:annotation-config></context:annotation-config> <context:component-scan base-package="com.dao"/> <context:component-scan base-package="com.biz"/> <context:component-scan base-package="com.action"/> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/epdb"/> <property name="username" value="root"/> <property name="password" value="java"/> </bean> <!-- 注入Hibernate的session工厂 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.connection.autocommit">true</prop> <prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/epdb</prop> <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop> </props> </property> <property name="mappingLocations"> <list> <value>classpath:com/entity/Dep.hbm.xml</value> <value>classpath:com/entity/Emp.hbm.xml</value> <value>classpath:com/entity/Welfare.hbm.xml</value> </list> </property> </bean> <!-- 注入hibernate的事务管理器 --> <bean id="txmanager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="dataSource" ref="dataSource"/> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 注入事务注解支持 --> <tx:annotation-driven transaction-manager="txmanager"/> </beans> |
9.3.编写DAO类(加入注解@Service)和业务类(将以前的业务类复制到当前项目指定的biz包中)
DepDaoImp.java
package com.dao.imp; import com.dao.DepDao; import com.entity.Dep; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class DepDaoImp implements DepDao { @Resource(name = "sessionFactory") private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public List<Dep> findAll() { String hql="from Dep where 1=1 order by depid"; Session session=sessionFactory.getCurrentSession(); Query query=session.createQuery(hql); List<Dep> lsdep= null; try { lsdep = query.list(); } catch (Exception e) { e.printStackTrace(); } finally { //session.close(); } return lsdep; } } |
WelfareDaoImp.java
package com.dao.imp; import com.dao.DepDao; import com.dao.WelfareDao; import com.entity.Dep; import com.entity.Welfare; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class WelfareDaoImp implements WelfareDao { @Resource(name = "sessionFactory") private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public List<Welfare> findAll() { String hql="from Welfare where 1=1 order by wid"; Session session=sessionFactory.getCurrentSession(); Query query=session.createQuery(hql); List<Welfare> lswf= null; try { lswf = query.list(); } catch (Exception e) { e.printStackTrace(); } finally { //session.close(); } return lswf; } @Override public Welfare findById(Integer wid) { Session session=sessionFactory.getCurrentSession(); //使用load方法获取根据主键查询的对象 Welfare wf=null; try { wf = session.get(Welfare.class,wid); return wf; } catch (Exception e){ e.printStackTrace(); }finally { // session.close(); } return null; } } |
EmpDaoImp.java
package com.dao.imp; import com.dao.EmpDao; import com.entity.Emp; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; @Service @Transactional //注入事务注解 public class EmpDaoImp implements EmpDao { @Resource(name = "sessionFactory") private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public int save(Emp emp) { Session session=sessionFactory.getCurrentSession();//使用spring容器提供当前的数据库会话对象处理事务 try { session.save(emp); return 1; } catch (Exception e) { e.printStackTrace(); } finally { //session.close(); } return 0; } @Override public int update(Emp emp) { Session session=sessionFactory.getCurrentSession(); try { session.merge(emp); return 1; } catch (Exception e) { e.printStackTrace(); } finally { //session.close(); } return 0; } @Override public int delById(Integer eid) { Session session=sessionFactory.getCurrentSession(); try { Emp emp=session.load(Emp.class,eid); session.delete(emp); return 1; } catch (Exception e) { e.printStackTrace(); } finally { // session.close(); } return 0; } @Override public Emp findById(Integer eid) { Session session=sessionFactory.openSession(); Emp emp= null;//立即将整个员工对象先加载到内存中 try { emp = session.get(Emp.class,eid); } catch (Exception e) { e.printStackTrace(); } finally { session.close(); } return emp; } @Override public List<Emp> findPageAll(Integer page, Integer pagesize) { String hql="from com.entity.Emp where 1=1 order by eid"; Session session=sessionFactory.openSession(); System.out.println("isopen---->"+session.isOpen()); Query query=session.createQuery(hql); query.setFirstResult((page-1)*pagesize); try { query.setMaxResults(pagesize); List<Emp> lsemp=query.list(); return lsemp; } catch (Exception e) { e.printStackTrace(); }finally { session.close(); } return null; } @Override public int findMaxRow() { String hql="select count(*) from Emp"; Session session=sessionFactory.openSession(); if(session==null||!session.isOpen()){ session=sessionFactory.openSession(); } try { Query query=session.createQuery(hql); Long maxrow= (Long) query.uniqueResult(); return maxrow.intValue(); } catch (Exception e) { e.printStackTrace(); }finally { session.close(); } return 0; } } |
EmpBiz.java
package com.biz; import com.entity.Dep; import com.entity.Emp; import com.entity.Welfare; import java.util.Arrays; import java.util.List; import com.dao.*; import com.dao.imp.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class EmpBizImp implements EmpBiz { @Autowired//使用自动装配 private DepDao depDao; @Autowired private WelfareDao welfareDao; @Autowired private EmpDao empDao; public DepDao getDepDao() { return depDao; } public void setDepDao(DepDao depDao) { this.depDao = depDao; } public WelfareDao getWelfareDao() { return welfareDao; } public void setWelfareDao(WelfareDao welfareDao) { this.welfareDao = welfareDao; } public EmpDao getEmpDao() { return empDao; } public void setEmpDao(EmpDao empDao) { this.empDao = empDao; } @Override public int save(Emp emp) { //获取从界面传递的福利编号数组 String[] wids=emp.getWidsarray(); if(wids!=null&&wids.length>0){ StringBuilder sb=new StringBuilder(); for (String wid:wids) { sb.append(wid+","); } //使用,号连接数组的值 String s=sb.toString(); System.out.println("s--->"+s); emp.setWids(s);//保存使用,号拼接的福利编号 } return empDao.save(emp); } @Override public int update(Emp emp) { //获取从界面传递的福利编号数组 String[] wids=emp.getWidsarray(); if(wids!=null&&wids.length>0){ StringBuilder sb=new StringBuilder();//定义字符缓冲对象 for (String wid:wids) { sb.append(wid+",");//将福利编号使用,号进行链接,准备向表中的福利编号字段存储。 } //使用,号连接数组的值 String s=sb.toString(); System.out.println("s--->"+s); emp.setWids(s);//保存使用,号拼接的福利编号 } return empDao.update(emp);//确定保存员工的信息 } @Override public int delById(Integer eid) { return empDao.delById(eid); } @Override public Emp findById(Integer eid) { Emp emp=empDao.findById(eid); //获取福利的编号 String wids=emp.getWids();//从表中获取员工的福利编号,使用,号拼接的员工福利编号 wids=wids.substring(0,wids.lastIndexOf(",")); System.out.println("wids--->"+wids); if(wids!=null&&!wids.trim().equals("")){ String[] widsArray=wids.split(","); emp.setWidsarray(widsArray); //获取福利的名称数组 String[] wnames=new String[widsArray.length]; for(int i=0;i<widsArray.length;i++){ String wid=widsArray[i];//获取福利编号 Welfare wf=welfareDao.findById(new Integer(wid)); wnames[i]=wf.getWname();//将福利名称传递给福利名称数组 } emp.setWnamearray(wnames); } return emp; } @Override public List<Emp> findPageAll(Integer page, Integer pagesize) { if(page==null||page<1)page=1; if(pagesize==null||pagesize<1)pagesize=5; List<Emp> lsemp=empDao.findPageAll(page,pagesize); for (Emp emp:lsemp) { //获取福利的编号 String wids=emp.getWids();//从表中获取员工的福利编号,使用,号拼接的员工福利编号 wids=wids.substring(0,wids.lastIndexOf(",")); System.out.println("wids--->"+wids); if(wids!=null&&!wids.trim().equals("")){ String[] widsArray=wids.split(","); emp.setWidsarray(widsArray); //获取福利的名称数组 String[] wnames=new String[widsArray.length]; for(int i=0;i<widsArray.length;i++){ String wid=widsArray[i];//获取福利编号 Welfare wf=welfareDao.findById(new Integer(wid)); wnames[i]=wf.getWname();//将福利名称传递给福利名称数组 } emp.setWnamearray(wnames); } } return lsemp; } @Override public int findMaxRow() { return empDao.findMaxRow(); } @Override public List<Dep> findAllDep() { return depDao.findAll(); } @Override public List<Welfare> findAllWelfare() { return welfareDao.findAll(); } /*public static void main(String[] args) { EmpBiz ebiz=new EmpBizImp(); List<Emp> lsemp=ebiz.findPageAll(1,5); lsemp.forEach(e->{ System.out.println(e); }); JSONUtil.printJsonString(null,lsemp); }*/ } |
9.4.复制Action控制器类到当前项目的action包中,并且加入注解(@Contraller),注入到spring容器。
EmpAction.java
package com.action; import com.biz.EmpBiz; import com.biz.EmpBizImp; import com.entity.*; import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.util.*; import com.util.*; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import java.io.*; import javax.servlet.http.*; @Namespace("/") @ParentPackage("struts-default") @Controller//注入控制器到spring容器 public class EmpAction implements IEmpAction { private Emp emp; private Integer eid; private String path; //分页的参数 private Integer page;//当前页数 private Integer pagesize;//每页记录数 @Autowired private EmpBiz empBiz; public Emp getEmp() { return emp; } public void setEmp(Emp emp) { this.emp = emp; } public Integer getEid() { return eid; } public void setEid(Integer eid) { this.eid = eid; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public Integer getPage() { return page; } public void setPage(Integer page) { this.page = page; } public Integer getPagesize() { return pagesize; } public void setPagesize(Integer pagesize) { this.pagesize = pagesize; } @Override @Action(value = "save_Emp",results = { @Result(name = "ok",location = "${path}",type = "redirect") }) public String save() { System.out.println("emp-->"+emp.getWidsarray()); /****文件上传的处理*************************/ //获取服务器的根路径 String realpath=ServletActionContext.getServletContext().getRealPath("/"); File pic=emp.getPic();//获取上传的文件对象 if(pic!=null&&pic.length()>0){ //获取上传的文件的名称 String fname=emp.getPicFileName(); System.out.println("fname--->"+fname); //获取上传文件的后缀 if(fname.lastIndexOf(".")!=-1){//存在后缀 //获取上传文件的后缀 String ext=fname.substring(fname.lastIndexOf(".")); //判断上传文件的后缀是不是.jpg或者.png if(ext.equalsIgnoreCase(".jpg")||ext.equalsIgnoreCase(".png")){ //将上传的文件名称改名 String newfname=new Date().getTime()+ext; System.out.println("新的文件名称:"+newfname); //创建文件对象,指定文件在服务器的存放位置 File destFile=new File(realpath+"/uppic/"+newfname); try { //开始上传 FileUtils.copyFile(pic,destFile); emp.setPhoto(newfname);//设置上传文件的名称到数据库表 } catch (IOException e) { e.printStackTrace(); } } } } /*****************************************/ int code=0; if(emp.getEid()==0){ code=empBiz.save(emp); }else{ //如果员工编号不为空,进行更新 code=empBiz.update(emp); } if(code>0){ path="emp.html";//刷新页面 return "ok"; } path="fail.html"; return "ok"; } @Override @Action(value = "update_Emp",results = { @Result(name = "ok",location = "${path}",type = "redirect") }) public String update() { /****文件上传的处理*************************/ //获取服务器的根路径 String realpath=ServletActionContext.getServletContext().getRealPath("/"); File pic=emp.getPic();//获取上传的文件对象 if(pic!=null&&pic.length()>0){ //获取上传的文件的名称 String fname=emp.getPicFileName(); System.out.println("fname--->"+fname); //获取上传文件的后缀 if(fname.lastIndexOf(".")!=-1){//存在后缀 //获取上传文件的后缀 String ext=fname.substring(fname.lastIndexOf(".")); //判断上传文件的后缀是不是.jpg或者.png if(ext.equalsIgnoreCase(".jpg")||ext.equalsIgnoreCase(".png")){ //将上传的文件名称改名 String newfname=new Date().getTime()+ext; System.out.println("新的文件名称:"+newfname); //创建文件对象,指定文件在服务器的存放位置 File destFile=new File(realpath+"/uppic/"+newfname); try { //开始上传 FileUtils.copyFile(pic,destFile); emp.setPhoto(newfname);//设置上传文件的名称到数据库表 } catch (IOException e) { e.printStackTrace(); } } } }else{//没有上传的文件,将原来的照片文件设置给要更新的员工对象 String oldphoto=empBiz.findById(emp.getEid()).getPhoto(); emp.setPhoto(oldphoto); } /*****************************************/ int code=empBiz.update(emp); if(code>0){ path="emp.html";//刷新页面 return "ok"; } path="fail.html"; return "ok"; } @Override @Action(value = "delById_Emp") public String delById() { HttpServletResponse response= ServletActionContext.getResponse(); PrintWriter out=null; try { out=response.getWriter(); int code=empBiz.delById(eid);//根据员工编号删除 if(code>0){ out.print("1");//删除成功 return null; } out.print("0");//删除失败 } catch (IOException e) { e.printStackTrace(); } return null; } @Override @Action(value = "findById_Emp") public String findById() { HttpServletResponse response= ServletActionContext.getResponse(); //获取要查找的数据 Emp oldemp=empBiz.findById(eid); System.out.println("oldemp---->"+oldemp); JSONUtil.printJsonString(response,oldemp); /*EmpVo ev=new EmpVo();//创建emp的值对象类 try { BeanUtils.copyProperties(ev,oldemp);//让emp对象脱离hibernate容器的控制 JSONUtil.printJsonString(response,ev); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); }*/ return null; } @Override @Action(value = "findPageAll_Emp") public String findPageAll() { HttpServletResponse response= ServletActionContext.getResponse(); PageBean pb=new PageBean(); System.out.println("action--page--->"+page); System.out.println("action--pagesize--->"+pagesize); page=page==null||page<1?pb.getPage():page; pagesize=pagesize==null||pagesize<1?pb.getPagesize():pagesize; if(pagesize>20)pagesize=20;//限制每页的记录数不要超过20条记录 //获取总记录数 int maxrow=empBiz.findMaxRow(); int maxpage=maxrow%pagesize==0?maxrow/pagesize:maxrow/pagesize+1; if(maxpage==0)maxpage=1; if(page>maxpage)page=maxpage; //获取当前页的记录集合 List<Emp> lsemp=empBiz.findPageAll(page,pagesize); pb.setPage(page); pb.setPagesize(pagesize); pb.setMaxpage(maxpage); pb.setPagelist(lsemp); //将pb分页对象输出到页面 JSONUtil.printJsonString(response,pb); return null; } @Override @Action(value = "findDepList_Emp") public String findDepList() { HttpServletResponse response= ServletActionContext.getResponse(); List<Dep> lsdep=empBiz.findAllDep(); JSONUtil.printJsonString(response,lsdep); return null; } @Override @Action(value = "findWelfareList_Emp") public String findWelfareList() { HttpServletResponse response= ServletActionContext.getResponse(); List<Welfare> lswf=empBiz.findAllWelfare(); JSONUtil.printJsonString(response,lswf); return null; } } |
9.5.修改applicationContext.xml文件,加入注解支持和注解扫描器,扫描注解的组件包。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <context:annotation-config></context:annotation-config> <context:component-scan base-package="com.dao"/> <context:component-scan base-package="com.biz"/> <context:component-scan base-package="com.action"/> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/epdb"/> <property name="username" value="root"/> <property name="password" value="java"/> </bean> <!-- 注入Hibernate的session工厂 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.connection.autocommit">true</prop> <prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/epdb</prop> <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop> </props> </property> <property name="mappingLocations"> <list> <value>classpath:com/entity/Dep.hbm.xml</value> <value>classpath:com/entity/Emp.hbm.xml</value> <value>classpath:com/entity/Welfare.hbm.xml</value> </list> </property> </bean> <!-- 注入hibernate的事务管理器 --> <bean id="txmanager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 注入事务注解支持 --> <tx:annotation-driven transaction-manager="txmanager"/> </beans> |
9.6.修改web.xml文件,配置spring的启动。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app> |
9.7.复制emp.html与后端交互
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>员工管理</title> <script src="js/jquery-1.9.1.js"></script> <script> $(function(){ /*************获取部门的下拉列表**************/ $.getJSON('findDepList_Emp.action?t='+new Date().getTime(),function(lsdep){ console.log(lsdep); for(var i=0;i<lsdep.length;i++){ var dep=lsdep[i]; $("#depid").append("<option value='"+dep.depid+"'>"+dep.depname+"</option>") } }); /*******************************************/ /*********获取福利列表,为复选框赋值******************/ $.getJSON('findWelfareList_Emp.action?t='+new Date(),function(lswf){ console.log(lswf); for(var i=0;i<lswf.length;i++){ var wf=lswf[i]; $("#wf").append("<input type='checkbox' value='"+wf.wid+"' name='emp.widsarray' >"+wf.wname+""); } }); /***************************************************/ //调用显示员工列表的方法 findAll(); }); /*****************显示员工信息的方法*************/ var page=1;//当前页数 var pagesize=5;//每页记录数 var maxpage=1;//总页数 function findAll(page,pagesize) { // alert('findAll---page--->'+page); $.getJSON('findPageAll_Emp.action?page='+page+'&pagesize='+pagesize+'&t='+new Date().getTime(),function(pb){ console.log(pb); page=pb.page; pagesize=pb.pagesize; maxpage=pb.maxpage; var lsemp=pb.pagelist;//获取员工的列表数组 var tabhead="<table width='770' border='1' align='center' cellpadding='1' cellspacing='1'>" +"<tr align='center' bgcolor='#FFFF99'>" +"<td width='63'>编号</td>" +"<td width='121'>姓名</td>" +"<td width='92'>密码</td>" +"<td width='66'>性别</td>" +"<td width='95'>部门</td>" +"<td width='176'>福利</td>" +"<td width='119'>操作</td>" +"</tr>"; var trrow=''; for(var i=0;i<lsemp.length;i++){ var emp=lsemp[i]; trrow+="<tr align='center'>" +"<td>"+emp.eid+"</td>" +"<td>"+emp.ename+"</td>" +"<td>"+emp.passwd+"</td>" +"<td>"+emp.sex+"</td>" +"<td>"+emp.depByDepid.depname+"</td>" +"<td>"+emp.wnamearray+"</td>" +"<td><input type='button' name='btdel' id='btdel' value='删除' οnclick='dodel("+emp.eid+")'>" +"<input type='button' name='btedit' id='btedit' value='编辑' οnclick='dofindById("+emp.eid+")'></td>" +"</tr>"; } var endtable=tabhead+trrow+"</table>"; $("#tt").html(endtable); /**分页条的控制*/ $("#page").val(page); $("#pagesize").val(pagesize); $("#pagelable").html(page+"/"+maxpage+"页"); }); } /*********************************************/ /********分页按钮的控制*********************/ $(function(){ //首页的按钮事件 $("#btfirst").click(function(){ page=1; findAll(page,pagesize);//刷新列表 }); //上页按钮事件 $("#btup").click(function(){ page=page-1; if(page<1){ page=1; } findAll(page,pagesize);//刷新列表 }); //下页的按钮事件 $("#btnext").click(function(){ page=page+1; //alert(page); if(page>maxpage){ page=maxpage; } findAll(page,pagesize);//刷新列表 }); $("#btlast").click(function(){ page=maxpage; findAll(page,pagesize);//刷新列表 }); //改变每页记录数的控制 $("#btpagesize").click(function(){ //获取改变后的每页记录数 var psize=$("#pagesize").val(); if(isNaN(psize)){//判断文本框输入的是不是数字 alert('请输入正确的数字!'); $("#pagesize").val(pagesize); return; } pagesize=parseInt(psize); findAll(page,pagesize);//刷新列表 }); //改变页数的事件处理 $("#btpage").click(function(){ //获取要跳转的页数 var cpage=$("#page").val(); if(isNaN(cpage)){ alert("请输入正确的数字!"); $("#page").val(page); return; } page=parseInt(cpage); findAll(page,pagesize);//刷新列表 }); }); /*****************************************/ /***********删除*************/ function dodel(id){ //alert(id); $.get('delById_Emp.action?eid='+id,function (code) { if(code=='1'){ alert('删除成功!'); findAll();//刷新列表 }else{ alert('删除失败!'); } }); } /****************************/ /*******根据员工编号查询员工信息***********************/ function dofindById(id){ //alert(id); //先清除原来复选框的选中状态 $(":input[name='emp.widsarray']:checkbox").each(function () { console.log("先执行清除计划.......") $(this).attr("checked",false); }); $.getJSON('findById_Emp.action?eid='+id,function(oldemp){ console.log('在进行赋值计划......'); //将返回的员工对象设置到表单元素 $("#eid").val(oldemp.eid);//获取要修改的员工编号 $("#ename").val(oldemp.ename); $("#passwd").val(oldemp.passwd); $(":radio[value='"+oldemp.sex+"']").prop("checked",true); $("#depid").val(oldemp.depByDepid.depid); $("#mypic").attr("src","uppic/"+oldemp.photo); /********给复选框设置选中的值***********************/ //从旧的员工对象中获取福利编号数组 var wids=oldemp.widsarray; /***************************************************/ $(":checkbox[name='emp.widsarray']").each(function(){ for(var i=0;i<wids.length;i++){ var wid=wids[i]; console.log("原来员工的福利编号wid-->"+wid); console.log("所有复选框的值$(this).val()---->"+$(this).val()) if(parseInt(wid)== $(this).val()){ $(this).prop("checked",true);//选中 } } }); /*****************************************/ }); } /***************************************************/ /********更新事件*****************************/ $(function(){ //点击更新按钮的事件 $("#btupdate").click(function(){ //获取form表单的数据,并封装为FormData对象 var form1=$("#form1"); var formData=new FormData(form1)[0]; $.ajax({ type:'POST', url:'update_Emp.action', data:formData, async: false,/*设置为同步提交*/ cache: false,/*不需要缓冲处理*/ contentType: false,/*带有文件上传的内容*/ processData: false, success : function(code) { if(code=='1'){ alert('更新成功!'); findAll();//刷新列表 }else{ alert('更新失败!'); } } }); }); }); /*********************************************/ </script> </head> <body> <p align="center">员工列表</p> <hr width="800"> <div id="tt" style="font-size: 12px"> </div> <table width="770" border="1" align="center" cellpadding="1" cellspacing="1"> <tr align="center" bgcolor="#FFFF99"> <td><input type="button" name="btfirst" id="btfirst" value="首页"></td> <td><input type="button" name="btup" id="btup" value="上页"></td> <td><input type="button" name="btnext" id="btnext" value="下页"></td> <td><input type="button" name="btlast" id="btlast" value="末页"></td> <td>每页 <label for="pagesize"></label> <input name="pagesize" type="text" id="pagesize" size="2"> 条记录 <input type="button" name="btpagesize" id="btpagesize" value="确定"></td> <td>跳转到第 <label for="page"></label> <input name="page" type="text" id="page" size="2"> 页 <input type="button" name="btpage" id="btpage" value="确定"></td> <td><span id="pagelable">1/1页</span></td> </tr> </table> <hr width="800"> <form id="form1" action="save_Emp.action" method="post" enctype="multipart/form-data" name="form1"> <table width="550" border="0" align="center" cellpadding="0" cellspacing="10" style=" border: solid; border-width: 1px; border-color: aqua; "> <tr> <td colspan="3" align="center">员工管理</td> </tr> <tr> <td width="113">姓名:</td> <td width="260"> <input type="text" name="emp.ename" id="ename"> <input type="hidden" name="emp.eid" id="eid"> </td> <td width="137" rowspan="5"><img id="mypic" src="uppic/default.jpg" width="100" height="144"></td> </tr> <tr> <td>密码:</td> <td><input type="password" name="emp.passwd" id="passwd"></td> </tr> <tr> <td>性别:</td> <td><input name="emp.sex" type="radio" id="sex0" value="男" checked> 男 <input type="radio" name="emp.sex" id="sex1" value="女"> 女 </td> </tr> <tr> <td>部门:</td> <td> <select name="emp.depByDepid.depid" id="depid"> </select></td> </tr> <tr> <td>浏览照片:</td> <td> <input type="file" name="emp.pic" id="pic"></td> </tr> <tr> <td>福利:</td> <td colspan="2"><span id="wf"> </span></td> </tr> <tr> <td colspan="3" align="center"><input type="submit" name="button" id="button" value="提交"> <!--<input type="button" id="btupdate" name="btupdate" value="更新">--> <input type="reset" name="button2" id="button2" value="重置"></td> </tr> </table> </form> <p> </p> </body> </html> |
正在上传…重新上传取消