spring整合Hibernate步骤以及遇到的问题
文章目录
- spring整合Hibernate步骤以及遇到的问题
- 步骤:
- 创建实体类:
- 编写Dao层:
- 编写server层:
- spring配置文件
- hibernate配置文件
- 用到的注解:
- 遇到的问题
- 找不到spring的@Transactional注解
- 使用HibernateDaoSupport时注入SessionFactory的方式
- 使用自动扫描机制时要添加扫描包
- xml配置全过程代码
使用环境:
idea 2019.1
jdk 1.8
spring 5.3.1
hibernate 5.4.6
连接数据库方式 dbcp
步骤介绍使用的是注解注入,后面贴上了使用配置文件配置。
步骤:
创建一个spring项目并且勾上Web Application、勾上hibernate,Libraries选择Set up library later
**创建好项目后,在web目录下创建lib子目录,将要添加的jar复制到里面,并右键所有复制进去的包,选择Add as library成功将jar包导入到项目中。**以下为使用到的jar包,圈出的为必须导入。
整合spring和hibernate时对于配置文件有两种写法:将hibernate配置文件直接写入spring配置文件中;另外写hibernate配置文件,在spring中注入。(以下演示选择的是后者,后者spring的配置文件更简洁)
ps:1.、在整合后的hibernate配置文件中只存放:dialect、ddl模式、是否显示sql、加载映射文件等配置,数据库连接方式和数据库信息,均在spring配置文件中配置成dataSource
2、加入spring后,hibernate的DataSource、SessionFactory、事务管理都由spring配置,并且添加了HibernateTemplate、HibernateDaosupport使得hibernate的使用更加方便
创建实体类:
使用的是注解映射,所以不用编写映射文件,但是要在hibernate配置文件中加载mapping映射
package com.sise.hgl.po;
import javax.persistence.*;
@Table(name = "user")
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private int id;
@Column(name = "username", nullable = false)
private String username;
public void setId(int id){
this.id = id;
}
public int getId(){
return id;
}
public void setUsername(String username){
this.username = username;
}
public String getUsername(){
return username;
}
}
编写Dao层:
Dao层接口:
package com.sise.hgl.dao;
import com.sise.hgl.po.User;
import org.springframework.stereotype.Repository;
@Repository
public interface UserDao {
public void addUser(User user);
public void deleteUser(User user);
public User queryUser(int id);
public void updateUser(User user);
}
接口实现类:
UserDaoImpl.java
package com.sise.hgl.dao.impl;
import com.sise.hgl.dao.UserDao;
import com.sise.hgl.po.User;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
@Repository("userDao")
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
public void setSuperSessionFactory(SessionFactory sessionFactory){
super.setSessionFactory(sessionFactory);
}
public void addUser(User user) {
getHibernateTemplate().persist(user);
}
public void deleteUser(User user) {
getHibernateTemplate().delete(user);
}
public User queryUser(int id) {
return getHibernateTemplate().get(User.class, id);
}
public void updateUser(User user) {
getHibernateTemplate().update(user);
}
}
编写server层:
Service层接口:
UserService.java
package com.sise.hgl.service;
import com.sise.hgl.po.User;
import org.springframework.stereotype.Service;
@Service
public interface UserService {
public void addUser(User user);
public void deleteUser(User user);
public User queryUser(int id);
public void updateUser(User user);
}
接口实现类:
UserServiceImpl.java
package com.sise.hgl.service.impl;
import com.sise.hgl.dao.UserDao;
import com.sise.hgl.po.User;
import com.sise.hgl.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Service("userService")
@Transactional(readOnly = false)
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void addUser(User user) {
userDao.addUser(user);
}
public void deleteUser(User user) {
userDao.deleteUser(user);
}
public User queryUser(int id) {
return userDao.queryUser(id);
}
public void updateUser(User user) {
userDao.updateUser(user);
}
}
spring配置文件
ApplicationContext.xml
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置数据库连接池(数据源) -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/hibernate"/>
<property name="username" value="数据库用户名"/>
<property name="password" value="数据库密码"/>
<property name="maxTotal" value="100"/>
<property name="maxIdle" value="60"/>
<property name="maxWaitMillis" value="10000"/>
</bean>
<!-- 配置SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
</bean>
<!-- 配置Hibernate事务管理 -->
<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
<!-- 配置HibernateTemplate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<
<!-- spring自动扫描机制 用于注解注释-->
<context:component-scan base-package="com.sise.hgl.dao.impl"/>
<context:component-scan base-package="com.sise.hgl.service.impl"/>
</beans>
使用tx,需要引入命名空间
hibernate配置文件
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="show_sql">true</property>
<mapping class="com.sise.hgl.po.User"/>
</session-factory>
</hibernate-configuration>
测试类:
package com.sise.hgl;
import com.sise.hgl.po.User;
import com.sise.hgl.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApplication {
private static ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
private static UserService userService = (UserService) applicationContext.getBean("userService");
public static void main(String[] args) {
addUser();
delete(5);
update(1, "hgl");
findUserById(2);
}
public static void addUser(){
User u1 = new User();
u1.setUsername("Gavin");
userService.addUser(u1);
User u2 = new User();
u2.setUsername("Steven");
userService.addUser(u2);
User u3 = new User();
u3.setUsername("Tom");
userService.addUser(u3);
User u4 = new User();
u4.setUsername("David");
userService.addUser(u4);
User u5 = new User();
u5.setUsername("GLongH");
userService.addUser(u5);
}
public static void findUserById(int id){
User user = userService.queryUser(id);
System.out.println("编号:" + user.getId() + "的姓名是:" + user.getUsername());
}
public static void update(int id, String name){
User user = userService.queryUser(id);
System.out.println("修改前:" + "编号:" + user.getId() + "的姓名是:" + user.getUsername());
user.setUsername(name);
userService.updateUser(user);
user = userService.queryUser(id);
System.out.println("修改后:" + "编号:" + user.getId() + "的姓名是:" + user.getUsername());
}
public static void delete(int id){
User user = userService.queryUser(id);
System.out.println("即将删除的数据为:"+ "编号:" + user.getId() + "的姓名是:" + user.getUsername());
userService.deleteUser(user);
System.out.println("successfully");
}
}
用到的注解:
@Entity
:声明该类是Hibernate的实体类@Table
:对应数据库的表@Id
:声明为主键@GeneratedValue
:主键生成策略@Column
:声明数据对应的数据库字段@Repository
:与@component
作用一样,前者表明该bean是dao层bean,默认id为类名首字母小写,可以另外设定。@Service
:与@component
作用一样,前者表明该bean是service层bean,默认id为类名首字母小写,可以另外设定。@Resource
:通过名字注入,该注解是jdk中的不是spring中的。@Transactional
:由spring自动管理hibernate事务。
遇到的问题
找不到spring的@Transactional注解
- 引入
@Transactional
只有import javax.transaction.Transactional的源,而没有spring包下的。
解决:该注解是org.springframework.transaction.annotation.Transactional中的,在spring-tx包下,导入jar包即可。
使用HibernateDaoSupport时注入SessionFactory的方式
- 在使用HibernateDaoSupport的同时使用注解会遇到如何注入SessionFactory的问题,直接声明一个SessionFactory成员属性,这个方法并不能成功注入。而直接重写父类的
setHibernateTemplate()
方法可以但是!!!该方法是final不能重写。
解决:使用父类调用该方法完成注入
@Resource
public void setSessionFactoryBySuper(SessionFactory sessionFactory){
super.setSessionFactory(sessionFactory);
}
使用自动扫描机制时要添加扫描包
- 使用spring的自动扫描机制时,需要在配置文件中添加
<context:component-scan base-package="..."/>
xml配置全过程代码
User.java
package com.sise.hgl.po;
public class User {
private int id;
private String username;
public void setId(int id){
this.id = id;
}
public int getId(){
return id;
}
public void setUsername(String username){
this.username = username;
}
public String getUsername(){
return username;
}
}
UserDao.java
package com.sise.hgl.dao;
import com.sise.hgl.po.User;
public interface UserDao {
public void addUser(User user);
public void deleteUser(User user);
public User queryUser(int id);
public void updateUser(User user);
}
UserDaoImpl.java
package com.sise.hgl.dao.impl;
import com.sise.hgl.dao.UserDao;
import com.sise.hgl.po.User;
import org.springframework.orm.hibernate5.HibernateTemplate;
public class UserDaoImpl implements UserDao {
private HibernateTemplate hibernateTemplate;
public void setHibernateTemplate(HibernateTemplate hibernateTemplate){
this.hibernateTemplate = hibernateTemplate;
}
public void addUser(User user) {
hibernateTemplate.persist(user);
}
public void deleteUser(User user) {
hibernateTemplate.delete(user);
}
public User queryUser(int id) {
return hibernateTemplate.get(User.class, id);
}
public void updateUser(User user) {
hibernateTemplate.update(user);
}
}
UserService.java
package com.sise.hgl.service;
import com.sise.hgl.po.User;
public interface UserService {
public void addUser(User user);
public void deleteUser(User user);
public User queryUser(int id);
public void updateUser(User user);
}
UserServiceImpl.java
package com.sise.hgl.service.impl;
import com.sise.hgl.dao.UserDao;
import com.sise.hgl.po.User;
import com.sise.hgl.service.UserService;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Transactional(readOnly = false)
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void addUser(User user) {
userDao.addUser(user);
}
public void deleteUser(User user) {
userDao.deleteUser(user);
}
public User queryUser(int id) {
return userDao.queryUser(id);
}
public void updateUser(User user) {
userDao.updateUser(user);
}
}
ApplicationContext.xml
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/hibernate"/>
<property name="username" value="root"/>
<property name="password" value="sise"/>
<property name="maxTotal" value="100"/>
<property name="maxIdle" value="60"/>
<property name="maxWaitMillis" value="10000"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="userDao" class="com.sise.hgl.dao.impl.UserDaoImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
<bean id="userService" class="com.sise.hgl.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
</beans>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="show_sql">true</property>
<mapping resource="com/sise/hgl/po/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.sise.hgl.po">
<class name="User" table="user">
<id name="id">
<generator class="identity"/>
</id>
<property name="username" type="string" length="50" not-null="true" column="username"/>
</class>
</hibernate-mapping>
以上是学习过程总结,如有疏漏之处,还请不吝赐教,让我能更加了解这方面内容,提前感谢。