目的:
在上次的基础下,对ssh框架进行简化。
1、本文提纲:本文通过一个新闻管理系统的实例来简化ssh框架的代码编写,功能包括查询数据库中所有新闻信息,删除某条新闻信息。
2、本项目的搭建环境:Windows 8-64位,Eclipse(开发工具),jdk1.8.0_91,Tomcat 8.0 ,mysql数据库。
第一步:在eclipse里创建web项目 (news)
第二步:导入本次项目要使用到的jar包
第三步:在配置文件web.xml配置一个struts2的过滤器和spring监听器。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> 3 <display-name>news</display-name> 4 <welcome-file-list> 5 <welcome-file>default.jsp</welcome-file> 6 </welcome-file-list> 7 8 <!-- struts2过滤器 --> 9 <filter> 10 <filter-name>struts2</filter-name> 11 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 12 </filter> 13 <filter-mapping> 14 <filter-name>struts2</filter-name> 15 <url-pattern>/*</url-pattern> 16 </filter-mapping>、 17 18 <!-- spring监听器 --> 19 <context-param> 20 <param-name>contextConfigLocation</param-name> 21 <param-value>classpath:applicationContext.xml</param-value> 22 </context-param> 23 <listener> 24 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 25 </listener> 26 </web-app>
第四步: 在src下建包 ,配置文件
第五步: 创建实体类
News(实体类):
1 package news.entity; 2 3 import java.util.Date; 4 5 /* 6 * 跟数据库表一致,作为一个java对象 7 * 1个对象代表的是数据库表中的一行记录 8 * 1个属性代表的是表中的一个字段 9 */ 10 public class News { 11 private Integer id; //新闻编号 12 private String title; //新闻标题 13 private String content; //新闻内容 14 private Date begintime; //发布时间 15 private String username; //作者 16 17 //创建get()和set()方法 18 public Integer getId() { 19 return id; 20 } 21 public void setId(Integer id) { 22 this.id = id; 23 } 24 public String getTitle() { 25 return title; 26 } 27 public void setTitle(String title) { 28 this.title = title; 29 } 30 public String getContent() { 31 return content; 32 } 33 public void setContent(String content) { 34 this.content = content; 35 } 36 public Date getBegintime() { 37 return begintime; 38 } 39 public void setBegintime(Date begintime) { 40 this.begintime = begintime; 41 } 42 public String getUsername() { 43 return username; 44 } 45 public void setUsername(String username) { 46 this.username = username; 47 } 48 49 }
News.hbm.xml(映射文件):
<?xml version="1.0" encoding="UTF-8"?> <hibernate-mapping xmlns="http://www.hibernate.org/xsd/hibernate-mapping"> <class name="news.entity.News" table="news"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="title" type="string" length="50" column="title" not-null="true"></property> <property name="content" type="text" length="50000" column="content" not-null="true"></property> <property name="begintime" type="date" column="begintime" not-null="true"></property> <property name="username" type="string" length="20" column="username" not-null="true"></property> </class> </hibernate-mapping>
NewsService(接口类):
package news_service; import java.util.List; public interface NewsService { //查询 显示所有数据 public List showAllNews(); //删除单个数据 public String deleteNews(Integer id); }
NewsServiceImpl(实现类):注:有背景颜色的代码,就是注解,它代替里applicationContext.xml文件里的 托管实例bean标签删除。详细见下图,
package news_service; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import news_dao.NewsDao;
@Service
@Scope("prototype")
public class NewsServiceImpl implements NewsService {
@Autowired
private NewsDao nd;
public List showAllNews() { List allnews =nd.showAllNews(); return allnews; } public String deleteNews(Integer id) { String deleteOK =nd.deleteNews(id); return deleteOK; } }
下图:applicationContext.xml 的代码都不需要了 将用注解代替,@Service 代替bean , @Autowired 代替 property
NewsDao(接口类):
package news.dao; import java.util.List; public interface NewsDao { public List showAllNews(); //显示首页所有数据(查询使用的。PS:本例没用到) public String findNews(); public String deleteSingleNews(Integer id); }
NewsDaoImpl(实现类):注;有背景颜色的代码,就是注解 ,在Dao里 @Repository代替bean
package news.dao; import java.util.List; import javax.annotation.Resource; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Repository; import news.entity.News; @Repository @Scope("prototype") public class NewsDaoImpl implements NewsDao { @Autowired private SessionFactory sf; @Override public List<News> showAllNews() { Session session =sf.openSession(); session.getTransaction().begin(); Query query =session.createQuery("from News"); session.getTransaction().commit(); List<News> allNews =query.getResultList(); return allNews; } @Override public String deleteNews(Integer id) {
Session session = sf.openSession();
//Session session = sf.getCurrentSession();//它会与事务关联,并且在事务后自动关闭
Query query = session.createQuery("from News where id=:myid");
//query.setParameter(0, id);
query.setParameter("myid", id);
List<News> deleteList = query.getResultList();
//如果搜索出来是1条,就删除,如果是0条就不管了
if ( deleteList.size()==1 ) {
News news = deleteList.get(0);
System.out.println("删除对象:"+news.getTitle()+ " Id:"+news.getId());
session.getTransaction().begin();
session.delete(news);
session.getTransaction().commit();
session.close();
//sessionFactory关闭策略
//1.坚持使用数据库连接池(例如C3P0)
//2.sessionFactory就不关闭,而使用hibernate事务自动关闭功能
// 说明:sf.openSession(); 必须关闭
// sf.openSession(); 改为:sf.getCurrentSession();
//getCurrentSession创建的线程会在事务提交或者事务回滚后自动关闭
//sf.close();
return "deleteOK";
} }
编写NewsAction(action类)。
package news.action; 2 3 import java.util.List; 4 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.context.annotation.Scope; 7 import org.springframework.stereotype.Controller; 8 9 import com.opensymphony.xwork2.ActionSupport; 10 11 import news.entity.News; 12 import news.service.NewsService; 13 14 //创建NewsAction(action类)继承ActionSupport接口 15 //使用@Controller类注解自动注入,并且为非单例 16 @Controller 17 @Scope("prototype") 18 public class NewsAction extends ActionSupport { 19 20 //获取从客户端传递过来的值 21 private Integer id; 22 23 //strtus自动的赋值 24 public void setId(Integer id) { 25 this.id = id; 26 } 27 28 //使用spring内置注解@Autowired自动注入实例 29 @Autowired 30 private NewsService ns; 31 32 private List<News> allNewList; 33 34 public List<News> getAllNewList() { 35 return allNewList; 36 } 37 38 public void setAllNewList(List<News> allNewList) { 39 this.allNewList = allNewList; 40 } 41 42 //查询出所有数据 43 public String showAllNews(){ 44 45 allNewList=ns.showAllNews(); 46 47 return "success"; 48 } 49 55 56 //删除某条数据 57 public String deleteSingleNews(){ 58 59 System.out.println("客户端传过来的id值是:"+id); 60 61 String returnValue=ns.deleteSingleNews(id); 62 63 return returnValue; 64 } 65 }
struts.xml:
<?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 <!-- 上面的头,注意版本,从样例里复制过来 showcase.war\WEB-INF\src\java\struts.xml --> 6 7 <struts> 8 <!-- 告知Struts2运行时使用Spring来创建对象 --> 9 <constant name="struts.objectFactory" value="spring"></constant> 10 <!-- 第1步:先定义一个包 --> 11 <package name="mynews" extends="struts-default"> 12 <!-- 第2步:定义一个action,配置跳转信息 name 类似于Servlet 注:这里使用了通配符来指定调用的方法--> 13 <action name="NewsAction_*" class="newsAction" method="{1}"> 14 <!-- 跳转是forward/WEB-INF/是防止jsp不经过action就可以访问--> 15 <!-- result接收返回的字符串,然后做对应的事情 --> 16 <result name="success">/WEB-INF/jsp/NewsIndex.jsp</result> 17 <!-- 删除后通过type="redirectAction"这个类型重新跳转到NewsAction_showAllNews.action刷新页面 --> 18 <result name="deleteOK" type="redirectAction">NewsAction_showAllNews.action</result> 19 </action> 20 </package> 21 </struts>
简化后的 applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 8 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 9 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd 10 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd 11 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> 12 13 <!-- spring注解自动注入 --> 14 <context:component-scan base-package="news"></context:component-scan> 15 16 <!-- 引入外部属性文件 --> 17 <context:property-placeholder location="classpath:jdbc.properties" /> 18 <!-- 添加sessionFactory bane ,注意,该类是Spring提供的 --> 19 <bean id="sessionFactory" 20 class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" scope="prototype"> 21 <!-- 注入连接池,包含了数据库用户名,密码等等信息 --> 22 <property name="dataSource" ref="myDataSource" /> 23 24 <!-- 配置Hibernate的其他的属性 --> 25 <property name="hibernateProperties"> 26 <props> 27 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> 28 <prop key="hibernate.show_sql">true</prop> 29 <prop key="hibernate.format_sql">true</prop> 30 <prop key="hibernate.connection.autocommit">false</prop> 31 <!-- 开机自动生成表 --> 32 <prop key="hibernate.hbm2ddl.auto">update</prop> 33 </props> 34 </property> 35 <property name="mappingResources"> 36 <list> 37 <!-- 引用News.hbm.xml映射文件 --> 38 <value>news/entity/News.hbm.xml</value> 39 </list> 40 </property> 41 </bean> 42 43 <!-- 添加c3p0数据库连接池 bean --> 44 <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 45 <!-- 数据库连接配置 --> 46 <property name="driverClass" value="${jdbc.driver}" /> 47 <property name="jdbcUrl" value="${jdbc.url}" /> 48 <property name="user" value="${jdbc.user}" /> 49 <property name="password" value="${jdbc.password}" /> 50 <!-- 每300秒检查所有连接池中的空闲连接 --> 51 <property name="idleConnectionTestPeriod" value="300"></property> 52 <!-- 最大空闲时间,900秒内未使用则连接被丢弃。若为0则永不丢弃 --> 53 <property name="maxIdleTime" value="900"></property> 54 <!-- 最大连接数 --> 55 <property name="maxPoolSize" value="2"></property> 56 </bean> 57 </beans>
总结:通过对本例项目搭建到功能的编写,使用注解的方式简化了ssh框架代码编写,对实例和类直接用注解注入。