上篇文章写了Hibernate简单查询的几个步骤,现在把SSH和spring结合做一个整合。首先还是导入jar包和配置文件。
项目启动会先去找web.xml配置文件,所以先来看web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>ssh</display-name> //项目名,自动生成,防止重复,最好改为自己项目的名字
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>//欢迎页面
</welcome-file-list>
<!-- Spring MVC 分发器 DispatcherServlet -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name> //分发器
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-context.xml</param-value> //要去的下一个配置文件
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern> //发送请求后缀
</servlet-mapping>
<!-- 配置spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 设置Spring容器加载所有的配置文件的路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-context.xml,classpath:spring-hibernate.xml</param-value>
//然后要加载的配置文件 (classpath=src)
</context-param>
<!-- 解决Post提交中文乱码 -->
<filter>
<filter-name>encoding</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>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
之前Hibernate需要自己开启事务和提交事务,现在和spring结合使用,spring会自动开启事务和提交事务,所以看spring的配置文件
<!-- druid配置数据源 1.相当于configuration -->
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据库驱动 -->
<property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
<!-- 数据库连接路径 -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
<!-- 数据库连接帐号 -->
<property name="username" value="${jdbc_username}" />
<!-- 数据库连接密码 -->
<property name="password" value="${jdbc_password}" />
//上面这些根据EL表达式取的值都是通过数据源配置文件取来的,用来连接数据库
<!-- 配置hibernate session工厂 2.相当于构建session工厂 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments}</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext
</prop>
</props>
</property>
<!-- 自动扫描注解方式配置的hibernate类文件,扫描反向生成表的映射实体类 -->
<property name="packagesToScan">
<list>
<!-- 修改的地方 ↓↓ -->
<value>com.jk.model</value> //存放实体类的包,根据自己的包修改
</list>
</property>
</bean>
<!-- 配置事务管理器 -->
<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 拦截器方式配置事物——事务通知,事务的传播特性 隔离性 一致性 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="chaxun*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="reg*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="saveOrUpdate*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="del*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="*" propagation="REQUIRED" read-only="true" rollback-for="Exception" />
</tx:attributes>
</tx:advice>
最后面这几行是根据Service层(写拦截在哪一层的标签在后面,我写的是service层)写的方法名拦截,提交,遇见异常回滚,最后一个name只有一个*,代表拦截除上面外的所有方法,但是有一个 read-only=“true” ,意思是只读,不进行提交操作,如果上面没有自己起方法名的习惯,可以再加。
<!-- 整合完spring 我们一般将事务控制在service层 -->
<aop:config>
<!-- 第一个*代表所有的返回值类型;第二个*代表所有的实现类;第三个*代表类所有方法;最后一个..代表所有的参数 -->
<aop:pointcut expression="(execution(* com.jk.service.*.*.*(..)))" id="transactionPointcut"/>
<!-- 通知 -->
<aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointcut"/>
</aop:config>
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
driverClassName=oracle.jdbc.OracleDriver
jdbc_url=jdbc:oracle:thin:@localhost:1521:orcl
jdbc_username=system
jdbc_password=123
//刚才提到的数据源配置文件,这里更改自己要连接的数据库的数据和账号密码
有了spring帮助自己开启事务和提交事务之后,dao层的代码量就减少了很多,不过多了几个注解,接下来写一个简单的查询
前台发送请求页面:
<a href="<%=basePath%>/dog/select.do">查询</a>
然后发送到Controller层:
@Controller//注明是Controller层
@RequestMapping("dog")//给类起名
public class DogController {
@Autowired //按类型注入,spring帮助我们实例化对象
private DogService ds; //相当于实例化service实现类的对象,可以直接调用service的方法
//查询
@RequestMapping("select")//给方法起名
public ModelAndView select(){
List<DogModel> list = ds.select(); //查询出来的存到集合,所以用集合接收
ModelAndView mv=new ModelAndView(); //向前台转发的类
mv.addObject("list",list);
//把接收到的list存给mv,前面是key,前台根据key来接受值,类似于map
mv.setViewName("WEB-INF/view/selectpage"); //要去的页面
return mv;
}
}
然后是service层的接口:
public interface DogService {
List<DogModel> select();
Service实现类实现了这个接口,所以要重写接口的方法
@Service //注明是Service层
public class DogServiceImpl implements DogService {
@Autowired //spring注入
private DogDao dd; //实例化dao层
@Override
public List<DogModel> select() {
String hql=" from DogModel ";
//hql语句,类似于sql语句,不过这里是实体类的名字和属性名,将hql语句作为参数传给dao层
List<DogModel> list = dd.select(hql);
return list;
}
}
dao层和service层一样,一个接口,一个实现类,所以直接写dao层代码:
@Autowired //和之前一样,不过这里是实例化sessionFactory工厂对象
private SessionFactory sf;
@Override
public List<DogModel> select(String hql) {
Session session = sf.openSession();
List<DogModel> list = session.createQuery(hql).list();
return list;
}
之前hibernate生成表是通过配置文件,略微有些麻烦,现在是用注解的方法,看一下实体类代码:
@Entity //声明实体类
@Table(name="dog") //想要创建的数据库表名
public class DogModel {
@Id //声明是ID,是主键
@GeneratedValue(strategy=GenerationType.AUTO) //主键生成策略
private Integer did;
private String dname;