五天的课程让我看了八天多,倒不是跟不上,中间好几天追了追大创的论文,周末还给学校开发了艺术生登分的系统,真是忙的。。。不过也顺脚复习了Servlet和JSP的知识,我觉得挺好,再者说还管了两顿盒饭呢,对饭的诱惑力是永远抵抗不了的,哈哈!
SSH实战项目中没遇到太多的坑,因为之前开发学校的系统的时候也有经验,这次学习主要是学习了jstl、Spring整合Hibernate事务的配置、Struts2.5.x的坑、在Hibernate中使用原生SQL语句进行查询、BaseDAO抽取、多对多关系转换成两个一对多、多条件查询、数据字典额也算个知识点吧,哈哈!
jstl
${requestScope.requestAttribute} - request域,如果是request可以直接使用attribute的key来表示
${sessionScope.sessionAttribute} - session域
<c:forEach var="var" items="list">
<c:out value="${var.xxx}"> / ${var.xxx}
</c:forEach>
<c:if test="codition">条件成立时执行</if>
Spring整合Hibernate配置事务管理
<!-- 创建事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
需要在Service前或Dao前加上@Transactional的注解才可以,否则报错。即需要声明此类中的全部方法需要进行事务管理
Struts 2.5.x的坑已经解决,看之前的随笔
在Hibernate中使用原生SQL语句进行复杂查询操作
如果此时SQL为select count(*) num,customer from t_customer,HQL是无法执行的,使用session.cresteSQLQuery(sql).addEntity(Entity.class);但是上面的sql语句count(*)、customer没有对应的实体类,如果单独为这两个变量创建一个实体类显然不是一个好的解决办法,但是怎样方便的将返回的数据使用呢?
上述语句使用list方法可以返回一个list集合,但是list内部的数据是以数组的形式存放的。这不友好。观察num customer实际上他们与其对应的数据是一个KV的形式,可以将返回的数据转换成一个Map。
在Hibernate中使用setResultTransformer方法将返回数据转换成一个HashMap:
q.setResultTransformer(Transformers.aliasToBean(HashMap.class));
BaseDao抽取
DAO层是简单说就是对DB进行操作,CURD操作几乎是每个DAO类具备的功能,如果每个类都需要写一遍CURD代码重复太多影响点儿效率,主要是编程的人烦啊。那么这个时候抽取出一个BaseDao来解决这一问题。
BaseDao一般是实现CURD操作,那么首先声明一个BaseDao,在类中写明add、update、delete等方法,代码如下:
package tech.youngs.Dao; import java.util.List; public interface BaseDao<T> { void add(T object); void delete(T object); void update(T object); T findOne(int id); List<T> findAll(); }
<T>就是泛型,有T就说明肯定会根据T的值来对相应的实体进行操作,肯定会用到反射。添加修改删除都好说,直接用T,但是根据id查询对象,返回的值可是相应的实体类的类型,java是不认识T是什么东东的。所以说,在实例化DAO的实现对象的时候要根据T来知道到底是哪个实体类型。
package tech.youngs.Dao; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import org.springframework.orm.hibernate5.support.HibernateDaoSupport; @SuppressWarnings("all") public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> { private Class tClass; public BaseDaoImpl() { //获取当前对象的字节码 Class clazz = this.getClass(); //根据字节码对象获取超类的泛型参数值 Type type = clazz.getGenericSuperclass(); ParameterizedType ptype = (ParameterizedType) type; //获取到了泛型参数 Type[] typearr = ptype.getActualTypeArguments(); //Type转换成class对象 tClass = (Class) typearr[0]; } @Override public void add(T object) { // TODO Auto-generated method stub this.getHibernateTemplate().save(object); } @Override public void delete(T object) { // TODO Auto-generated method stub this.getHibernateTemplate().delete(object); } @Override public void update(T object) { // TODO Auto-generated method stub this.getHibernateTemplate().update(object); } @Override public T findOne(int id) { // TODO Auto-generated method stub return (T) this.getHibernateTemplate().get(tClass, id); } @Override public List<T> findAll() { // TODO Auto-generated method stub return (List<T>) this.getHibernateTemplate().find("form "+tClass.getSimpleName()); } }
在使用的时候在DAO中继承BaseDao,在实现类中继承BaseDaoImpl就可以省很多时间了。
多对多关系转换成一对多关系
在hibernate中,多对多关系是通过第三张表来维护的,局限性很大,因为只有两个外键。在开发中一般不使用多对多,大多将多对多关系转换成两个一对多的关系。
多条件查询
三种方式,拼接HQL和使用hibernate模板是一个类型。
第三种方式是使用离线对象,离线对象有个好处是不用拼接语句,使用restriction.eq这些各种方法,但是还是需要判断有没有值。其实逻辑性的话还是HQL给我的感觉最好,但就对不起还麻烦实现hibernateTemplate了。
数据词典
数据词典实际上就是对用户输入的值做一个限制,比如说添加一个客户,在选择客户级别的时候就不能随便输入,比如是个VIP客户,写一个亮瞎你的钛合金狗眼的VIP客户。。。。会被经理打屁屁的,所以约定好客户级别都有哪些。
再补充一点
这次项目开发都是使用的配置文件,Spring中有注解的机制,我们不需要在配置文件中写哪些东西,直接使用@Controller @Service @Repository这些注解会很方便的。
再再补充一点
高工资和多技术是成正比的,不要嫌弃现在学的东西多,记不住,太杂。实际上每一个技术都是日后谈论薪资的筹码!