本文共 9131 字,大约阅读时间需要 30 分钟。
完成例子:spring容器中取出业务bean,传入参数用户信息,持久化到数据库.
1.新建工程,导入spring包和hibernate包,还需要mysql驱动包,为方便测试,还导入junit包.
2.业务层类与dao层
package com.skymr.sphi.dao;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import com.skymr.sphi.model.User;public class UserDao { private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void save(User user){ System.out.println("执行UserDao save方法:"); Session session = sessionFactory.openSession(); Transaction tran = session.beginTransaction(); session.save(user); tran.commit(); session.close(); } public void update(User user){ System.out.println("执行UserDao update方法:"); Session session = sessionFactory.openSession(); Transaction tran = session.beginTransaction(); session.update(user); tran.commit(); session.close(); } public void delete(int id){ System.out.println("执行UserDao delete方法:"); Session session = sessionFactory.openSession(); Transaction tran = session.beginTransaction(); session.delete(id); tran.commit(); session.close(); } public User query(int id){ System.out.println("执行UserDao query方法:"); Session session = sessionFactory.openSession(); User ret = (User)session.get(User.class, id); session.close(); return ret; }}
package com.skymr.sphi.service;import com.skymr.sphi.model.User;public interface UserService { //保存用户信息 public void save(User user); //更新用户信息 public void update(User user); //删除用户信息 public void delete(int id); //查询用户信息 public User query(int id);}
package com.skymr.sphi.service.impl;import com.skymr.sphi.dao.UserDao;import com.skymr.sphi.model.User;import com.skymr.sphi.service.UserService;public class UserServiceBean implements UserService{ private UserDao userDao; public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void delete(int id) { userDao.delete(id); } public User query(int id) { return userDao.query(id); } public void save(User user) { userDao.save(user); } public void update(User user) { userDao.update(user); }}3.配置文件
1)spring主配置文件 config/applicationContext.xml
知道使用注解注入失败的原因了,是因为没开启注解的原因.
开启注解
要使用context标签就必须引入规范
2)spring管理的hibernate配置config/spring_annotation-hibernate.xml
3)Hibernate自己的配置config/hibernate/hibernate.cfg.xmlorg.hibernate.dialect.MySQLDialect true true update thread 1 true
classpath*:config/hibernate/hibernate.cfg.xml
4.实体类及Hibernate注解映射
package com.skymr.sphi.model;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name="test_user") //表名public class User { @Id //指定主键 @GeneratedValue private int id; @Column(length=32) private String userName; @Column(length=32) private String password; @Column(length=10) private int age; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } }GeneratedValue:指定Id生成策略,默认是auto,就是@GeneratedValue(strategy = GenerationType.AUTO)
5.junit测试
package com.skymr.sphi.test;import java.sql.SQLException;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.skymr.sphi.model.User;import com.skymr.sphi.service.UserService;public class TestMain { @Test public void saveUserTest() throws SQLException{ ApplicationContext context= new ClassPathXmlApplicationContext("/config/applicationContext.xml"); UserService service =(UserService) context.getBean("userService"); User user = new User(); user.setUserName("111"); user.setPassword("222"); user.setAge(10); service.save(user); } }经过测试,数据库中添加了test_user表,并成功添加一行数据.
6.spring管理Hibernate事务
上面例子中的UserDao类中使用的事务是直接写代码的方式,在session操作的前后进行事务的开始与结束,这里可以使用spring来管理事务了.
在spring_annotation-hibernate.xml配置中加入这段:
transactionAttributes的各种属性的意义如下: PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。 PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。PROPAGATION_REQUIRED,-Exception PROPAGATION_REQUIRED,-Exception PROPAGATION_NEVER PROPAGATION_REQUIRED,-Exception
-Exception表示有Exception抛出时,事务回滚. -代表回滚+就代表提交
readonly 就是read only, 设置操作权限为只读,一般用于查询的方法,优化作用.
经过以上配置后,spring就拦截了hibernate的数据库操作,对操作进行事务管理.
修改UserDao类,去掉代的事务代码
package com.skymr.sphi.dao;import org.hibernate.Session;import org.hibernate.SessionFactory;import com.skymr.sphi.model.User;public class UserDao { private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void save(User user){ System.out.println("执行UserDao save方法:"); Session session = sessionFactory.openSession(); session.save(user); session.close(); } public void update(User user){ System.out.println("执行UserDao update方法:"); Session session = sessionFactory.openSession(); session.update(user); session.close(); } public void delete(int id){ System.out.println("执行UserDao delete方法:"); Session session = sessionFactory.openSession(); session.delete(id); session.close(); } public User query(int id){ System.out.println("执行UserDao query方法:"); Session session = sessionFactory.openSession(); User ret = (User)session.get(User.class, id); session.close(); return ret; }}测试后出现异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in URL [file:/E:/webworkspace/spring_hibernate/WebRoot/WEB-INF/classes/config/spring_annotation-hibernate.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.hibernate.engine.spi.SessionFactoryImplementor.getConnectionProvider()Lorg/hibernate/service/jdbc/connections/spi/ConnectionProvider;
都是照着视频做的,没理由出错啊.
上网查找,发现是spring与hibernate版本不匹配的原因:
原因,在使用Spring3.2.x与Hibernate4.3.x(4.1.7以上)的版本整合时出的错。 解决方案:把Hibernate降至4.1.7或以下的版本就行了。 http://sourceforge.net/projects/hibernate/files/hibernate4/ 这是由Spring和Hibernate4.3.x版本兼容性的问题产生的 它的官方有如下说明: https://jira.springsource.org/browse/SPR-10839 |
7.UserDao调整
Dao层的Bean(UserDao)是个类,没有接口,是不规范的,spring中都要使用接口的,因为spring的底层的代理拦截(AOP原理)必须要有接口,我记得有另一种方法(动态代理)是不用代理的,既然spring这样要求,那就再加入个接口吧
package com.skymr.sphi.dao;import com.skymr.sphi.model.User;public interface UserDao { public void save(User user); public void update(User user); public void delete(int id); public User query(int id);}
package com.skymr.sphi.dao.impl;import javax.annotation.Resource;import org.hibernate.Session;import org.hibernate.SessionFactory;import com.skymr.sphi.dao.UserDao;import com.skymr.sphi.model.User;public class UserDaoBean implements UserDao{ @Resource private SessionFactory sessionFactory; public void save(User user){ System.out.println("执行UserDao save方法:"); Session session = sessionFactory.openSession(); session.save(user); session.close(); } public void update(User user){ System.out.println("执行UserDao update方法:"); Session session = sessionFactory.openSession(); session.update(user); session.close(); } public void delete(int id){ System.out.println("执行UserDao delete方法:"); Session session = sessionFactory.openSession(); session.delete(id); session.close(); } public User query(int id){ System.out.println("执行UserDao query方法:"); Session session = sessionFactory.openSession(); User ret = (User)session.get(User.class, id); session.close(); return ret; }}
转载地址:http://rjihj.baihongyu.com/