通过SSH搭建企业开发环境

一直没有写博客的习惯,但是这几年走过来,却发现了总没留下什么,所以是时候对过去做些记录了,一是为了缅怀过去,二是对技术重述,三是留作借鉴。

按照现在很多企业的开发都是基于springboot、或者一些微服务都用到了springcloud、dubbo,为什么会想着回归到以前的技术呢。我觉得,对于现在接触软件行业的人来说,对于工具的使用越来越容易了,但是对于技术的理解确越来越困难。由于太多的技术不断发展,而且发展的很快,不断的改进、升华、包装,这些都是经验与思想的结晶,对我们来说,只是看到了结果,确很难去看穿这些过程,那么如何然我们去理解这些由于时代变迁与技术革新留下的成果物,是不是只能从头再来,这个真不得而知,每个人接触新事物、学习能力、思维模式等等方面都有很大差异,没有什么方式能够弥补时代欠下我们的经验,那么只有一步一个脚印,按自己的方式走下去了....

记得最开始进入这个行业,也是4年前了,那个时候用到的就是spring、springmvc、hibernate orm、jsp来完成企业项目的开发,那么今天,我也将试着按照这样的脚步走一遍。之后也会涉及到springboot、springcloud、mybatis、redis、zookeeper、vue等这些前后端目前都比较流行的技术进行下去,档案更多的是完成效果,那么具体为什么、如何理解等比较深层次的东西,只有在以后的日子慢慢理解,从源码的角度与各种渠道进行解析,这是一个比较漫长的过程,包括现在,都是学习与记录的过程。

现在同样先构建一个maven的空项目,首先通过spring-bom配置spring环境依赖的各种jar的最佳版本,

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>3.2.16.RELEASE</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

然后无非就是spring的一些包,比如bean、core、context、web、mvc,档案现在和hibernate配合,需要 shring的orm和hibernate-croe,当然还有一些数据库驱动、数据库连接池、json处理、测试、日志以为web开发相关的包,如servlet-api等。

一般mvc项目都会遵循这样的结构:

3cf322f53ac5d1c183457a264eb34d4f122.jpg

其中core中主要会有一些扩展,这个可能只能在之后来慢慢补充了,由于这是一个简单的应用,各个所有业务会划分成多模块存在与一个项目中,直接回存在一些依赖于调用。

可以看下实体是怎么处理的:

@Data
@Entity
@Table(name = "USER")
@JsonIgnoreProperties({"password"})
public class User implements Domain {

    @Id
    @Column(name = "USER_ID",length = 36)
    @GeneratedValue(generator = "system-id")
    @GenericGenerator(name = "system-id", strategy = "uuid")
    private String userId;

    @JoinColumn(name = "AGENCY_ID")
    @ManyToOne(fetch = FetchType.LAZY)
    private Agency agency;

    @Column(name = "LOGIN_NAME",length = 56)
    private String loginName;

    @Column(name = "USER_CAPTION",length = 16)
    private String userCaption;

    @Column(name = "PASSWORD",length = 24)
    private String password;

    @Column(name = "BIRTHDAY",length = 24)
    private String birthday;

    @Column(name = "TELEPHONE",length = 16)
    private String telephone;

    @Column(name = "EMAIL",length = 36)
    private String email;

    @Column(name = "QQ",length = 12)
    private String qq;

    @Column(name = "WEIXIN",length = 56)
    private String weixin;

    @Column(name = "DESCRIPTION",columnDefinition="varchar(256)")
    private String description;
}

因为使用的是hibernate orm,所以不会有hibernate的配置,这里只用jpa的相关注解即可。同时由java 实体生成数据库表,所以对每个属性都加上了注解。而doa与service层则相对简单

public interface UserDao extends Dao<User,String> {

}
@Repository
public class UserDaoImpl extends HibernateDao<User,String> implements UserDao {
    @Override
    protected Class<User> getModelClazz() {
        return User.class;
    }
}
public interface UserService extends BaseService {

    List<User> getUsers();

    User getUser(String id);

    User saveUser(User user);

    void removeUser(String id);
}
@Transactional
@Service
public class UserServiceImpl extends BaseServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public List<User> getUsers() {
        return userDao.getAll();
    }

    @Override
    public User getUser(String id) {
        return userDao.get(id);
    }

    @Override
    public User saveUser(User user) {
        return userDao.save(user);
    }

    @Override
    public void removeUser(String id) {
        userDao.remove(id);
    }
}

其实可以看到,这些接口都有一定的普遍性,如果有多个功能模块,基本都是一些重复复制的工作,所以完全可以在完成一定阶段后,通过模板来生成这些代码,网上有非常多的反向工程工具,同时通过一些模板框架如freemaker、volacity来实现,那么只用保证代码的统一结构后,就大大减少了工作量。

关于web层其实就是一些congtroller了,没什么特别的:

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @ResponseBody
    @RequestMapping("/getUsers")
    public List<User> getUsers(){
        return userService.getUsers();
    }

    @ResponseBody
    @RequestMapping("/getUser")
    public User getUser(@RequestParam String id){
        return userService.getUser(id);
    }

    @ResponseBody
    @RequestMapping("/saveUser")
    public User saveUser(User user){
        return userService.saveUser(user);
    }

    @ResponseBody
    @RequestMapping("removeUser")
    public void removeUser(@RequestParam String id){
        userService.removeUser(id);
    }
}

web资源都在webapp中,如下:

b38171cd772f376b24a67f0aacf9ca682d9.jpg

将css、js以及 静态资源文件放在resources中,configs主要放各种扩展配置,pages就是页面了。

首先可以看下web.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<!--
    metadata-complete = true,则servlet相关的注解
-->
<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_3_1.xsd"  version="3.1"  metadata-complete="true">

    <description>
        springmvc hibernate app
    </description>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/configs/spring/applicationContext.xml</param-value>
    </context-param>

    <!--  字符集过滤  -->
    <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>

    <!--Open Session in View 解决lazy时加载问题-->
    <filter>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/configs/spring/applicationContext-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>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

这里主要的配置就是spring的上下文已经web上下文。其次就是编码过滤以及hibernate Open Session in View问题,关键监听ContextLoaderListener,这个是springweb环境的重要处理环节。

最后要说的就是一些配置了,比如spring相关的,主要有两个,一个是spring上下文applicationContext.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"
       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">

    <!-- 扫描指定包下的spring注解,完成bean的注册 -->
    <context:component-scan base-package="com.sucl.shms">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 加载属性文件 -->
    <context:property-placeholder location="classpath*:configs/config-*.properties"/>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="${jdbc.initialSize}"></property>
        <!-- 连接池最大数量 -->
        <property name="maxActive" value="${jdbc.maxActive}"></property>
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="${jdbc.maxIdle}"></property>
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="${jdbc.minIdle}"></property>
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="${jdbc.maxWait}"></property>
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />
        <property name="validationQuery" value="${jdbc.validationQuery}" />
        <property name="testWhileIdle" value="${jdbc.testWhileIdle}" />
        <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
        <property name="testOnReturn" value="${jdbc.testOnReturn}" />
        <property name="maxOpenPreparedStatements" value="${jdbc.maxOpenPreparedStatements}" />
        <!-- 打开removeAbandoned功能 -->
        <property name="removeAbandoned" value="${jdbc.removeAbandoned}" />
        <!-- 1800秒,也就是30分钟 -->
        <property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" />
        <!-- 关闭abanded连接时输出错误日志 -->
        <property name="logAbandoned" value="${jdbc.logAbandoned}" />
    </bean>

    <!--配置session工厂-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.sucl.shms.*.entity" />
        <property name="hibernateProperties">
            <props>
                <!--<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> &lt;!&ndash; SessionFactory.getCurrentSession() 需要指定jta | thread | managed | custom &ndash;&gt;-->
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> <!--hibernate根据实体自动生成数据库表-->
                <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>     <!--在控制台显示执行的数据哭操作语句(格式)-->
            </props>
        </property>
    </bean>

    <!-- 事物管理器配置  -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>

这里主要是添加包的扫描配置、属性文件加载、数据源、orm依赖已经事务。

而web环境由于内容较少,配置也相对简单:

<?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: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.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.sucl.shms.*.web"/>

    <mvc:annotation-driven/>

    <mvc:default-servlet-handler/>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

其余的无非就是一些页面资源了,这个与我们所选择的前端框架有关系,目前没有做前后分离,但是从Controller可以看出,用了@ResponseBody,因此我们返回的已经是数据流,而非页面了。

其实到这里大的方面也差不多了,那么还有一些点:

  • 数据库操作的抽象
  • 代码模板生成器的设计
  • 页面与数据的控制
  • 异常处理
  • 前端界面的设计
  • 具体细节的说明
  • .....

还有很多都会在下一周全部完成。最后会形成一个比较完善可以直接使用的管理系统,当然只会包含系统模块了。

代码:https://github.com/suspring/springmvc-hibernate-ms 将会继续更新。

处理代码生成器没有生成,其他功能都有个轮廓,前端采用layui实现,没有做过多的包装。

代码生成器可以参考mybatis-plus的,代码已经引入,需要从源码分析如何从数据库中取出相关的表、字段、类型等信息。

其余功能目前不再完善,下一步将看看spring4.x通过注解方式构建web环境,。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值