02 完善ssh搭建

项目快速搭建已在上一篇当中介绍(包含,c3p0、hibernate、spring文件)

在这篇当中,完善spring

下图是各层之间的联系




因为在实际开发中,不可能所有操作都是增删改查,可能有很复杂的操作,再复杂的操作都是由基本的操作组合成,所以一般都是面向业务编程,业务,就是在service层。service跟dao是两个层面,service力度比较粗,可以不断的去丰富和扩展,但是dao不变(因为我们一般先设计数据库表),BaseDao接口只有一个,而service可以有很多个接口(增加业务),所以:


首先编写BaseDao接口,为了一般性,包含一个泛型:


然后编写BaseDaoImpl抽象类实现BaseDao,其中sf依赖于hibernate:

/*
BaseDao接口的实现类
 */
public abstract class BaseDaoImpl<T> implements BaseDao<T> {
   private SessionFactory sf;//会话工厂,相当于连接池
    private Class<T> clazz;

    public void setSf(SessionFactory sf) {
        this.sf = sf;
    }

    public BaseDaoImpl(){
        //取得子类的泛型化超类
        ParameterizedType type= (ParameterizedType) this.getClass().getGenericSuperclass();
       //得到第一个实际参数
        clazz = (Class) type.getActualTypeArguments()[0];
    }
    public void saveEntity(T t) {
        sf.getCurrentSession().save(t);
    }

    public void updateEntity(T t) {
        sf.getCurrentSession().update(t);
    }

    public void saveOrUpdateEntity(T t) {
        sf.getCurrentSession().saveOrUpdate(t);
    }

    public void deleteEntity(T t) {
        sf.getCurrentSession().delete(t);
    }

    public T getEntity(Integer id) {
        return (T) sf.getCurrentSession().get(clazz,id);
    }
/*
按照HQL查询数据  Hibernate Query Language
 */
    public List<T> findByHQL(String hql, Object... objects) {
        Query query = sf.getCurrentSession().createQuery(hql);
        for (int i=0;i<objects.length;i++){
            query.setParameter(i,objects[i]);
        }
        return query.list();
    }
/*
按照HQL进行批量写操作
 */
    public void execHQL(String hql, Object... objects) {
        Query query = sf.getCurrentSession().createQuery(hql);
        for (int i=0;i<objects.length;i++){
            query.setParameter(i,objects[i]);
        }
        query.executeUpdate();
    }
}

注意!一个很常见的问题:如何得到超类的泛型化参数,比如如何传递User,在BaseDaoImpl得到传递过来的是User



需走构造函数:



目前基准类已经创建好,现在创建UserDaoImpl:


创建BaseService接口:



因为service跟dao打交道,所以在service中声明dao对象,调用dao实现方法就OK:

创建BaseServiceImpl抽象类:

/*
    serviceDao打交道,在service声明dao对象,调用dao实现方法。
 */
public abstract class BaseServiceImpl<T> implements BaseService<T> {
    private BaseDao<T> baseDao;

    public BaseDao<T> getBaseDao() {
        return baseDao;
    }

    public void saveEntity(T t) {
        baseDao.saveEntity(t);
    }


    public void updateEntity(T t) {
        baseDao.updateEntity(t);
    }

    public void saveOrUpdateEntity(T t) {
        baseDao.saveOrUpdateEntity(t);
    }

    public void setBaseDao(BaseDao<T> baseDao) {
        this.baseDao = baseDao;
    }

    public void deleteEntity(T t) {
        baseDao.deleteEntity(t);
    }

    public T getEntity(Integer id) {
        return baseDao.getEntity(id);
    }

    public List<T> findByHQL(String hql, Object... objects) {
        return baseDao.findByHQL(hql,objects);
    }

    public void execHQL(String hql, Object... objects) {
        baseDao.execHQL(hql,objects);
    }
}

创建UserService接口:


创建UserServiceImpl:


接下来配置到Spring里(一个bean依赖另外一个):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
   <!--指定外部文件的位置-->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="location" value="classpath:jdbc.properties"></property>
   </bean>
    <!--c3p0数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverclass}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="maxPoolSize" value="${c3p0.pool.size.max}"></property>
        <property name="minPoolSize" value="${c3p0.pool.size.min}"></property>
        <property name="initialPoolSize" value="${c3p0.pool.size.ini}"></property>
        <property name="acquireIncrement" value="${c3p0.pool.size.increment}"></property>

    </bean>
    <!--hibernate会话工厂类-->
    <bean id="sf" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
      <!--数据源属性-->
        <property name="dataSource" ref="dataSource"></property>
        <!--hibernate自身属性-->
        <property name="hibernateProperties">
            <props>
                <!--dialect方言-->
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            </props>
        </property>
        <!--映射文件位置-->
        <property name="mappingDirectoryLocations">
            <list>
                <value>classpath:com/chenway/eshop/model</value>
            </list>
        </property>
    </bean>
    <!--UserDao-->
    <bean id="userDao" class="com.chenway.eshop.dao.impl.UserDaoImpl">
        <property name="sf" ref="sf"></property>
    </bean>

    <!--userService-->
    <bean id="userService" class="com.chenway.eshop.service.impl.UserServiceImpl">
        <property name="baseDao" ref="userDao"></property>
    </bean>
</beans>

jdbc.properties:

jdbc.driverclass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eshop
jdbc.username=root
jdbc.password=123456

c3p0.pool.size.max=10
c3p0.pool.size.min=2
c3p0.pool.size.ini=3
c3p0.pool.size.increment=2

hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true


注意,还有一个事务问题:

1.transaction.
2.acid
atomic //原子性,不可分割.要么全成功,要么全失败
consistent //一致性,操作前,结束后,操作不能被破坏
isolate //隔离性,相互独立
durable //持久化性,

谈到mysql的隔离级别:

        来历由并发现象产生:

脏读 //读未提交,一个事务读取了另外一个事务改写还没有提交的数据,如果另外一个事务在稍后回滚
不可重复读 //读不回去,只要在两个同样查询的情况下发现了不一致,每次结果不一样
幻读 //读多了,在稍后同样条件查询情况下,被插入了

        怎么办?隔离级别
----------------
1.读未提交 read uncommitted
2.读已提交 read committed
4.可以重复读repeatable read

8.serializable 串行化


                        jvm:
----------------
runtime Data area.
heap //堆,共享
stack
native method stack
counter register
method area //共享,所有线程共享


heap:
//堆,年轻代(伊甸区 + 幸存一区 + 幸存二区) + 年老代

非堆 non-heap //method area.


在beans引入名字空间mvc、tx、sop、context:

<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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
">

添加mvc依赖:



<!--hibernate事务管理器-->
<bean id="txManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
    <property name="sessionFactory" ref="sf"></property>
</bean>

 

<!--事务通知-->
<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <!--save开头的所有方法都开启事务-->
        <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/>
        <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT"/>
        <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT"/>
        <tx:method name="exec*" propagation="REQUIRED" isolation="DEFAULT"/>

        <tx:method name="find*" propagation="REQUIRED" isolation="DEFAULT"/>
        <tx:method name="get*" propagation="REQUIRED" isolation="DEFAULT"/>

        <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/>

    </tx:attributes>
</tx:advice>

<!--配置spring扫描的包,自动管理需要的bean对象-->
<context:component-scan base-package="com.chenway.eshop.dao.impl,com.chenway.eshop.service.impl"></context:component-scan>
<!--aop配置-->
<aop:config>
    <!--切入点-->
    <aop:pointcut id="txPoint" expression="execution(* com.chenway.eshop.service.*Service.*(..))"></aop:pointcut>
    <!--切入点通知-->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"></aop:advisor>

</aop:config>

所以最终spring文件:

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
">

    <!--配置spring扫描的包,自动管理需要的bean对象-->
    <context:component-scan base-package="com.chenway.eshop.dao.impl,com.chenway.eshop.service.impl"></context:component-scan>
    <!--aop配置-->
    <aop:config>
        <!--切入点-->
        <aop:pointcut id="txPoint" expression="execution(* com.chenway.eshop.service.*Service.*(..))"></aop:pointcut>
        <!--切入点通知-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"></aop:advisor>

    </aop:config>

    <!--事务通知-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!--save开头的所有方法都开启事务-->
            <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="exec*" propagation="REQUIRED" isolation="DEFAULT"/>

            <tx:method name="find*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="get*" propagation="REQUIRED" isolation="DEFAULT"/>

            <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/>

        </tx:attributes>
    </tx:advice>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="location" value="classpath:jdbc.properties"></property>
   </bean>
    <!--c3p0数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverclass}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="maxPoolSize" value="${c3p0.pool.size.max}"></property>
        <property name="minPoolSize" value="${c3p0.pool.size.min}"></property>
        <property name="initialPoolSize" value="${c3p0.pool.size.ini}"></property>
        <property name="acquireIncrement" value="${c3p0.pool.size.increment}"></property>

    </bean>
    <!--hibernate会话工厂类-->
    <bean id="sf" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
      <!--数据源属性-->
        <property name="dataSource" ref="dataSource"></property>
        <!--hibernate自身属性-->
        <property name="hibernateProperties">
            <props>
                <!--dialect方言-->
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            </props>
        </property>
        <!--映射文件位置-->
        <property name="mappingDirectoryLocations">
            <list>
                <value>classpath:com/chenway/eshop/model</value>
            </list>
        </property>
    </bean>

    <!--hibernate事务管理器-->
    <bean id="txManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
        <property name="sessionFactory" ref="sf"></property>
    </bean>

</beans>



创建测试类,插入数据,没问题的话目前已经搭建好,接下来要搭建mvc:


Tomcat之所以能够对外提供服务,是因为里边有很多写好的servlet(服务器端程序,固定的API)。很多第三方框架,都会给出自己的servlet实现,所以如果我们要部署到tomcat去,就要使用它给的servlet,springmvc提供一个DispatcherServlet(分发请求),处理请求的时候,会交给HandlerMapping(处理映射),通过url来映射某个组件来处理它,这个组件就是controller,controller会返回ModelAndView,ModelAndView会返回给DispathcerServlet,还需进一步解析,所以交给ViewResolver,把逻辑名映射到真正的一个资源文件(通常为JSP)


在resources文件夹中创建webmvc.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
               http://www.springframework.org/schema/mvc
               http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
    <!-- 注解方法处理器适配器 -->
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/plain;charset=UTF-8</value>
                            <value>text/html;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
    </bean>

    <!-- 内部资源视图解析器(解析的是jsp的路径) -->
    <bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/jsps/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

接下来在web-inf/web.xml中配置:

 
 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--上下文配置参数,指定的是springbeans.xml文件位置-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:beans.xml</param-value>
    </context-param>
    <!--通过监听器方式在tomcat启动时,完成beans的初始化-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!--配置spring的分发器控制器-->
<servlet>
    <servlet-name>controller</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--初始化参数,确保web服务器启东时,初始化springmvc容器-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:webmvc.xml</param-value>
    </init-param>
</servlet>
    <servlet-mapping>
        <servlet-name>controller</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>


创建

/**
 *主页控制器
 */
@Controller
@RequestMapping(value = "/")
public class HomeController {

    public HomeController(){
        System.out.println("hello world");
    }

    /**
     *到主页
     */
    @RequestMapping(value = "home",method =RequestMethod.GET)
    public String toHome(){
        System.out.println("hello world!!");
        return  "index" ;
    }
}

猜你喜欢

转载自blog.csdn.net/a8330508/article/details/81054824
02