Spring –持久层–编写实体并配置Hibernate

欢迎来到本教程的第二部分。 当您看到本文有多长时间时,请不要惊慌–我向您保证,这主要是简单的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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/371377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无线服务器主机名是,wifi默认服务器主机名

wifi默认服务器主机名 内容精选换一换以CentOS 7操作系统的弹性云服务器为例&#xff1a;登录Linux弹性云服务器&#xff0c;查看“cloud-init”的配置文件。检查“/etc/cloud/cloud.cfg”文件中“update_hostname”是否被注释或者删除。如果没有被注释或者删除&#xff0c;则需…

pygame里面物体闪烁运动_利用自闪烁发光二极管探究小车在倾斜轨道上的运动规律...

2020年11月23日&#xff0c;周一&#xff0c;24小时安全值班。利用当班中午的时间&#xff0c;微主在创客空间测试了自闪烁发光二极管在匀加速运动中的效果&#xff0c;结果还比较满意。将小车放置在倾斜的轨道上&#xff0c;将自闪烁发光二极管和纽扣电池构成频闪光源&#xf…

python网络爬虫与信息提取 学习笔记day3

Day3&#xff1a; 只需两行代码解析html或xml信息 具体代码实现:day3_1 注意BeautifulSoup的B和S需要大写&#xff0c;因为python大小写敏感 import requests r requests.get("http://python123.io/ws/demo.html") r.text demo r.text from bs4 import Beauti…

番石榴文件:Java文件管理

正如我在这里 &#xff0c; 这里 &#xff0c; 这里和这里所讨论的那样&#xff0c; Groovy和Java SE 7都为Java文件管理提供了改进。 但是&#xff0c;当特定的Java应用程序尚不能使用Java SE 7或Groovy进行文件管理时&#xff0c;仍然可以通过使用Guava的Files类获得改进的文…

顺序查找

顺序查找属于查找中较容易的一个方法&#xff0c;且对数据是否已经排序没有要求&#xff0c;是很常用的一个查找算法。 但缺点是必须一个一个数字进行比较查找&#xff0c;查找所需步骤可能较多。 顺序查找算法的思想是&#xff0c;将目标与待查找数据进行比较&#xff0c;若发…

王者荣耀微信哪个服务器人最少,王者荣耀:微信区王者人数锐减,大神们都去哪了?这些原因很真实...

原标题&#xff1a;王者荣耀&#xff1a;微信区王者人数锐减&#xff0c;大神们都去哪了&#xff1f;这些原因很真实王者荣耀&#xff1a;微信区王者人数锐减&#xff0c;大神们都去哪了&#xff1f;这些原因很真实大家好&#xff01;王者荣耀S16赛季已经开启一月之余&#xff…

一个div压在另一个div上面_【CSS小分享】用CSS画一个新拟态风格键盘

什么是新拟态新拟态的英文名称是“Neumorphism”&#xff0c;也有人称为“Soft UI”。简单讲&#xff0c;新拟态是一种图形样式&#xff0c;其原理是通过模拟真实物体来为界面的UI元素赋予真实感。新拟态风格起源于dribbble&#xff0c;后面陆续被收录在2020设计趋势预测里面&a…

JBoss BRMS与JasperReports进行报告

介绍 Jasperreports是一个免费的可下载库&#xff0c;可用于为Java EE应用程序生成丰富的报告。 本指南还提供了使用Jasper iReport设计器生成报告模板的步骤。 软件需求 JBoss BRMS 5.3&#xff08;从客户门户网站http://access.redhat.com &#xff09; JasperReports 4.6…

java字符串 删除指定字符的那些事

需求如下&#xff1a; 1.算出2周以前的时间&#xff0c;以正常日期格式返回 2.如果月份和日期前面有0需要去掉返回结果&#xff0c;比如&#xff1a;2017-08-15 就需要显示2017-8-15。 Calendar calendar Calendar.getInstance();calendar.add(Calendar.DATE, -14);Date date…

Hibernate中Hql查询

这篇随笔将会记录hql的常用的查询语句&#xff0c;为日后查看提供便利。 在这里通过定义了三个类&#xff0c;Special、Classroom、Student来做测试&#xff0c;Special与Classroom是一对多&#xff0c;Classroom与Student是一对多的关系&#xff0c;这里仅仅贴出这三个bean的属…

Java代码质量工具–概述

最近&#xff0c;我有机会在本地IT社区聚会上介绍了该主题。 这是基本演示&#xff1a; Java代码质量工具 以及更有意义的思维导图&#xff1a; 但是&#xff0c;我认为我需要更深入地探讨这一主题。 这篇博客文章应该像是在此方向上进行进一步调查的起点。 1. CodePro Anal…

利用yum升级Centos6的gcc版本,使其支持C++11

下面的可以在centos6下工作&#xff0c;centos7下有问题。可能是因为centos下的scl我是拷贝的文件&#xff0c;没有完全验证centos6下肯定没问题。 https://my.oschina.net/u/583362/blog/682123 和https://www.quyu.net/info/876.html 拷贝其关键内容就是&#xff1a; 1.使用 …

cuda版本查看_ubuntu安装CUDA

0 写在前面安装环境&#xff1a;ubuntu18.04以及GTX1050Ti笔记本为什么要安装CUDA&#xff1f; 参考百科&#xff0c;CUDA是英伟达推出的集成技术&#xff0c;通过该技术可利用GeForce 8 以后的GPU或者较新的Quadro GPU进行计算。例如典型的tensorflow-GPU和pyCUDA安装之前都要…

HTML 标签列表(功能排序) HTML 参考手册- (HTML5 标准)

HTML 标签列表&#xff08;功能排序&#xff09; HTML 参考手册- (HTML5 标准) 功能排序 New : HTML5 新标签 标签描述基础 <!DOCTYPE> 定义文档类型。<html>定义一个 HTML 文档<title>为文档定义一个标题<body>定义文档的主体<h1> to <h6>…

idea新建scala文件_IDEA maven项目中新建.scala文件

本文首发于我的博客[IDEA maven项目中新建.scala文件]分为三步第一步、IDEA中安装scala插件1、搜索安装File-Sittings-Plugins-搜索安装scala2、安装完成重启安装完成之后点击重启idea第二步、下载、安装、配置Scala1、下载安装Scala SDK本体搜索引擎搜索Scala SDK或者点我去Sc…

Linux中执行shell脚本的4种方法总结

文章来源&#xff1a;http://www.jb51.net/article/53924.htm 这篇文章主要介绍了Linux中执行shell脚本的4种方法总结,即在Linux中运行shell脚本的4种方法,需要的朋友可以参考下 bash shell 脚本的方法有多种&#xff0c;现在作个小结。假设我们编写好的shell脚本的文件名为hel…

Log4j线程死锁–案例研究

此案例研究描述了影响Weblogic Portal 10.0生产环境的Apache Log4j线程争用问题的完整根本原因分析和解决方案。 它还将说明在开发和支持Java EE应用程序时适当的Java类加载器知识的重要性。 本文也是您提高线程转储分析技能和了解线程竞争条件的另一个机会。 环境规格 Java …

代码实现:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字

import java.util.Scanner;/*题目&#xff1a;求saaaaaaaaaaaa...a的值&#xff0c;其中a是一个数字。例如222222222222222(此时共有5个数相加)&#xff0c;几个数相加有键盘控制。 程序分析&#xff1a;关键是计算出每一项的值。*/public class Test08 {public static void ma…

堆栈跟踪从何而来?

我认为&#xff0c;阅读和理解堆栈跟踪是每个程序员都必须具备的一项基本技能&#xff0c;以便有效地解决每种JVM语言的问题&#xff08;另请参阅&#xff1a; 过滤日志中无关的堆栈跟踪行和首先记录引起异常的根本原因 &#xff09;。 那么我们可以从一个小测验开始吗&#xf…

@select 怎么写存储过程_MySQL4:存储过程和函数

什么是存储过程简单说&#xff0c;存储过程就是一条或多条SQL语句的集合&#xff0c;可视为批文件&#xff0c;但是起作用不仅限于批处理。本文主要讲解如何创建存储过程和存储函数以及变量的使用&#xff0c;如何调用、查看、修改、删除存储过程和存储函数等。使用的数据库和表…