开发SSH项目过程中的一个小结

开发SSH项目过程中的一个小结

SSH项目中需要注意的一些问题
这里的SSH指的是Spring + SpringMVC + Hibernate

  1. 项目结构
    【强制】对于Service和Dao类,基于 SOA 的理念,暴露出来的服务一定是接口,内部的实现类用Impl的后缀与接口区分。
    【参考】各层命名规约:
    A) Servi…

SSH项目中需要注意的一些问题

这里的SSH指的是Spring + SpringMVC + Hibernate

1. 项目结构

【强制】对于Service和Dao类,基于 SOA 的理念,暴露出来的服务一定是接口,内部的实现类用Impl的后缀与接口区分。
【参考】各层命名规约:
A) Service/DAO 层方法命名规约
1) 获取单个对象的方法用 get 做前缀。
2) 获取多个对象的方法用 list 做前缀,复数形式结尾如: listObjects。
3) 获取统计值的方法用 count 做前缀。
4) 插入的方法用 save/insert 做前缀。
5) 删除的方法用 remove/delete 做前缀。
6) 修改的方法用 update 做前缀。
B) 领域模型命名规约
1) 数据对象: xxxDO, xxx 即为数据表名。
2) 数据传输对象: xxxDTO, xxx 为业务领域相关的名称。
3) 展示对象: xxxVO, xxx 一般为网页名称。
4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。

2. Spring 与 Hibernate 进行整合

  • 将spring以及springmvc的配置文件统一由DispatherServlet进行加载,分为spring-web.xml、spring-service.xml、spring-dao.xml
web.xml中的部分配置:

<servlet>
<servlet-name>Lambda-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Lambda-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

在这里插入图片描述

  • 由spring的配置文件进行管理hibernate的相关配置

未整合之前的配置:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/database?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true&amp;autoReconnectForPools=true&amp;useSSL=false</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">update</property>

<mapping resource="hbm/Test.xml"/>
</session-factory>
</hibernate-configuration>

整合后的配置:

1.spring的配置(在spring-dao.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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<context:component-scan base-package="cn.example.dao"/>

<!-- 引入外部的部署文件 -->
<context:property-placeholder location="classpath:property/jdbc.properties"/>
<!-- 配置连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 配置hibernate的相关属性 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 引入hibernate配置文件 -->
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>

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

2.hibernate的配置(在hibernate.cfg.xml里):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">update</property>

<mapping class="cn.example.entity.Test"/>
</session-factory>
</hibernate-configuration>

3.jdbc.properties

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/lambda?useUnicode=false&characterEncoding=utf8&autoReconnect=true&autoReconnectForPools=true&useSSL=false
jdbc.username=root
jdbc.password=root

注:这里&不要换成&amp;,否则将报错

3. Service 和 Dao 类

1.spring如何使用注解自动装载

// 首先在spring的配置文件中:
// 扫描组件:例如service包下的所有类
<context:component-scan base-package="cn.example.service"/>

// 然后在service或dao的实现类上加上注解@Service或@Repository
// serviceImpl 加 @Service
// daoImpl 加 @Repository
// 然后在需要使用的地方进行自动装载
@Autowired
private TestService testService;
// 注意写的是接口,不是实现类

关于使用注解进行注入还有 @Component 和 @Controller
@Component是任何类都可以使用
@Controller是针对controller使用的

2.SessionFactory的自动装载以及@Transactional注解的使用

为了实现SessionFactory的自动装载,需要在spring的配置文件中写:
<!-- 引入外部的部署文件 -->
<context:property-placeholder location="classpath:property/jdbc.properties"/>
<!-- 配置连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 配置hibernate的相关属性 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 引入hibernate配置文件 -->
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
之后便可以在类中使用:
@Autowired
private SessionFactory sessionFactory;


@Transactional注解的使用,也需要在spring的配置文件中进行配置:
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

注:在使用SessionFactory.getCurrentSession()获取session的时候,需要加上@Transactional开启事务,否则会报异常 Could not obtain transaction-synchronized Session for current thread
参考:https://www.cnblogs.com/zeng1994/p/7778145.html

4. HibernateDaoSupport与HibernateTemplate

引用:
spring3.1里已经不提供hibernatedaosupport,hibernateTemplete了,只能用hibernate原生的session
来自:
https://blog.csdn.net/Yiyuan_chen/article/details/74091797?utm_source=blogxgwz5

5. 简单Dao 查询的实现

@Repository
public class TestDaoImpl implements TestDao {

@Autowired
private SessionFactory sessionFactory;

@Transactional
@Override
public Blog getBlogById(long blogId) {
String hql = "from Test t where t.a = ?0";
Query query = sessionFactory.getCurrentSession().createQuery(hql);
List<Blog> list = query.setParameter(0, 1L).list();
return list.get(0);
}
}

值得注意的是:String hql = "from Test t where t.a = ?0";

  • Test是实体类,不需要写全路径,只需要写类名就可以
  • ?0 是现在hql中提供参数的方式,dao查询的实现步骤是:
    先通过sessionFactory的getCurrentSession()获取到session,
    然后使用session的createQuery()方法,
    并向该方法传入hql语句,
    这就可以得到一个Query类型的query,
    使用query的setParameter进行参数设置,问号后面的数字代表参数的位置,
    如果上面我改成t.a = ?2,那么我就要写成:query.setParameter(2, 1L)
    最后使用list()方法获取到一个list集合
  • 记得加上@Transactional注解
    参考:https://blog.csdn.net/m0_37922841/article/details/80560127

6. 其他的一些问题

  1. Ambiguous mapping. Cannot map ‘xxxController’ method
    这篇文章说的是controller中的@RequestMapping的值不能是相同的字符串,否则会报如标题一样的错误

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×