注:在阅读本文前,请先阅读:
使用IntelliJ IDEA开发SpringMVC网站(一)开发环境
使用IntelliJ IDEA开发SpringMVC网站(二)框架配置
访问GitHub下载最新源码:https://github.com/gaussic/SpringMVCDemo
文章已针对IDEA 15做了一定的更新,部分更新较为重要,请重新阅读文章并下载最新源码。
六、数据库配置
下面,就要通过一个简单的例子,来介绍SpringMVC如何集成Spring Data JPA(由 Hibernate JPA 提供),来进行强大的数据库访问,并通过本章节的讲解,更加深刻地认识Controller是如何进行请求处理的,相信看完这一章节,你就可以开始你的开发工作了。
准备工作:
在src\main\java中新建两个包:com.gaussic.model、com.gaussic.repository,将在后面用上,如下图所示:
1、创建Mysql数据库
本文的讲解使用Mysql数据库,如果使用其它数据库的读者,可以去网上参考其他的配置教程,在此不做太多的叙述。数据库是一个底层的东西,底层的细节对上层的抽象并没有太大的影响,因此,只要配置好数据库,本章的内容仍然是适用于所有数据库的(貌似如此)。
假设我们现在要建立一个小小的博客系统,其数据库ER图如下所示(当然这只是一个小小的例子,真实的博客系统比这要复杂的多):
新建一个数据库springdemo,在数据库中,有两张表:
(1)用户表user:用户登录信息,主键id设为自增;
(2)博文表blog:储存用户发表的博文,主键id设为自增,其中有一个外键user_id链接到user表。
详细表结构如下图所示:
使用MySQL Workbench添加外键流程:
注意:在添加外键时,应该根据需求设置,例如右边红框中的Foreign Key Options,默认在Delete时是NO ACTION,说明在删除一个用户时,如果数据库中存在该用户的文章,那么就无法删除该用户,也无法删除该用户的所有文章,而如果将该选项改为CASCADE,那么删除该用户,就会同时删除该用户所有的文章。通常后者是不太可取的,因为如果发生了删除用户的误操作,很有可能该用户的内容被连带删除,且不可逆,这也是实现真实系统时需要考虑的原因之一。
2、IntelliJ IDEA导入数据库
对于此前所接触的一些常用的框架中,一张数据表往往对应一个Java Bean。在SpringMVC中,这个Java Bean相当于model。那么,这个类是否需要自己来写呢?不需要,利用IntelliJ IDEA可以帮我们自动的生成这些JavaBean。
首先,右键项目,选择Add Framework Support:
下拉选择JavaEE Persistence,右边provider选择Hibernate:
在这一步结束后,我们可以发现,在resources里面生成了persistence.xml配置文件,左边栏出现了一个Persistence标题(若没有请点击左下角那个灰框):
persistemce.xml具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <? 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.ejb.HibernatePersistence</ 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,显示如下图所示:
右键项目名,选择Generate Persistence Mapping,再选择By Database Schema:
出现如下界面,其主要需要配置的地方如下图红框所示:
点击Choose Data Source右边的三个点选择数据源,在弹出的界面左上角选择“+”,选择Mysql:
在如下界面填写主机、端口号、数据库名、用户名、密码,如果驱动丢失点击下面的Download可以下载驱动,点击 Test Connection可以测试数据库是否连接成功:
在以上界面配置完成后,点OK,第一次使用需要Setup Master Password:
回到如下页面,package填写model包(1),勾选Prefer primitive type使用原始数据类型(2),勾选Show default relationships以显示所有数据库关系(3),再点击刷新按钮(4),将会找到数据库中的两个表,勾选两个数据表(5),再勾选Generate Column Defination以生成每一列的描述信息(6)。选中blog表然后点击“+”号按钮,添加外键关系(7)。
点击OK后,在Database Schema Mapping中可以发现多出了两个关系,如图所示:
再点击OK,稍后,打开model包,可以看到生成了两个Java Bean,在SpringMVC中称为两个实体,它们对应了数据库的两张表:
BlogEntity如下所示(注意把java.sql.Date改为java.util.Date):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | package com.gaussic.model; import javax.persistence.*; import java.util.Date; /** * 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; } } |
再看UserEntity:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | package com.gaussic.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补全配置):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!-- 表示JPA Repository所在的包 --> < jpa:repositories base-package = "com.gaussic.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:打开事务管理器的注解驱动,可以使用注解的方法操纵数据库。
整体如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <? 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" 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.gaussic.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.gaussic.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。在下面的文件中,我添加了一些更为详细的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <? xml version = "1.0" encoding = "UTF-8" ?> < persistence xmlns = "http://java.sun.com/xml/ns/persistence" version = "2.0" > < persistence-unit name = "defaultPersistenceUnit" transaction-type = "RESOURCE_LOCAL" > < provider >org.hibernate.ejb.HibernatePersistence</ 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 = "111111" /> <!-- 显示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 = "hibernate.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,如果没有报错,说明数据库已经配置完成了,接下来就要讲解数据库的相关开发工作。
转载地址:http://my.oschina.net/gaussik/blog/513444