欢迎来到本教程的第二部分。 当您看到本文有多长时间时,请不要惊慌–我向您保证,这主要是简单的POJO和一些生成的代码。

在开始之前,我们需要更新我们的Maven依赖项,因为我们现在将使用Hibernate和Spring。 将以下依赖项添加到pom.xml中

<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>3.6.8.Final</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><!-- spring framework --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>3.1.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>3.1.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>3.1.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>3.1.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>3.1.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>3.1.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>3.1.0.RELEASE</version></dependency>

如果您是Maven的新手,您可能现在想知道-您怎么知道这些? 我在哪里可以买到? 好吧,只需转到http://mvnrepository.com/并输入您要搜索的啤酒。 您将获得有关Maven依赖项的完整代码。 如果您曾经尝试在不使用Maven的情况下自己组装Spring或Hibernate应用程序,那么您可能知道它是多么痛苦。 使用Maven,事情变得简单得多。

还要注意,我们包括了对MySQL连接器的依赖。 如果您决定使用其他数据库,请不要忘记更改它。

使用Hibernate,我们有2种选择如何将POJO变成实体。 我们要么使用XML并创建映射文件 ,要么将一些元信息放入我们的代码(java批注)中。 有些人对此感到恐惧,并认为这是与框架的结合。 的确,您在类路径中将需要javax.persistence批注,但我们不会实现接口或扩展框架类。 我们将只在代码中添加一些元信息,而POJO仍然只是带有一些额外信息的POJO。

现在,我们将POJO转换为实体。 我们将需要进行以下更改:

  • 为Hibernate添加默认的无参数构造函数
  • 为字段创建获取器和设置器
  • 添加equalshashCode方法。
  • 添加持久性注释。 请注意,我们还使用@Table批注来区分Java和SQL命名约定。
  • 添加ID字段。 这些将是我们关系数据库中的主键。

这是很多样板代码,因此让您的IDE帮您。 大多数现代IDE都会为您生成构造函数,getter,setter,equals和hashCode。

package org.timesheet.domain;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;@Entity
@Table(name = 'employee')
public class Employee {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)private Long id;private String name;private String department;public Employee() {}public Employee(String name, String department) {this.name = name;this.department = department;}public String getName() {return name;}public String getDepartment() {return department;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public void setName(String name) {this.name = name;}public void setDepartment(String department) {this.department = department;}@Overridepublic String toString() {return 'Employee [id=' + id + ', name=' + name + ', department='+ department + ']';}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result+ ((department == null) ? 0 : department.hashCode());result = prime * result + ((id == null) ? 0 : id.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic 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 (department == null) {if (other.department != null) {return false;}} else if (!department.equals(other.department)) {return false;}if (id == null) {if (other.id != null) {return false;}} else if (!id.equals(other.id)) {return false;}if (name == null) {if (other.name != null) {return false;}} else if (!name.equals(other.name)) {return false;}return true;}}
package org.timesheet.domain;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;@Entity
@Table(name = 'manager')
public class Manager {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)private Long id;private String name;public Manager() {}public Manager(String name) {this.name = name;}public String getName() {return name;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public void setName(String name) {this.name = name;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((id == null) ? 0 : id.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj) {return true;}if (obj == null) {return false;}if (!(obj instanceof Manager)) {return false;}Manager other = (Manager) obj;if (id == null) {if (other.id != null) {return false;}} else if (!id.equals(other.id)) {return false;}if (name == null) {if (other.name != null) {return false;}} else if (!name.equals(other.name)) {return false;}return true;}@Overridepublic String toString() {return 'Manager [id=' + id + ', name=' + name + ']';}}
package org.timesheet.domain;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;@Entity
@Table(name='timesheet')
public class Timesheet {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)private Long id;@OneToOne@JoinColumn(name = 'employee_id')private Employee who;@OneToOne@JoinColumn(name = 'task_id')private Task task;private Integer hours;public Timesheet() {}public Timesheet(Employee who, Task task, Integer hours) {this.who = who;this.task = task;this.hours = hours;}public Employee getWho() {return who;}public Task getTask() {return task;}public Integer getHours() {return hours;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public void setWho(Employee who) {this.who = who;}public void setTask(Task task) {this.task = task;}public void setHours(Integer hours) {this.hours = hours;}/*** Manager can alter hours before closing task* @param hours New amount of hours*/public void alterHours(Integer hours) {this.hours = hours;}@Overridepublic String toString() {return 'Timesheet [id=' + id + ', who=' + who + ', task=' + task+ ', hours=' + hours + ']';}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((hours == null) ? 0 : hours.hashCode());result = prime * result + ((id == null) ? 0 : id.hashCode());result = prime * result + ((task == null) ? 0 : task.hashCode());result = prime * result + ((who == null) ? 0 : who.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj) {return true;}if (obj == null) {return false;}if (!(obj instanceof Timesheet)) {return false;}Timesheet other = (Timesheet) obj;if (hours == null) {if (other.hours != null) {return false;}} else if (!hours.equals(other.hours)) {return false;}if (id == null) {if (other.id != null) {return false;}} else if (!id.equals(other.id)) {return false;}if (task == null) {if (other.task != null) {return false;}} else if (!task.equals(other.task)) {return false;}if (who == null) {if (other.who != null) {return false;}} else if (!who.equals(other.who)) {return false;}return true;}
}

最后,这是我们需要同时使用@ManyToMany映射的Task实体。 这是因为一名雇员可以从事多个任务,而一项任务可以分配多个雇员。 我们使用@JoinTable和@JoinColumn批注定义了m:n的外观。

package org.timesheet.domain;import javax.persistence.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;@Entity
@Table(name = 'task')
public class Task {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@ManyToMany(fetch = FetchType.EAGER)@JoinTable(name = 'task_employee',joinColumns = {@JoinColumn(name = 'task_id')},inverseJoinColumns = {@JoinColumn(name = 'employee_id')})private List<Employee> assignedEmployees = new ArrayList<Employee>();@OneToOne@JoinColumn(name = 'manager_id')private Manager manager;private String description;boolean completed;public Task() {}public Task(String description, Manager manager, Employee... employees) {this.description = description;this.manager = manager;assignedEmployees.addAll(Arrays.asList(employees));completed = false;}public Manager getManager() {return manager;}public List<Employee> getAssignedEmployees() {return assignedEmployees;}public void addEmployee(Employee e) {assignedEmployees.add(e);}public void removeEmployee(Employee e) {assignedEmployees.remove(e);}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public boolean isCompleted() {return completed;}public void setCompleted(boolean completed) {this.completed = completed;}public void setAssignedEmployees(List<Employee> assignedEmployees) {this.assignedEmployees = assignedEmployees;}public void setManager(Manager manager) {this.manager = manager;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}@Overridepublic boolean equals(Object o) {if (this == o) {return true;}if (o == null || getClass() != o.getClass()) {return false;}Task task = (Task) o;if (completed != task.completed) {return false;}if (description != null ? !description.equals(task.description) : task.description != null) {return false;}if (id != null ? !id.equals(task.id) : task.id != null) {return false;}if (manager != null ? !manager.equals(task.manager) : task.manager != null) {return false;}return true;}@Overridepublic int hashCode() {int result = id != null ? id.hashCode() : 0;result = 31 * result + (manager != null ? manager.hashCode() : 0);result = 31 * result + (description != null ? description.hashCode() : 0);result = 31 * result + (completed ? 1 : 0);return result;}@Overridepublic String toString() {return 'Task{' +'id=' + id +', assignedEmployees=' + assignedEmployees +', manager=' + manager +', description='' + description + '\'' +', completed=' + completed +'}';}
}

因此,我们实际上并没有做任何特别的建模。 如果您喜欢一些UML,请看下图,关系与以前相同。

好的,我们有实体,现在让我们创建数据库。 选择一些数据库管理工具(即使是普通终端也可以)并创建时间表数据库(默认情况下,mysql将在Mac OS X上安装到/ usr / local / mysql / bin / mysql):

$ mysql -u root
mysql > create database timesheet;

如果您可能在不了解之前就已经配置过Hibernate,那么在处理SessionFactory时就需要很多文件和样板代码。 使用Spring,这些事情要简单得多。

现在,我们将创建我们的第一个Spring Bean配置文件 -该文件在其中注册Spring容器的bean。 如果我不得不向根本不了解Spring的人解释这个文件是什么,那是Spring容器可以找到对象的神奇包。

现代IDE将帮助您正确使用所有XML名称空间,例如,您可以从STS向导中查看图片。 NetBeans具有类似的功能,IntelliJ可以动态解析名称空间。

命名配置文件persistence-beans.xml,然后将其放在src / main / resources文件夹下。

因此,设置Hibernate,事务,批注配置等就像在XML文件中创建几个bean一样简单。 另外,我们可以将Java Config用于Spring,但是XML config仍然使用更多,因此我们将坚持使用这些配置。 我不想阻止您使用Java Config! XML config 现在更受欢迎,但是我不能保证在接下来的几年中。
我已经评论了每个bean,以确保您在继续之前了解我们在这里所做的事情。 如果要直观地了解Bean之间的连接,则可以再次使用一些工具-在STS中将其称为Bean Graph,在IntelliJ中将其称为Dependencies。 您可以在下面的图片中看到依赖项示例。

<?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:tx='http://www.springframework.org/schema/tx'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd'><!-- we can use annotations --><context:annotation-config />  <!-- package to look for annotated classes --><context:component-scan base-package='org.timesheet.service.impl' /><!-- we will manage transactions with annotations --><tx:annotation-driven /><!-- data source for our database --><bean id='dataSource' class='org.springframework.jdbc.datasource.DriverManagerDataSource'><property name='driverClassName' value='com.mysql.jdbc.jdbc2.optional.MysqlDataSource' /><property name='url' value='jdbc:mysql://localhost/timesheet' /><property name='username' value='root' /><property name='password' value='' /></bean><!-- configure hibernate session factory --><bean id='sessionFactory'class='org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean'><property name='dataSource' ref='dataSource' /><property name='annotatedClasses' ><list><value>org.timesheet.domain.Employee</value><value>org.timesheet.domain.Manager</value><value>org.timesheet.domain.Task</value><value>org.timesheet.domain.Timesheet</value></list></property><property name='hibernateProperties'><props><prop key='dialect'>org.hibernate.dialect.MySQL5InnoDBDialect</prop><prop key='hibernate.show_sql'>true</prop><prop key='hibernate.hbm2ddl.auto'>update</prop></props></property> </bean></beans>

好的,那是很多配置,对吗? 不好的是,我们已经将实体的名称作为纯文本放置到XML中,因此它不是友好的重构形式。 但我认为对于本教程来说是可以接受的 让我们为Hibernate编写集成测试,以便我们知道一切都已正确设置。

package org.timesheet.integration;import static org.junit.Assert.*;import org.hibernate.SessionFactory;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;@ContextConfiguration(locations = '/persistence-beans.xml')
public class HibernateConfigurationTest extends AbstractJUnit4SpringContextTests {@Autowiredprivate SessionFactory sessionFactory;@Testpublic void testHibernateConfiguration() {// Spring IOC container instantiated and prepared sessionFactoryassertNotNull (sessionFactory); }}

我要你在这里注意两件事。 首先,我们扩展AbstractJUnit4SpringContextTests类。 我们告诉它应该在哪里寻找使用Spring bean的实际XML配置。 否则,我们将不得不自己创建Spring容器,这意味着需要更多样板代码。

其次,我们使用@Autowired批注。 这意味着我们不会使用新的运算符手动创建SessionFactory实例,而是将其通过Spring容器自动装配(注入)! 这是Spring容器最重要的目的之一-依赖于接口注入实现而不是手工创建它们。
一切现在都应该正常工作,我认为这部分就足够了。

如果您愿意,可以检查普通的SQL,并在此处查看表,请按照以下步骤进行操作:

mysql> use timesheet;
mysql> show tables;
+---------------------+
| Tables_in_timesheet |
+---------------------+
| employee            |
| manager             |
| task                |
| task_employee       |
| timesheet           |
+---------------------+
5 rows in set (0.00 sec)

参考: 第2部分–持久层–从vrtoonjava博客的JCG合作伙伴 Michal Vrtiak 编写实体并配置Hibernate 。

翻译自: https://www.javacodegeeks.com/2012/09/spring-persistence-layer-writing.html

Spring –持久层–编写实体并配置Hibernate相关推荐

  1. Spring中的packagesToScan的方式配置hibernate的class文件映射规则的理解

    Spring中的packagesToScan的方式配置hibernate的class文件映射规则的理解            1.持久化实体,使用自动扫描class的形式进行配置时,规则如下 (1)& ...

  2. 【Spring 持久层】Spring 与 Mybatis 整合

    持久层 持久层整合总述 Mybatis 开发步骤回顾 Mybatis 开发中存在的问题 Spring 与 Mybatis 整合思路 Spring 与 Mybatis 整合的开发步骤 Spring 与 ...

  3. 【Spring 持久层】Spring 事务开发、事务属性详解

    持久层 事务回顾 Spring 事务编程开发 Spring 中的事务属性(Transaction Attribute) 隔离属性(ISOLATION) 传播属性(PROPAGATION) 只读属性(r ...

  4. 基于持久层框架hibernate用SpringMVC增删功能

    接Spring MVC框架(1)的方法 Hibernate:持久层全自动化的框架 hibernate 用的少了 因为现在mybatis用的多 接下来 hibernate框架要链接数据库blog /* ...

  5. java开源持久层框架集

    原文链接:http://www.open-open.com/3_18.htm Hibernate Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Ja ...

  6. Java持久层框架之mybatis使用

    一.什么是框架,框架从何而来,为什么使用框架? 框架(framework): 1.是一系列jar包,其本质是对JDK功能的拓展.(jar包,jar:class文件的压缩包) 2.框架是一组程序的集合, ...

  7. 表现层(jsp)、持久层(类似dao)、业务层(逻辑层、service层)、模型(javabean)、控制层(action)...

    转自:http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html 为了实现web层(struts)和持久层(Hibernate)之间的松 ...

  8. 业务层 java_表现层(jsp)、持久层(类似dao)、业务层(逻辑层、service层)、模型(javabean)、控制层(action)...

    为了实现web层(struts)和持久层(Hibernate)之间的松散耦合,我们采用业务代表(Business Delegate)和DAO(Data Access Object)两种模式.DAO模式 ...

  9. 表现层、持久层、业务层

    为了实现web层(struts)和持久层(Hibernate)之间的松散耦合,我们采用业务代表(Business Delegate)和DAO(Data Access Object)两种模式.DAO模式 ...

最新文章

  1. 【libevent】libevent库学习总结(二)——编程步骤
  2. 用计算机语言编写的完成一定功能,C+的+预备知识.ppt
  3. 通过NSNotification来监听键盘弹出和弹回
  4. 变量命名 – 匈利亚命名法则 - C语言零基础入门教程
  5. 计算机网络课程设计之基于 IP 多播的网络会议程序
  6. java代码god类_java – 如何编写Controller而不将其作为God对象?
  7. 2021年下半年网络规划设计师下午真题及答案解析
  8. squid配置选项分析
  9. python 特殊方法实例
  10. was如何使用gzip_一文详解前端Node原生模块zlib,开启gzip压缩让页面响应速度更快...
  11. 信息安全问题频发:四成人讨厌大数据 六成人称微信谣言最多
  12. tcp/ip IP数据报头详解
  13. python中的pip什么意思-python中的pip
  14. oracle中同义词的用法,Oracle中定义以及使用同义词的方法
  15. SAP中统驭科目理解及举例
  16. React技术栈探究-Redux
  17. 如何查看谷歌账户的实际消费金额和扣款金额是否一致?
  18. 数列的操作 div2
  19. GNU gettext
  20. 破窗效应(Break Pane Law)

热门文章

  1. maven 版本号插件_测试Maven版本插件自动递增版本号
  2. envoy api 网关_为Envoy构建控制平面的指南-特定于域的配置API
  3. packt_Packt和Java Code Geeks提供的$ 5 Java编程书籍!
  4. mysql 死锁监视器_并发基础知识:死锁和对象监视器
  5. java 字段构造函数_依赖注入–字段vs构造函数vs方法
  6. javaee编程题_在JavaEE中使用CDI的简单面向方面的编程(AOP)
  7. 使用Spring Boot和DJL进行深度学习
  8. Spring Reactive已经过时了吗? 螺纹连接反转
  9. 使用Spock 1.2简化对遗留应用程序的集成测试
  10. 使用一个命令执行单个Java源文件