首页 技术 正文
技术 2022年11月14日
0 收藏 559 点赞 2,823 浏览 13188 个字

参考: https://my.oschina.net/gaussik/blog/513444

注:在阅读本文前,请先阅读:

Java EE 学习(5):IDEA + maven + spring 搭建 web(1)

Java EE 学习(6):IDEA + maven + spring 搭建 web(2)

5 数据库配置

下面,就要通过一个简单的例子,来介绍 SpringMVC 如何集成 Spring Data JPA(由 Hibernate JPA 提供),来进行强大的数据库访问,并通过本章节的讲解,更加深刻地认识 Controller 是如何进行请求处理的,看完这一章节,你就可以开始你的开发工作了。

准备工作:

在src\main\java 中新建两个包:com.example.model、com.example.repository,将在后面用上,如下图所示:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

(1)、创建Mysql数据库

本文的讲解使用Mysql数据库,如果使用其它数据库的读者,可以去网上参考其他的配置教程,在此不做太多的叙述。数据库是一个底层的东西,底层的细节对上层的抽象并没有太大的影响,因此,只要配置好数据库,本章的内容仍然是适用于所有数据库的(貌似如此)。

假设我们现在要建立一个小小的博客系统,其数据库ER图如下所示(当然这只是一个小小的例子,真实的博客系统比这要复杂的多):

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

新建一个数据库springdemo,在数据库中,有两张表:

(1)用户表user:用户登录信息,主键 id 设为自增;

(2)博文表blog:储存用户发表的博文,主键 id 设为自增,其中有一个外键 user_id 链接到 user 表。

详细表结构如下图所示:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

使用MySQL Workbench添加外键流程:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

注意:在添加外键时,应该根据需求设置,例如右边红框中的 Foreign Key Options,默认在 Delete 时是 NO ACTION,说明在删除一个用户时,如果数据库中存在该用户的文章,那么就无法删除该用户,也无法删除该用户的所有文章,而如果将该选项改为 CASCADE,那么删除该用户,就会同时删除该用户所有的文章。通常后者是不太可取的,因为如果发生了删除用户的误操作,很有可能该用户的内容被连带删除,且不可逆,这也是实现真实系统时需要考虑的原因之一。

以下是使用 Navicat for MySql 创建的过程:

user 表:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

blog 表:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

添加外键:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

(2)、IntelliJ IDEA导入数据库

对于此前所接触的一些常用的框架中,一张数据表往往对应一个Java Bean。在 SpringMVC 中,这个Java Bean 相当于 model。那么,这个类是否需要自己来写呢?不需要,利用  IntelliJ IDEA 可以帮我们自动的生成这些 JavaBean。

首先,右键项目,选择 Add Framework Support:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

下拉选择 JavaEE Persistence,右边 provider 选择 Hibernate:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

注:这一部分有一点过时,更新的项目中直接把数据库的配置放在了mvc-dispatcher-servlet.xml 中,但依然要做这一步的操作,为了这一步可以使用 Persistence 的工具。

关于新的配置,可以翻到博客底部。

在这一步结束后,我们可以发现,在 resources 里面生成了persistence.xml 配置文件,左边栏出现了一个 Persistence 标题(若没有请点击左下角那个灰框):

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

persistemce.xml 具体如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="NewPersistenceUnit">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.connection.url" value=""/>
<property name="hibernate.connection.driver_class" value=""/>
<property name="hibernate.connection.username" value=""/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>

我们先不着急填写这个配置文件。点开左边栏的 Persistence,显示如下图所示:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

右键项目名,选择Generate Persistence Mapping,再选择By Database Schema:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

出现如下界面,其主要需要配置的地方如下图红框所示:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

点击 Choose Data Source 右边的三个点选择数据源,在弹出的界面左上角选择 “+”,选择 Mysql:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

在如下界面填写主机、端口号、数据库名、用户名、密码,如果驱动丢失点击下面的 Download 可以下载驱动,点击 Test Connection可以测试数据库是否连接成功:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

在以上界面配置完成后,点OK,第一次使用需要 Setup Master Password:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

回到如下页面:

(1)package 填写 model 包;

(2) 勾选 Prefer primitive type 使用原始数据类型;

(3) 勾选 Show default relationships 以显示所有数据库关系;

(4)再点击刷新按钮,将会找到数据库中的两个表

(5)勾选两个数据表;

(6) 再勾选 Generate Column Defination 以生成每一列的描述信息。

(7)选中 blog 表然后点击“+”号按钮,添加外键关系(若已经添加过外键,此步则可以跳过)。

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

添加外键(若已经添加过,此不可忽略)

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

点击OK后,在Database Schema Mapping中可以发现多出了两个关系,如图所示:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

再点击OK,稍后,打开model包,可以看到生成了两个Java Bean,在SpringMVC中称为两个实体,它们对应了数据库的两张表:

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

BlogEntity 如下所示(注意把java.sql.Date改为java.util.Date):

package com.example.model;    # 注意自己的包名import javax.persistence.*;
import java.util.Date; # change: 更改导入包/**
* Created by dzkan on 2016/3/8.
*/
@Entity
@Table(name = "blog", schema = "springdemo", catalog = "")
public class BlogEntity {
private int id;
private String title;
private String content;
private Date pubDate;
private UserEntity userByUserId; @Id
@Column(name = "id", nullable = false)
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Basic
@Column(name = "title", nullable = false, length = 100)
public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} @Basic
@Column(name = "content", nullable = true, length = 255)
public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} @Basic
@Column(name = "pub_date", nullable = false)
public Date getPubDate() {
return pubDate;
} public void setPubDate(Date pubDate) {
this.pubDate = pubDate;
} @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; BlogEntity that = (BlogEntity) o; if (id != that.id) return false;
if (title != null ? !title.equals(that.title) : that.title != null) return false;
if (content != null ? !content.equals(that.content) : that.content != null) return false;
if (pubDate != null ? !pubDate.equals(that.pubDate) : that.pubDate != null) return false; return true;
} @Override
public int hashCode() {
int result = id;
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + (content != null ? content.hashCode() : 0);
result = 31 * result + (pubDate != null ? pubDate.hashCode() : 0);
return result;
}
@ManyToOne
@JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)
public UserEntity getUserByUserId() {
return userByUserId;
} public void setUserByUserId(UserEntity userByUserId) {
this.userByUserId = userByUserId;
}
}# 此处,注意,对于 “blog” , “springdemo” 之类的标红,不用管,是 IDEA 自身问题,不影响项目运行

再看UserEntity:

package com.example.model;   # 使用自己的包import javax.persistence.*;
import java.util.Collection; /**
* Created by dzkan on 2016/3/8.
*/
@Entity
@Table(name = "user", schema = "springdemo", catalog = "")
public class UserEntity {
private int id;
private String nickname;
private String password;
private String firstName;
private String lastName;
private Collection<BlogEntity> blogsById; @Id
@Column(name = "id", nullable = false)
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Basic
@Column(name = "nickname", nullable = false, length = 45)
public String getNickname() {
return nickname;
} public void setNickname(String nickname) {
this.nickname = nickname;
} @Basic
@Column(name = "password", nullable = false, length = 45)
public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} @Basic
@Column(name = "first_name", nullable = true, length = 45)
public String getFirstName() {
return firstName;
} public void setFirstName(String firstName) {
this.firstName = firstName;
} @Basic
@Column(name = "last_name", nullable = true, length = 45)
public String getLastName() {
return lastName;
} public void setLastName(String lastName) {
this.lastName = lastName;
} @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; UserEntity that = (UserEntity) o; if (id != that.id) return false;
if (nickname != null ? !nickname.equals(that.nickname) : that.nickname != null) return false;
if (password != null ? !password.equals(that.password) : that.password != null) return false;
if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null) return false;
if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null) return false; return true;
} @Override
public int hashCode() {
int result = id;
result = 31 * result + (nickname != null ? nickname.hashCode() : 0);
result = 31 * result + (password != null ? password.hashCode() : 0);
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
return result;
}

@OneToMany(mappedBy = "userByUserId")
public Collection<BlogEntity> getBlogsById() {
return blogsById;
} public void setBlogsById(Collection<BlogEntity> blogsById) {
this.blogsById = blogsById;
}
}

(3)、配置数据库

既然数据库已经导入了,那么前期准备工作基本完成,还需要进行最终的配置。

首先,打开 mvc-dispatcher-servlet.xml,添加下列配置(如果某些地方报错,请选中并按 Alt + Insert 补全配置):

<!-- 表示JPA Repository所在的包 -->
<jpa:repositories base-package="com.example.repository"/> # 注意自己的包名<!-- 链接到persistence.xml -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="defaultPersistenceUnit"/>
</bean><!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean><!-- 开启事务管理注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

讲解:

(1) jpa:repositories:这一部分涉及到数据库的接口,将在后面详解;

(2)entityManagerFactory:实体管理器工厂,读取 persistence.xml 配置;

(3)transactionManager:事务管理器,利用 entityManager 进行事务管理;

(4)tx:annotation-driven:打开事务管理器的注解驱动,可以使用注解的方法操纵数据库。

整体如下所示:

<?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"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx" # 此处要注意,默认的 tx 地址是 ../schema/catche, 此处需要更改,改为 黄色部分
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
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> # 此处同样要更改,改为 黄色部分
<!--指明 controller 所在包,并扫描其中的注解-->
<context:component-scan base-package="com.example.controller"/> <!-- 静态资源(js、image等)的访问 -->
<mvc:default-servlet-handler/> <!-- 开启注解 -->
<mvc:annotation-driven/> <!--ViewResolver 视图解析器-->
<!--用于支持Servlet、JSP视图解析-->
<bean id="jspViewResolver" 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> <!-- 表示JPA Repository所在的包 -->
<jpa:repositories base-package="com.example.repository"/> <!-- 链接到persistence.xml -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="defaultPersistenceUnit"/>
</bean> <!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean> <!-- 开启事务管理注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
# 另,此文件 配置正确,无任何错误!!

下面,填充 persistence.xml,将 persistence-unit 的 name改为 defaultPersistenceUnit。在下面的文件中,我添加了一些更为详细的配置:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="defaultPersistenceUnit">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<!-- 使用MySQL方言 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<!-- 数据库连接的URL地址 -->
<property name="hibernate.connection.url"
value="jdbc:mysql://localhost:3306/springdemo"/>
<!-- 数据库连接的驱动 -->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<!-- 数据库连接的用户名 -->
<property name="hibernate.connection.username" value="root"/>
<!-- 数据库连接的密码 -->
<property name="hibernate.connection.password" value=""/>
<!-- 显示SQL语句 -->
<property name="hibernate.show_sql" value="true"/> <property name="hibernate.connection.useUnicode" value="true"/>
<property name="hibernate.connection.characterEncoding" value="UTF-8"/> <!-- 在显示SQL语句时格式化语句 -->
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="false"/>
<!-- 自动输出schema创建DDL语句 -->
<property name="hbm2ddl.auto" value="update"/> <!-- 数据库连接超时后自动重连 -->
<property name="hibernate.connection.autoReconnect" value="true"/>
<property name="connection.autoReconnectForPools" value="true"/>
<property name="connection.is-connection-validation-required" value="true"/>
</properties>
</persistence-unit>
</persistence>

现在,重新启动 tomcat,如果没有报错,说明数据库已经配置完成了,接下来就要讲解数据库的相关开发工作,另开一文:Java EE 学习(8):IDEA + maven + spring 搭建 web(4)- 用户管理

更新(未尝试):

阅读评论发现许多同学的persistence.xml出现了问题,因为出现问题的原因可能有很多,如果没有完全的报错以及代码的话,我这边很难解决问题,一个办法就是在GitHub Issues上面提问并贴出代码,我这边尽量解答。另一个办法就是下载最新的代码运行看有没有什么问题。

最后一个办法,尝试另外一种配置方法,无需 persistence.xml,直接在 mvc-dispatcher-servlet.xml 中配置数据库,如下所示:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="defaultPersistenceUnit"/>
<property name="packagesToScan" value="com.example.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/springdemo?useSSL=false</prop>
<prop key="hibernate.connection.username">root</prop>
<prop key="hibernate.connection.password">111111</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.autoReconnect">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="connection.autoReconnectForPools">true</prop>
<prop key="connection.is-connection-validation-required">true</prop> <prop key="hibernate.c3p0.validate">true</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">600</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.preferredTestQuery">SELECT 1;</prop>
<prop key="hibernate.c3p0.testConnectionOnCheckout">true</prop>
<prop key="hibernate.c3p0.idle_test_period">3000</prop>
</props>
</property>
</bean>

删除persistence.xml,直接修改entityManagerFactory bean为如上图所示。这个方法可以摆脱persistence.xml的困扰,但是有一个小小的问题,如果之前没有添加Java EE Persistence这个框架的,文中的Persistence工具栏将不会显示。一个解决办法就是,先修改mvc-dispatcher-servlet,然后再添加Java EE Persistence框架,等能够看到Persistence工具栏后,删除persistence.xml,余下的步骤可以继续操作。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,965
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,486
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,331
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,114
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,747
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,781