共计 9901 个字符,预计需要花费 25 分钟才能阅读完成。
说明:全注解配置 Spring3+SpringMVC+Hibernate4,Eclipse 含 jar,导入直接使用。数据库使用 Oracle,可以按照配置文件 dataSource 的内容建用户。访问 http://localhost/eap 将调用 FileManagerControl 的 getFileServerList 方法,从数据库表中读取数据并返回到 index.jsp 上。献给那些和我一样为环境配置纠结的初学者。
我没有使用 maven,直接使用 Eclipse 创建动态 Web 项目,jar 包复制在了 lib 下。这样做导致我马上概述的项目既依赖 Eclipse 和其项目结构,又依赖我复制在 lib 下的那些 jar 包版本。
jar 包下载地址:http://pan.baidu.com/s/1hqfH3pU
但是我现在还是会以这种形式阐述,因为对于接触新事物而言的人,我觉得首先需要的是热情,这样才能有勇气面对尝试过程中的失败。热情从哪里来?热情从在事物获得的每一点成就感而来,现在按照以下步骤,我们来获得一点成就感,然后再讨论技术层面的事情(我记得以前刚学 Java 的时候,如果没有 Eclipse 那神奇的自动补全,我一定坚持不下来,早就转行了。不切实际的艰苦只能浪费时间和磨练心性,它在某些时候不一定是必要的,它应当成为一个可选项而不是一条必经路)。
环境 Spring3.2.0,Hibernate4.1.6,Eclipse 3.7,Tomcat5.5,JDK1.6.45,Oracle10g(不要对我的环境版本搭配和数据库使用抱有异议,我本地恰好就是 JDK1.6.45 的,恰好 Tomcat 就是 5.5 的,恰好 Oracle 在新建项目前就已经安装好了)。
这是一个 SSH 项目,所以我假设各位了解或听过一些 J2EE 的术语,我们将跃过“从入门到精通”系列的引言,直接让你来看看我到底是怎么做的,还有那中间的波折。
首先,我在 Eclipse 下建立了一个动态 Web 项目,这时候除了目录结构外,唯一有点内容的就是 WEB-INF 下的 web.xml 了,大话不多说,如果你已经把我贴了下载地址的 jar 包复制到了 lib 下,那么在 web.xml 里复制如下内容。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<!– <param-value>/WEB-INF/applicationContext.xml</param-value> –>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Very Nice! 现在除了自动的 xml 头,<welcome-file-list>,就是以上 spring 配置信息了。这里配置了 Spring 和 SpringMVC,<listener> 和 contextConfigLocation 是对 spring 的配置,前者是 spring 的监听类,后者是 spring 配置文件的路径,这里一目了然,毫无疑问。
然后从 servlet 开始,都是 SpringMVC 的配置,这里先后配置了类似全局 Filter 的类 DispatcherServlet 的路径,然后是 SpringMVC 的配置文件,我们将在那儿启用我们的全注解功能。servlet-mapping 就真的像 Filter 一样,配置了需要拦截的请求路径,最后是一些字符集配置,在领略到成就感之前不叙述了,免得打击士气。
和刚才配置的信息一致的,我们在 src 下建立 applicationContext.xml(这名字好长!虽然可以换掉它,但我在项目里一看见这名字就知道它是干什么的了,所以不换了)和 servlet-mvc.xml。
首先配置 applicationContext:
<?xml version=”1.0″ encoding=”UTF-8″ ?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:context=”http://www.springframework.org/schema/context”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd”>
<bean id=”dataSource”
class=”org.springframework.jdbc.datasource.DriverManagerDataSource”>
<property name=”driverClassName” value=”oracle.jdbc.driver.OracleDriver” />
<property name=”url” value=”jdbc:oracle:thin:@localhost:1521:ORCL” />
<property name=”username” value=”fm” />
<property name=”password” value=”admin” />
</bean>
<!– 配置 Hibernate –>
<bean id=”sessionFactory”
class=”org.springframework.orm.hibernate4.LocalSessionFactoryBean”>
<property name=”dataSource” ref=”dataSource”></property>
<property name=”packagesToScan” >
<list>
<value></value>
</list>
</property>
<property name=”hibernateProperties”>
<props>
<prop key=”dialect”>org.hibernate.dialect.Oracle10gDialect</prop>
<prop key=”hibernate.current_session_context_class”>thread</prop>
<prop key=”hibernate.show_sql”>true</prop>
<prop key=”hibernate.format_sql”>true</prop>
<prop key=”hibernate.hbm2ddl.auto”>update</prop>
</props>
</property>
</bean>
<context:annotation-config />
<context:component-scan base-package=”com.eap.filemanager.service” />
<context:component-scan base-package=”com.eap.pub.user.service.impl” />
<context:component-scan base-package=”com.eap.pub.user.dao” />
</beans>
全部的内容,各位直接复制呗。这里 xml 头包括了注解的路径,然后配置 DataSource,配置 Hibernate,最后一段就是启用注解了,说是 <context:annotation-config /> 在这个版本已经不需要写了,反正我项目现在正在跑着,先复制上来再说。最后路径扫描,我是定义到包的,因为通配符好像没起作用,老是报错,我就把所有需要扫描的包都写上去了。
接下来是 SpringMVC,配置 SpringMVC 之前,其实各位已经可以开始和数据库进行交互操作了,可以编写 DAO 的代码了,我再说一遍,DAO 是 Data Access Object,这一层该写什么不该写什么,这名字清清楚楚了已经!
servlet-mvc.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” xmlns:p=”http://www.springframework.org/schema/p”
xmlns:context=”http://www.springframework.org/schema/context”
xmlns:util=”http://www.springframework.org/schema/util” xmlns:mvc=”http://www.springframework.org/schema/mvc”
xsi:schemaLocation=”
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd”>
<!– ViewResolver –>
<bean
class=”org.springframework.web.servlet.view.InternalResourceViewResolver”>
<property name=”viewClass”
value=”org.springframework.web.servlet.view.JstlView” />
<property name=”prefix” value=”/WEB-INF/jsp/” />
<property name=”suffix” value=”.jsp” />
</bean>
<!– 使用默认的注解映射 –>
<mvc:annotation-driven />
<!– 自动扫描 controller 包中的控制器 –>
<context:component-scan base-package=”com.eap.filemanager.cmd” />
</beans>
xml 头,ViewResolver,然后启用注解,然后扫描。
这其中,第二部分的意思就是,SpringMVC 里有个跳转类型叫做 ModelAndView,它 setView 之后,就会自动跑到 view 名字 + 后缀的文件上去,比如 setView(“index”),那么在这个配置文件下,就会自动跳转到 index.jsp 上,而且是 WEB-INF/jsp 下的 index.jsp 上,WEB-INF 下的 jsp 无法直接通过地址栏访问,所以这种控制可以让容器对资源访问权限进行管理。
大功告成,最困难的配置文件就这么搞定了,我可是花了好多时间在网上搜了来着,现在你们已经拥有了基石般的配置文件信息,你可以在上面测试通配符啦等你觉得方便的任何内容。
好了,看配置文件上的包也能知道,我的 DAO 是这么写的。
非常奇怪,使用 @Controller 和 @Resource 必须得实现接口,得这么写:
接口:
public interface IUserDao {
public List query(String sql);
public List queryByName(String name);
}
DAO 代码:
@Repository
public class UserDao implements IUserDao{
Session session;
@Autowired
UserDao(SessionFactory sessionFactory){
session = sessionFactory.getCurrentSession();
session.beginTransaction();
}
public List query(String sql) {
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
return query.list();
}
public List queryByName(String username){
String sql = “select * from pub_user where username=?”;
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
query.setString(0, username);
return query.list();
}
}
这里我可是试了好多种方法,由于我喜欢直接写 sql 语句,以充分利用关系数据库的“关系”特性(毕竟关系型数据库不是和对象无缝贴合的,要发挥其最大优势应该从数据表之间的关系入手。有异议就提,最好论据充分,我需要证据不是结论,有了证据我也可以自己分析分析了,说不定我还知道点别的,能得出更有用的结论),所以我在这里使用了 SQLQuery,否则你可以直接 session.createQuery(hql)。但是,这里有一个问题,我继承 HibernateDAOSupport 反而会获取不到 session 或别的什么东西。
我在这儿顺便附上 JavaBean 的,完全注解。
@Entity
@Table(name=”pub_user”)
public class User {
@Id
@Column(name = “id”, unique = true, nullable = false)
String id;
@Column(name=”username”)
String username;
@Column(name=”passwd”)
String passwd;
@Column(name=”user_ip”)
String userIp;
//getter 和 setter… 自己用 Eclipse 生成吧,我省略掉了
}
DAO 这样写,那么我的 Service 就可以这么写了。一样的先接口,再 @Controller
public interface UserService {
public List getUsers();
}
@Service
public class UserServiceImpl implements UserService{
@Resource
IUserDao dao;
public List getUsers(){
List list = dao.query(“select * from pub_user”);
return list;
}
}
你看哦,我这里 @Resource,必须写在接口定义的变量上面,然后 Spring 会自己去找谁实现了它并且还是 @Resource 的。关于具体命名管理,还有一些内容就不说了,这个在我们这么点代码的例子中根本就遇不到的。记得我说的,万一有两个 DAO 都实现了这个接口,那该怎么办呢,这就是命名管理要做的事情,自己去看吧(说不定你还没看完这篇博客就放弃 Spring 了,那么写上去真是多此一举……什么?你不会放弃?你不会放弃我也不写啊,我又没用到)。
接下来就是 @Controller 了,这里不需要接口了,嘿嘿(我就说,UserDao 都是 UserDao<T>,里面的 save 方法都不用定义具体类型了,干嘛每个模块还要用不同的 DAO?既然大家都用一个 DAO,干嘛还要依赖接口编程?我直接泛型 <T> 继承了一个 HibernateDAO 后,Spring 还不许我这么访问 DAO。不用拿概念忽悠我,我知道内聚和耦合在什么样的规模下会展现出自身特性的怎样的优缺点,但注解依赖接口编程的强制性让我搭建环境的过程中走了很多弯路。好吧,也有可能明明有办法不用建接口,只是我不知道罢了)。
@Controller
public class FileManagerControl{
@Autowired
UserService service;// 其实我这不是 User 的 Controller,反正 Controller 过程都一样,大家看看调用过程就行了哦
@RequestMapping({“/”})
public ModelAndView welcome(){
ModelAndView mv = new ModelAndView();
mv.addObject(“users”, service.getUsers());
mv.setViewName(“index”);
return mv;
}
}
这样,http://localhost:8080/[projectName]/,对应 @RequestMapping({“/”})(如果里面是 ”/index.do” 那么连接就是 http://localhost:8080/[projectName]/index.do 了)就能访问 ModelAndView 设置的 index.jsp 了。这时候 jsp 上,${users} 将会调用 User 的 toString() 方法,很可惜,我试了 ${users.username},报错,不知道怎么搞。
完整项目下载 :
—————————————— 分割线 ——————————————
FTP 地址:ftp://ftp1.linuxidc.com
用户名:ftp1.linuxidc.com
密码:www.linuxidc.com
在 2015 年 LinuxIDC.com\8 月 \Spring3+SpingMVC+Hibernate4 全注解环境配置 \
下载方法见 http://www.linuxidc.com/Linux/2013-10/91140.htm
—————————————— 分割线 ——————————————
Spring-3.2.4 + Quartz-2.2.0 集成实例 http://www.linuxidc.com/Linux/2013-10/91524.htm
使用 Spring 进行单元测试 http://www.linuxidc.com/Linux/2013-09/89913.htm
运用 Spring 注解实现 Netty 服务器端 UDP 应用程序 http://www.linuxidc.com/Linux/2013-09/89780.htm
Spring 3.x 企业应用开发实战 PDF 完整高清扫描版 + 源代码 http://www.linuxidc.com/Linux/2013-10/91357.htm
Spring 容器加载完成后执行某个方法 http://www.linuxidc.com/Linux/2015-08/121757.htm
Hibernate 学习入门教程 http://www.linuxidc.com/Linux/2015-08/121498.htm
在 Hibernate 中开启日志 http://www.linuxidc.com/Linux/2015-07/120499.htm
Hibernate+JUnit 测试实体类生成数据库表 http://www.linuxidc.com/Linux/2015-07/120161.htm
Hibernate 整体理解 http://www.linuxidc.com/Linux/2014-07/104405.htm
Hibernate 的映射机制 http://www.linuxidc.com/Linux/2014-12/110265.htm
Hibernate 的详细介绍 :请点这里
Hibernate 的下载地址 :请点这里
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2015-08/122175.htm