之前用maven+spring+mybatis+spring mvc搭建了一个web项目,用于学习spring及相关知识,现在打算将mybatis换成hibernate,一样搭建一个框架。
其实mybatis或者hibernate都只是orm框架,负责数据持久层的工作,spring对这二者都提供了较好的支持。只不过在具体的实现配置上有一些差异。
话不多说,接下来以一个实例一步一步介绍如何搭建spring+hibernate的框架。
1.新建maven项目
导入必要的jar包。关于如何新建maven项目,可以看这篇文章。maven安装配置及使用maven创建一个web项目
2.引入jar包
我们来看下maven项目的pom.xml文件,这份文件是我从之前做maven+spring+mybatis+spring mvc项目的pom.xml文件中拷贝过来,并且将其中的mybatis相关包换成hibernate的相关包。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xdx</groupId> <artifactId>warrior_hibernate</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>warrior_hibernate Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- spring核心包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.2.5.RELEASE</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!-- jdbc驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.8-dmr</version> </dependency> <!-- hibernate核心包 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.9.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.3.9.Final</version> </dependency> <!-- 连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.29</version> </dependency> <!-- 打印日志 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.9</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.9</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- 其他 --> <!-- jsp标签 --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jstl-impl</artifactId> <version>1.2</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> </exclusion> </exclusions> </dependency> <!-- net.sf.json-lib --> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> <!-- websocket --> <dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>1.3.0</version> </dependency> <!-- 文件上传 --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.2</version> </dependency> <!-- 分页插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.0.3-beta</version> </dependency> <!-- 百度富文本 --> <dependency> <groupId>com.github.qiuxiaoj</groupId> <artifactId>ueditor</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20170516</version> </dependency> <!-- 防止responseBody中文乱码 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.5.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.2</version> </dependency> <!-- 邮件 --> <dependency> <groupId>javax.mail</groupId> <artifactId>javax.mail-api</artifactId> <version>1.6.0</version> </dependency> <dependency> <groupId>com.sun.mail</groupId> <artifactId>smtp</artifactId> <version>1.6.0</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>com.sun.mail</groupId> <artifactId>mailapi</artifactId> <version>1.6.0</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> <!-- quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency> <!-- redis --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.8.6.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.3.1.RELEASE</version> <type>pom</type> </dependency> <!-- 照片处理 --> <dependency> <groupId>com.mortennobel</groupId> <artifactId>java-image-scaling</artifactId> <version>0.8.6</version> </dependency> <!-- 测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- 第三方统计 --> <dependency> <groupId>net.bull.javamelody</groupId> <artifactId>javamelody-core</artifactId> <version>1.69.0</version> </dependency> </dependencies> <build> <finalName>warrior_hibernate</finalName> </build> </project>
主要的包是spring核心包,hibernate核心包,jdbc驱动,以及测试包等,其他包是今后扩展功能的时候用到的,暂时可以不用。
这边还需要注意的是,我本来用的是hibernate5.x的包,但是在启动项目的时候报错了,最后查出是因为包的版本太高,与spring的jar包发生了冲突,后面将其降为hibernate4.x才排除了错误。具体的排错过程,可以看这里。tomcat启动失败的一种可能性
3.建立数据库
并且建表。选取其中一个表t_admin,其表结构如下图所示。
4.建立实体对象
既然是用hibernate,则需要为数据库的表对象建立相应的java实体对象。具体可以参考这边文章。使用Myeclipse为数据表创建hibernate实体对象
创建后的实体文件如下所示。
TAdmin.java
package com.xdx.entity; import java.sql.Timestamp; /** * TAdmin entity. @author MyEclipse Persistence Tools */ public class TAdmin implements java.io.Serializable { // Fields private Integer adminId; private String adminName; private String password; private String realName; private Integer roleId; private Timestamp createTime; private Timestamp updateTime; private Integer isDel; // Constructors /** default constructor */ public TAdmin() { } /** minimal constructor */ public TAdmin(String password, Integer roleId, Timestamp createTime, Integer isDel) { this.password = password; this.roleId = roleId; this.createTime = createTime; this.isDel = isDel; } /** full constructor */ public TAdmin(String adminName, String password, String realName, Integer roleId, Timestamp createTime, Timestamp updateTime, Integer isDel) { this.adminName = adminName; this.password = password; this.realName = realName; this.roleId = roleId; this.createTime = createTime; this.updateTime = updateTime; this.isDel = isDel; } // Property accessors public Integer getAdminId() { return this.adminId; } public void setAdminId(Integer adminId) { this.adminId = adminId; } public String getAdminName() { return this.adminName; } public void setAdminName(String adminName) { this.adminName = adminName; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } public String getRealName() { return this.realName; } public void setRealName(String realName) { this.realName = realName; } public Integer getRoleId() { return this.roleId; } public void setRoleId(Integer roleId) { this.roleId = roleId; } public Timestamp getCreateTime() { return this.createTime; } public void setCreateTime(Timestamp createTime) { this.createTime = createTime; } public Timestamp getUpdateTime() { return this.updateTime; } public void setUpdateTime(Timestamp updateTime) { this.updateTime = updateTime; } public Integer getIsDel() { return this.isDel; } public void setIsDel(Integer isDel) { this.isDel = isDel; } }
TAdmin.hbm.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="com.xdx.entity.TAdmin" table="t_admin" catalog="qgranite"> <id name="adminId" type="java.lang.Integer"> <column name="admin_id" /> <generator class="native" /> </id> <property name="adminName" type="java.lang.String"> <column name="admin_name" length="100" /> </property> <property name="password" type="java.lang.String"> <column name="password" length="100" not-null="true" /> </property> <property name="realName" type="java.lang.String"> <column name="real_name" length="100" /> </property> <property name="roleId" type="java.lang.Integer"> <column name="role_id" not-null="true" /> </property> <property name="createTime" type="java.sql.Timestamp"> <column name="create_time" length="19" not-null="true" /> </property> <property name="updateTime" type="java.sql.Timestamp"> <column name="update_time" length="19" /> </property> <property name="isDel" type="java.lang.Integer"> <column name="is_del" not-null="true" /> </property> </class> </hibernate-mapping>
5.创建项目的主要包
分别创建com.xdx.entity,com.xdx.service,com.xdx.dao,com.xdx.controller,com.xdx.util等包。如下图所示。并将上面生成的实体放入com.xdx.entity包中。
6.编写数据源配置文件
项目采用阿里数据连接池,druid。jdpc.properities配置文件如下。
#数据源1 url:jdbc:mysql://xxx.xxx.xxx.xxx:3306/qgranite?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=UTC&useSSL=false driverClassName:com.mysql.cj.jdbc.Driver username:xdx password:xxxxxxxxx filters:stat maxActive:20 initialSize:1 maxWait:60000 minIdle:10 maxIdle:15 timeBetweenEvictionRunsMillis:60000 minEvictableIdleTimeMillis:300000 validationQuery:SELECT 'x' testWhileIdle:true testOnBorrow:false testOnReturn:false maxOpenPreparedStatements:20 removeAbandoned:true removeAbandonedTimeout:1800 logAbandoned:true # hibernate.X hibernate.connection.driverClass=org.gjt.mm.mysql.Driver hibernate.connection.url=jdbc:mysql://139.196.235.228:3306/qgranite hibernate.dialect=org.hibernate.dialect.MySQL5Dialect hibernate.connection.username=xdx hibernate.connection.password=wonyen@1602 hibernate.show_sql=true #hibernate.hbm2ddl.auto=create-drop 这边千万不要写create-drop,不然每次项目启动他会先删除表,再重建,表中的数据也会丢失 hibernate.hbm2ddl.auto=update
这边需要注意3个地方。
a.url的配置需要跟上后面那堆参数,那是新的jdbc驱动要求的,如果不跟,会报错。
b.driverClassName要写com.mysql.cj.jdbc.Driver而不是旧版本的com.mysql.jdbc.Driver,因为后者已经过时了。
c.hibernate.hbm2ddl.auto千万不要写=create-drop,否则项目启动的时候会把所有数据表删除,然后再新建,这样里面的数据就不见了,我这边写的是update,即有修改的时候会自动update.
上述配置文件会被spring的主配置文件,ApplicationContext.xml引用。
7.编写spring主配置文件
spring主配置文件是spring项目最重要的一个配置文件,数据源配置,事务管理配置,以及加载所有javabean等都在此处配置。当我们启动一个web项目的时候,先去加载项目所引用的jar包(包括jdk,tomcat,还有maven处所引用的jar包),接下来去访问web.xml文件,根据web.xml文件的配置,找到spring主配置文件的位置,读取其内容,然后就可以进行加载javabean,初始化数据库连接池等工作了。(关于web项目启动的步骤,可以参照这篇文章。)