前言

本文将基于注解配置, 集成Spring 4和Hibernate 4,开发一个增删改查应用,涉及以下内容:

创建Hibernate实体

保存数据到mysql数据库中

在事务transaction内部执行增删改查操作

典型企业应用中不同层之间的交互

基于注解配置

当然,我们也会给出XML配置作为对比。

涉及的技术及开发工具

Spring 4.0.6.RELEASE

Hibernate Core 4.3.6.Final

MySQL Server 5.6

Joda-time 2.3

Maven 3

JDK 1.6

Eclipse JUNO Service Release 2

工程结构目录

步骤一:往pom.xml中添加依赖

4.0.0

com.websystique.spring

Spring4HibernateExample

1.0.0

jar

Spring4HibernateExample

4.0.6.RELEASE

4.3.6.Final

5.1.31

2.3

org.springframework

spring-core

${springframework.version}

org.springframework

spring-context

${springframework.version}

org.springframework

spring-tx

${springframework.version}

org.springframework

spring-orm

${springframework.version}

org.hibernate

hibernate-core

${hibernate.version}

mysql

mysql-connector-java

${mysql.connector.version}

joda-time

joda-time

${joda-time.version}

org.jadira.usertype

usertype.core

3.0.0.CR1

org.apache.maven.plugins

maven-compiler-plugin

3.2

1.6

1.6

很明显我们需要添加Spring、Hibernate和Mysql连接器相关依赖,另外,由于我们使用了joda-time库来处理时间,所以也引入了joda-time依赖。usertype-core库引入是为了提供数据库时间类型与joda-time LocalDate之间的映射。

步骤二:配置Hibernate

com.websystique.spring.configuration.HibernateConfiguration

packagecom.websystique.spring.configuration;importjava.util.Properties;importjavax.sql.DataSource;importorg.hibernate.SessionFactory;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.PropertySource;importorg.springframework.core.env.Environment;importorg.springframework.jdbc.datasource.DriverManagerDataSource;importorg.springframework.orm.hibernate4.HibernateTransactionManager;importorg.springframework.orm.hibernate4.LocalSessionFactoryBean;importorg.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration

@EnableTransactionManagement

@ComponentScan({"com.websystique.spring.configuration"})

@PropertySource(value= { "classpath:application.properties"})public classHibernateConfiguration {

@AutowiredprivateEnvironment environment;

@BeanpublicLocalSessionFactoryBean sessionFactory() {

LocalSessionFactoryBean sessionFactory= newLocalSessionFactoryBean();

sessionFactory.setDataSource(dataSource());

sessionFactory.setPackagesToScan(new String[] { "com.websystique.spring.model"});

sessionFactory.setHibernateProperties(hibernateProperties());returnsessionFactory;

}

@BeanpublicDataSource dataSource() {

DriverManagerDataSource dataSource= newDriverManagerDataSource();

dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));

dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));

dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));

dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));returndataSource;

}privateProperties hibernateProperties() {

Properties properties= newProperties();

properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));

properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));

properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));returnproperties;

}

@Bean

@AutowiredpublicHibernateTransactionManager transactionManager(SessionFactory s) {

HibernateTransactionManager txManager= newHibernateTransactionManager();

txManager.setSessionFactory(s);returntxManager;

}

}

@Configuration注解表明该类包含了用@Bean标注的方法,这些被@Bean标注的方法可以生成bean并交由spring容器管理,在这里例子中,这个类代表了hibernate的配置。

@ComponentScan注解与xml配置中的“context:component-scan base-package="..."”等价,提供了扫描bean的包路径。

@EnableTransactionManagement注解与xml配置中Spring的tx:*命名空间等价,主要用于开启基于注解的事务管理。

@PropertySource注解用于在Spring运行时Environment中声明一组属性(在应用classpath路径下的properties文件中定义),可根据不同环境灵活改变属性值。

sessionFactory()方法创建了一个LocalSessionFactoryBean,与基于XML的配置类似,我们需要一个数据源dataSource和hibernate配置文件(如hibernate.properties)。

多亏了@PropertySource注解,我们可以从.properties文件中得到具体属性值,使用Spring的Environment接口获取对应项目的配置值。

一旦创建了SessionFactory,该bean将会被注入到transactionManager方法中,最终对sessionFactory创建的sessions提供事务支持功能。

如下是本文使用的属性配置文件:

/src/main/resources/application.properties

jdbc.driverClassName = com.mysql.jdbc.Driver

jdbc.url = jdbc:mysql://localhost:3306/websystique

jdbc.username = myuser

jdbc.password = mypassword

hibernate.dialect = org.hibernate.dialect.MySQLDialect

hibernate.show_sql = false

hibernate.format_sql = false

另外,对应的基于XML配置如下

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

com.websystique.spring.model

${hibernate.dialect}

${hibernate.show_sql:false}

${hibernate.format_sql:false}

步骤三:Spring配置

com.websystique.spring.configuration.AppConfig

packagecom.websystique.spring.configuration;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;

@Configuration

@ComponentScan(basePackages= "com.websystique.spring")public classAppConfig {

}

在我们这个示例中,即使该配置类内部是空的,但是使用了@ComponentScan注解,可以自动检测到对应包下所有的beans。

其实你可以完全去除以上的配置,将bean扫描功能放在application context级别去实现(main方法里)。

在成熟的应用里,你会发现使用配置类配置beans(如messageSource、PropertySourcesPlaceHolderConfigurer...)非常方便。

对应的基于XML的配置

以上就是关于本工程的所有配置了,现在,为了让工程能跑起来,我们还需要添加service、dao层,实体对象,数据库。

步骤四:DAO层

com.websystique.spring.dao.AbstractDao

packagecom.websystique.spring.dao;importorg.hibernate.Session;importorg.hibernate.SessionFactory;importorg.springframework.beans.factory.annotation.Autowired;public abstract classAbstractDao {

@AutowiredprivateSessionFactory sessionFactory;protectedSession getSession() {returnsessionFactory.getCurrentSession();

}public voidpersist(Object entity) {

getSession().persist(entity);

}public voiddelete(Object entity) {

getSession().delete(entity);

}

}

注意,我们在步骤二创建的SessionFactory会被自动装配到这里,这个类将作为基类用于执行数据库相关操作。

com.websystique.spring.dao.EmployeeDao

packagecom.websystique.spring.dao;importjava.util.List;importcom.websystique.spring.model.Employee;public interfaceEmployeeDao {voidsaveEmployee(Employee employee);

ListfindAllEmployees();voiddeleteEmployeeBySsn(String ssn);

Employee findBySsn(String ssn);voidupdateEmployee(Employee employee);

}

com.websystique.spring.dao.EmployeeDaoImpl

packagecom.websystique.spring.dao;importjava.util.List;importorg.hibernate.Criteria;importorg.hibernate.Query;importorg.hibernate.criterion.Restrictions;importorg.springframework.stereotype.Repository;importcom.websystique.spring.model.Employee;

@Repository("employeeDao")public class EmployeeDaoImpl extends AbstractDao implementsEmployeeDao{public voidsaveEmployee(Employee employee) {

persist(employee);

}

@SuppressWarnings("unchecked")public ListfindAllEmployees() {

Criteria criteria= getSession().createCriteria(Employee.class);return (List) criteria.list();

}public voiddeleteEmployeeBySsn(String ssn) {

Query query= getSession().createSQLQuery("delete from Employee where ssn = :ssn");

query.setString("ssn", ssn);

query.executeUpdate();

}publicEmployee findBySsn(String ssn){

Criteria criteria= getSession().createCriteria(Employee.class);

criteria.add(Restrictions.eq("ssn",ssn));return(Employee) criteria.uniqueResult();

}public voidupdateEmployee(Employee employee){

getSession().update(employee);

}

}

步骤五:添加Service层代码

com.websystique.spring.service.EmployeeService

packagecom.websystique.spring.service;importjava.util.List;importcom.websystique.spring.model.Employee;public interfaceEmployeeService {voidsaveEmployee(Employee employee);

ListfindAllEmployees();voiddeleteEmployeeBySsn(String ssn);

Employee findBySsn(String ssn);voidupdateEmployee(Employee employee);

}

com.websystique.spring.service.EmployeeServiceImpl

packagecom.websystique.spring.service;importjava.util.List;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importcom.websystique.spring.dao.EmployeeDao;importcom.websystique.spring.model.Employee;

@Service("employeeService")

@Transactionalpublic class EmployeeServiceImpl implementsEmployeeService{

@AutowiredprivateEmployeeDao dao;public voidsaveEmployee(Employee employee) {

dao.saveEmployee(employee);

}public ListfindAllEmployees() {returndao.findAllEmployees();

}public voiddeleteEmployeeBySsn(String ssn) {

dao.deleteEmployeeBySsn(ssn);

}publicEmployee findBySsn(String ssn) {returndao.findBySsn(ssn);

}public voidupdateEmployee(Employee employee){

dao.updateEmployee(employee);

}

}

以上比较引人注目的部分是@Transactional注解,配置了该注解的类会在每个类方法开启事务,并在方法结束的时候提交事务(或者在方法内部出错时回滚事务)。

注意,由于以上事务范围是方法级别的,我们在方法内部使用DAO,DAO方法会在同样的事物内部执行。

步骤六:创建实体类(POJO)

com.websystique.spring.model.Employee

packagecom.websystique.spring.model;importjava.math.BigDecimal;importjavax.persistence.Column;importjavax.persistence.Entity;importjavax.persistence.GeneratedValue;importjavax.persistence.GenerationType;importjavax.persistence.Id;importjavax.persistence.Table;importorg.hibernate.annotations.Type;importorg.joda.time.LocalDate;

@Entity

@Table(name="EMPLOYEE")public classEmployee {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)private intid;

@Column(name= "NAME", nullable = false)privateString name;

@Column(name= "JOINING_DATE", nullable = false)

@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDate")privateLocalDate joiningDate;

@Column(name= "SALARY", nullable = false)privateBigDecimal salary;

@Column(name= "SSN", unique=true, nullable = false)privateString ssn;public intgetId() {returnid;

}public void setId(intid) {this.id =id;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicLocalDate getJoiningDate() {returnjoiningDate;

}public voidsetJoiningDate(LocalDate joiningDate) {this.joiningDate =joiningDate;

}publicBigDecimal getSalary() {returnsalary;

}public voidsetSalary(BigDecimal salary) {this.salary =salary;

}publicString getSsn() {returnssn;

}public voidsetSsn(String ssn) {this.ssn =ssn;

}

@Overridepublic inthashCode() {final int prime = 31;int result = 1;

result= prime * result +id;

result= prime * result + ((ssn == null) ? 0: ssn.hashCode());returnresult;

}

@Overridepublic booleanequals(Object obj) {if (this ==obj)return true;if (obj == null)return false;if (!(obj instanceofEmployee))return false;

Employee other=(Employee) obj;if (id !=other.id)return false;if (ssn == null) {if (other.ssn != null)return false;

}else if (!ssn.equals(other.ssn))return false;return true;

}

@OverridepublicString toString() {return "Employee [id=" + id + ", name=" + name + ", joiningDate="

+ joiningDate + ", salary=" + salary + ", ssn=" + ssn + "]";

}

}

这是一个标准的实体类,基于JPA注解@Entity, @Table, @Column以及hibernate注解@Type(用于提供数据库类型与Joda-Time LocalDate的映射)。

步骤七:在数据库里创建Schema

CREATE TABLEEMPLOYEE(

idINT NOT NULLauto_increment,

nameVARCHAR(50) NOT NULL,

joining_date DATENOT NULL,

salaryDOUBLE NOT NULL,

ssnVARCHAR(30) NOT NULL UNIQUE,PRIMARY KEY(id)

);

步骤八:创建main方法执行程序

packagecom.websystique.spring;importjava.math.BigDecimal;importjava.util.List;importorg.joda.time.LocalDate;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;importorg.springframework.context.support.AbstractApplicationContext;importcom.websystique.spring.configuration.AppConfig;importcom.websystique.spring.model.Employee;importcom.websystique.spring.service.EmployeeService;public classAppMain {public static voidmain(String args[]) {

AbstractApplicationContext context= new AnnotationConfigApplicationContext(AppConfig.class);

EmployeeService service= (EmployeeService) context.getBean("employeeService");/** Create Employee1*/Employee employee1= newEmployee();

employee1.setName("Han Yenn");

employee1.setJoiningDate(new LocalDate(2010, 10, 10));

employee1.setSalary(new BigDecimal(10000));

employee1.setSsn("ssn00000001");/** Create Employee2*/Employee employee2= newEmployee();

employee2.setName("Dan Thomas");

employee2.setJoiningDate(new LocalDate(2012, 11, 11));

employee2.setSalary(new BigDecimal(20000));

employee2.setSsn("ssn00000002");/** Persist both Employees*/service.saveEmployee(employee1);

service.saveEmployee(employee2);/** Get all employees list from database*/List employees =service.findAllEmployees();for(Employee emp : employees) {

System.out.println(emp);

}/** delete an employee*/service.deleteEmployeeBySsn("ssn00000002");/** update an employee*/Employee employee= service.findBySsn("ssn00000001");

employee.setSalary(new BigDecimal(50000));

service.updateEmployee(employee);/** Get all employees list from database*/List employeeList =service.findAllEmployees();for(Employee emp : employeeList) {

System.out.println(emp);

}

context.close();

}

}

注意,假如你想删除AppConfig文件,那么只需将

AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

替换为

hibernate mysql 注解_【译】Spring 4 + Hibernate 4 + Mysql + Maven集成例子(注解 + XML)相关推荐

  1. java+spring+mysql配置_用spring的beans配置mysql数据库

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www. ...

  2. springboot mysql事物_在Spring Boot中使用数据库事务

    关于数据库访问还有一个核心操作那就是事务的处理了,前面两篇博客小伙伴们已经见识到Spring Boot带给我们的巨大便利了,其实不用猜,我们也知道Spring Boot在数据库事务处理问题上也给我们带 ...

  3. spring使用自定义注解_用Spring组成自定义注释

    spring使用自定义注解 Java批注在2004年随Java 5一起引入,是一种将元数据添加到Java源代码中的方法. 如今,许多主要框架(如Spring或Hibernate)都严重依赖注释. 在本 ...

  4. @autowired注解_品Spring:对@Autowired和@Value注解的处理方法(文末附spring系列资源合集)...

    作者:编程新说李新杰 出自:微信公众号"编程新说" 原文:品Spring:对@Autowired和@Value注解的处理方法 在Spring中能够完成依赖注入的注解有JavaSE提 ...

  5. jpa执行mysql存储过程_基于Spring Boot,使用JPA调用Sql Server数据库的存储过程并返回记录集合...

    那么,有些情况,会把一些查询语句写在存储过程中,由存储过程来返回记录集. 在这里就先通过EntityManager创建命名存储过程的方法完成调用. 1.创建SQL存储过程 存储过程返回所有的联系人. ...

  6. @jsonfield注解_好了,不装了,撸个注解有什么难的!

    文章来源:https://mp.weixin.qq.com/s/z8qA8i3F8-SDbcTDMdJgjw 作者:沉默王二 注解是 Java 中非常重要的一部分,但经常被忽视也是真的.之所以这么说是 ...

  7. spring批量写入mysql数据库_MyBatis-spring和spring JDBC批量插入Mysql的效率比较

    工具框架用spring-batch,数据库是mysql(未做特殊优化). 比较数据框架mybatis和spring jdbc的插入效率. Mybatis三种实现: 1.mybatis的官方写法 Jav ...

  8. 如何在linux系统下修改mysql密码_如何在linux下修改mysql数据库密码?linux修改数据库密码的方法...

    本篇文章给大家带来的内容是介绍如何在linux下修改mysql数据库密码?linux修改数据库密码的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助. Linux下修改Mysql的 ...

  9. linux上部署mysql服务_在Linux环境下部署MySql服务

    之前有下载部署过几次,但是每次都会踩一些坑.特此记录在liunx下部署安装mysql的基本步骤: 1.卸载老版本的mysql find / -name mysql|xargs rm -rf     查 ...

最新文章

  1. 数平精准推荐 | OCR技术之数据篇
  2. CRM WebClient UI的external service功能介绍
  3. 译 | 在 Azure SQL 上节约成本的八种方法
  4. 红帽436——HA高可用集群之概念篇
  5. python调用shell脚本
  6. 浮栅场效应管 符号_MOS场效应管
  7. 开发Adobe AIR移动应用程序的考虑事项
  8. html禁用选择,html – 设置可选的禁用属性
  9. 云呐-工单管理制度及流程,工单管理规范
  10. OpenGL学习(七)通过assimp库读取多种格式的模型
  11. python人脸比对算法_python实现人脸识别经典算法(一) 特征脸法
  12. 单位球坐标变换为椭球 matlab
  13. 2022最新批量删除微博教程!支持批量删除微博批量删除清空点赞关注评价以及粉丝
  14. java抓取百度搜索结果,一个百度搜索结果内容获取爬虫
  15. 安全威胁分类STRIDE
  16. java-net-php-python-jspm人力外包服务公司招聘管理系统计算机毕业设计程序
  17. NBU备份之效率提升
  18. 瑞星宣布个人安全软件产品永久免费
  19. 获取多个字符串公共的前缀部分
  20. 【python】端调用cmd命令

热门文章

  1. 【Elasticsearch】Meltdown对Elasticsearch性能的影响
  2. 95-847-040-源码-Netty-netty在Flink运行时的简介
  3. 【Java】java JMX之ObjectName
  4. 83-spark2.2的DataFrame使用以及以前版本SqlContext的隐式引用
  5. SpringBoot项目整合Retrofit最佳实践,这才是最优雅的HTTP客户端工具!
  6. 最详细的 Spring Boot 多模块开发与排坑指南
  7. 感觉Swagger功能不够强大?knife4j这款神器了解一下....
  8. StringHelper--封转自己的字符串工具类
  9. C# WinForm开发系列 - 开篇
  10. linux canopen软件,CANopen学习笔记