在Java的项目开发中,数据库是一个很重要的模块,Hibernate作为一个非常成熟的框架,在Java的开发中十分流行。本篇博客将会来介绍在SpringMVC项目中如何使用Hibernate,使用的数据库是MySQL。建议在开发之前首先在电脑上安装好MySQL数据库、MySQLWorkbench可视化工具。本文的示例代码上传至
https://github.com/chenyufeng1991/StartSpringMVC 。
(1)首先通过MySQLWorkbench创建一个连接,连接到本地的MySQL数据库。一般最简单的配置可以如下图所示:
(2)连接完成后,使用MySQLWorkbench创建一个数据库,也称为Schemas,这里创建一个TestDB数据库。然后在TestDB中创建一张EMPLOYEE表。现在表中的设计如下图:
(3)由于本身涉及的依赖比较多,我这里贴上pom.xml中的所有依赖,其中直接和Hibernate有关的有3个依赖。大家可以根据实际的需求进行删减,或和自己的pon.xml进行对比。
<!-- POM properties: -->
<properties>
<spring.version>4.2.0.RELEASE</spring.version>
<jsf.version>2.2.13</jsf.version>
<aspectj.version>1.7.4</aspectj.version>
<hibernate.version>4.3.5.Final</hibernate.version>
<jetty.port>8090</jetty.port>
<tomcat.port>8070</tomcat.port>
<joda-time.version>2.9</joda-time.version>
</properties>
<!-- Dependencies: -->
<dependencies>
<!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<!-- Project Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>0.11.6</version>
<scope>provided</scope>
</dependency>
<!-- Spring Framework-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Faces -->
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-faces</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<!-- JSF -->
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>${jsf.version}</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>${jsf.version}</version>
</dependency>
<!-- Facelets -->
<dependency>
<groupId>com.sun.facelets</groupId>
<artifactId>jsf-facelets</artifactId>
<version>1.1.14</version>
</dependency>
<!-- Commons -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- Javassist -->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
<!-- Javax annotations -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- Alibaba FastJSON-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.21</version>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.4</version>
</dependency>
<!-- Swagger-mvc -->
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.6</version>
</dependency>
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<!-- Others -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
<!-- Mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
<!-- Hibernate4 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- for JPA, use hibernate-entitymanager instead of hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- jboss -->
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.1.3.GA</version>
</dependency>
<!-- Joda-Time -->
<!--<dependency>-->
<!--<groupId>joda-time</groupId>-->
<!--<artifactId>joda-time</artifactId>-->
<!--<version>${joda-time.version}</version>-->
<!--</dependency>-->
<!-- To map JodaTime with database type -->
<dependency>
<groupId>org.jadira.usertype</groupId>
<artifactId>usertype.core</artifactId>
<version>5.0.0.GA</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
</dependency>
</dependencies>
(4)需要增加一个配置文件,作为对Hibernate的主要配置,我这里新建一个hibernate.properties,里面的实现如下:
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/TestDB
jdbc.username = root
jdbc.password = 123456
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.show_sql = true
hibernate.format_sql = true
(5)添加一个配置类,我这里创建“HibernateConfiguration”,该类读取了上面的配置文件,并做了创建数据源等操作:
@Configuration
@EnableTransactionManagement
@ComponentScan({"com.chenyufeng.springmvc"})
@PropertySource(value = {"classpath:hibernate.properties"})
public class HibernateConfiguration {
@Autowired
Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[]{"com.chenyufeng.springmvc.model"});
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
return properties;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
}
(6)对于数据库的使用,最重要的有几部分:dao、model、service。其中dao部分是直接和数据库交互的部分;model基本和表对应,代表数据库中的模型;service进行了数据库有关的业务逻辑。
model->Empoyee的主要实现:
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Size(min = 3, max = 50)
@Column(name = "NAME", nullable = false)
private String name;
@NotNull
@Column(name = "JOINING_DATE", nullable = false)
private String joiningDate;
@NotNull
@Digits(integer = 8, fraction = 2)
@Column(name = "SALARY", nullable = false)
private BigDecimal salary;
@NotEmpty
@Column(name = "SSN", unique = true, nullable = false)
private String ssn;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJoiningDate() {
return joiningDate;
}
public void setJoiningDate(String joiningDate) {
this.joiningDate = joiningDate;
}
public BigDecimal getSalary() {
return salary;
}
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((ssn == null) ? 0 : ssn.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Employee))
return false;
Employee other = (Employee) obj;
if (id != other.id)
return false;
if (ssn == null) {
if (other.ssn != null)
return false;
} else if (!ssn.equals(other.ssn))
return false;
return true;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", joiningDate="
+ joiningDate + ", salary=" + salary + ", ssn=" + ssn + "]";
}
}
dao->EmployeeDaoImpl的主要实现:
@Repository("employeeDao")
public class EmployeeDaoImpl extends AbstractDao<Integer, Employee> implements EmployeeDao {
@Override
public Employee findById(int id) {
return getByKey(id);
}
@Override
public void saveEmployee(Employee employee) {
persist(employee);
}
@Override
public void deleteEmployeeBySsn(String ssn) {
Query query = getSession().createSQLQuery("delete from Employee where ssn = :ssn");
query.setString("ssn", ssn);
query.executeUpdate();
}
@SuppressWarnings("unchecked")
public List<Employee> findAllEmployees() {
Criteria criteria = createEntityCriteria();
return (List<Employee>) criteria.list();
}
public Employee findEmployeeBySsn(String ssn) {
Criteria criteria = createEntityCriteria();
criteria.add(Restrictions.eq("ssn", ssn));
return (Employee) criteria.uniqueResult();
}
}
service->EmployeeServiceImpl的主要实现:
@Service("employeeService")
@Transactional
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeDao employeeDao;
@Override
public Employee findById(int id) {
return employeeDao.findById(id);
}
@Override
public void saveEmployee(Employee employee) {
employeeDao.saveEmployee(employee);
}
@Override
public void updateEmployee(Employee employee) {
Employee entity = employeeDao.findById(employee.getId());
if (entity != null) {
entity.setName(employee.getName());
entity.setJoiningDate(employee.getJoiningDate());
entity.setSalary(employee.getSalary());
entity.setSsn(employee.getSsn());
}
}
@Override
public void deleteEmployeeBySsn(String ssn) {
employeeDao.deleteEmployeeBySsn(ssn);
}
@Override
public List<Employee> findAllEmployees() {
return employeeDao.findAllEmployees();
}
@Override
public Employee findEmployeeBySsn(String ssn) {
return employeeDao.findEmployeeBySsn(ssn);
}
@Override
public boolean isEmployeeSsnUnique(Integer id, String ssn) {
Employee employee = findEmployeeBySsn(ssn);
return (employee == null || ((id != null) && (employee.getId() == id)));
}
}
(7)在Controller层进行方法的调用,并实现接口。
查询所有Employee:
@ResponseBody
@RequestMapping(value = {"/list"}, method = RequestMethod.GET)
public List<Employee> listEmployees() {
List<Employee> employees = service.findAllEmployees();
return employees;
}
创建Employee:
@ResponseBody
@RequestMapping(value = {"/new"}, method = RequestMethod.POST)
public String saveEmployee(
@ApiParam(value = "用户名", required = true) @RequestParam String name,
@ApiParam(value = "日期", required = true) @RequestParam String joiningDate,
@ApiParam(value = "薪水", required = true) @RequestParam BigDecimal salary,
@ApiParam(value = "ssn", required = true) @RequestParam String ssn
) {
Employee employee = new Employee();
employee.setName(name);
employee.setJoiningDate(joiningDate);
employee.setSalary(salary);
employee.setSsn(ssn);
service.saveEmployee(employee);
return "success";
}
更新Employee:
@ResponseBody
@RequestMapping(value = {"/edit-{ssn}-employee"}, method = RequestMethod.POST)
public String updateEmployee(@PathVariable String ssn,
@ApiParam(value = "用户名", required = true) @RequestParam String name,
@ApiParam(value = "日期", required = true) @RequestParam String joiningDate,
@ApiParam(value = "薪水", required = true) @RequestParam BigDecimal salary
) {
Employee employee = service.findEmployeeBySsn(ssn);
employee.setName(name);
employee.setJoiningDate(joiningDate);
employee.setSalary(salary);
service.updateEmployee(employee);
return "success update";
}
删除Employee:
/**
* 通过以下的方式可以获得路径中传递的参数,在swagger中也能使用
* @param ssn
* @return
*/
@ResponseBody
@RequestMapping(value = {"/delete-{ssn}-employee"}, method = RequestMethod.GET)
public String deleteEmployee(@PathVariable String ssn) {
service.deleteEmployeeBySsn(ssn);
return "success delete";
}
(8)在Swagger页面中调用接口,来进行测试:
查询所有Employee:
新建Employee:
修改Employee:
删除Employee:
(9)在IDEA右侧的Database页面中,可以测试和数据库的连接,以及进行简单的查看:
打开详情,也可以进行简单的配置,并测试连通性: