CRM系统
学完了Hibernate增删改查和Spring的基础url对应控制器处理方法,就可以写一个增删改查的应用了。
一个基础的CRM也是所有语言进行Web开发的必写项目,所谓零一生增删改查,增删改查生万物也。
第一个项目还是比较原始的,一个列表,然后一个按钮用于添加数据,之后是展示每一行数据,然后每一行数据有删除和修改两个按钮。像极了我当年Django写出来的第一个原型。
在开始项目之前进行简单的设计还是很重要的,尤其是数据库表格的设计,决定了之后很多代码方面的具体工作。
这个项目的关键是将Spring MVC与Hibernate结合起来。
创建MySQL数据库和使用Hibernate测试连接
这次我们创建一个新的用户和新的Customer表来存放数据。
CREATE USER 'springstudent'@'localhost' IDENTIFIED BY 'springstudent';
GRANT ALL PRIVILEGES ON * . * TO 'springstudent'@'localhost';
用户名和密码都叫做"springstudent",然后创建数据表:
然后创建一个叫做web_customer_tracker
的数据库,并创建一个customer表,填充一些初始数据:
CREATE DATABASE IF NOT EXISTS `web_customer_tracker` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `web_customer_tracker`;
DROP TABLE IF EXISTS `customer`;
CREATE TABLE `customer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) DEFAULT NULL,
`last_name` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
LOCK TABLES `customer` WRITE;
INSERT INTO `customer` VALUES
(1,'David','Adams','david@luv2code.com'),
(2,'John','Doe','john@luv2code.com'),
(3,'Ajay','Rao','ajay@luv2code.com'),
(4,'Mary','Public','mary@luv2code.com'),
(5,'Maxwell','Dixon','max@luv2code.com');
然后修改Hibernate的配置文件,尝试查询一下数据库:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import java.util.List;
public class TestCustomer {
public static void main(String[] args) {
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").addAnnotatedClass(Customer.class).buildSessionFactory();
Session session = factory.getCurrentSession();
try {
session.beginTransaction();
List<Customer> customerList = session.createQuery("from Customer customer").getResultList();
for (Customer c : customerList) {
System.out.println(c);
}
session.getTransaction().commit();
} catch (Exception ex) {
ex.printStackTrace();
}finally {
session.close();
factory.close();
}
}
}
这样就配置好了数据库,之后的重点是配置项目环境。
配置Spring
由于之前是单独使用Hibernate操作数据库,现在需要用一个Web项目,把Spring,Hibernate,JSTL等相关依赖包全部放到WEB-INF/lib/目录中,并将这些包加入到项目库中。
这一次除了Hibernate的lib/required目录下的jar包之外,我们还需要用到c3pO连接池,所以把optional/c3pO下的三个jar包也加入项目库中。
还需要将Hibernate的配置文件放到src目录之下,将spring的配置文件放到WEB-INF目录之下。
由于Spring MVC是Web框架,用于将所有的功能组装在一起成为一个应用,Hibernate只是Web应用的一个功能实现的组件,所以通过Spring来装配所有的组件是最先要做的事情。
先来配置相关的Bean,还记得默认的Bean是单例模式吗,这里我们就需要靠Spring来组装我们的Web应用所需的各个部件。
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<!--数据库连接的设置-->
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false&serverTimezone=UTC"/>
<property name="user" value="springstudent"/>
<property name="password" value="springstudent"/>
<!--C3PO的设置-->
<property name="minPoolSize" value="5"/>
<property name="maxPoolSize" value="20"/>
<property name="maxIdleTime" value="30000"/>
</bean>
使用过JDBC连接池就会知道,这里将连接池对象制作成了一个Bean,并使用属性注入将各种配置都注入了进去,这样通过获得Bean就可以得到一个连接池的单例,从其中可以获得数据库连接。
之后来配置Hibernate的sessionFactory:
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!--依赖注入连接池Bean-->
<property name="dataSource" ref="myDataSource"/>
<!--扫描Entity Class所在的类-->
<property name="packagesToScan" value="cc.conyli.entity"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
这里没有直接装配Hibernate的Bean,而是使用了Spring自己的一个实现,注入了连接池的Bean,设置好扫描Entity Class的包,以及SQL方言和是否显示SQL语句,这个Bean就是之后操作数据库的Bean了。
笔者在这里真的感动到流泪,之前学IOC和依赖注入的时候,只是大概知道了怎么用,在学Hibernate的时候就一直在想,如何将Hibernate装配起来,Hibernate是如何使用连接池的。看到这里真的感叹Spring框架之精妙:其中使用到的连接池,Hibernate对象,都是各自类的一个实例,而整个装配过程,又像是一张更大的蓝图,将各个部件装配成一台可以工作的机器。这大概是第一次感受到计算机科技的精妙之处,奉劝看到这里的各位,不是家里有矿,千万不要去学什么财务等商科,还是技术挣钱,虽然门槛高,但是不努力又怎么挣更多的钱呢。
还有很多Hibernate的配置,目前这里足够使用了。
还记得Hibernate要频繁的开启事务和提交事务吗,Spring也为这个准备了一个Bean:
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
这个管理事务的Bean与上边很相似,都采用了Spring自己的类,然后注入了刚才配置的sessionFactory这个Bean。
之后需要配置使Spring可以使用@Transactional
注解功能:
<tx:annotation-driven transaction-manager="myTransactionManager" />
注意,这处配置必须在beans标签内有如下这行:
xmlns:tx="http://www.springframework.org/schema/tx"
除此之外,还需要配置在之前最基础的一些项目,比如扫描Bean的目录,视图名称解析器等:
<context:component-scan base-package="cc.conyli"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
配置好了以后,我们需要编写简单的控制器和页面,来看看项目是否能够运行:
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(value = "/customer")
public class CustomerController {
@RequestMapping(value = "/list")
public String test(Model model) {
return "list-customers";
}
}
再编写一个简单的页面,放在WEB-INF/view/下:
<%--list-customers.jsp--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试主页</title>
</head>
<body>
<p>Spring装配Bean正常,项目初步启动成功</p>
<p>明天继续。。。。。</p>
</body>
</html>
之后启动项目到http://localhost:8080/customer/list
,正常启动啦,Spring装配Bean的功能实在是妙不可言啊。