在实际项目中,我们一般会使用面向接口编程,从而实现调用者和被调用者的完全解耦,方便项目的团队开发和后期的扩展。鉴于这样的考虑,关于Hibernate的持久层的实现,分两步进行:第一步定义公共接口和类,第二步基于Hibernate实现接口,详细介绍如下:
第一步:定义公共DAO接口和类
1、创建一个普通的Maven工程:MvnBookSSHDemo.DAO。目录结构如下:
pom.xml也没有太特别的,内容如下:
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2、编写公共接口和代码
在这里有两类代码,一类是实体类(MvnUser),另一类是实体DAO接口(IMvnUserDAO)。因为MvnUser里面有个状态(status)属性,配合它,定义了一个枚举状态类(Status)。具体代码如下:
Status.java
package cn.com.mvnbook.ssh.demo.entity;
public enum Status {
ACTIVE("Active"),
INACTIVE("Inactive"),
DELETED("Deleted"),
LOCKED("Locked");
private String status;
private Status(final String status){
this.status = status;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String toString(){
return this.status;
}
}
MvnUser.java
package cn.com.mvnbook.ssh.demo.entity;
public class MvnUser {
private int urId;
private String urUserName;
private String urPassword;
private int urAge;
private String urStatus = Status.ACTIVE.getStatus();//Active
public int getUrId() {
return urId;
}
public void setUrId(int urId) {
this.urId = urId;
}
public String getUrUserName() {
return urUserName;
}
public void setUrUserName(String urUserName) {
this.urUserName = urUserName;
}
public String getUrPassword() {
return urPassword;
}
public void setUrPassword(String urPassword) {
this.urPassword = urPassword;
}
public int getUrAge() {
return urAge;
}
public void setUrAge(int urAge) {
this.urAge = urAge;
}
public String getUrStatus() {
return urStatus;
}
public void setUrStatus(String urStatus) {
this.urStatus = urStatus;
}
}
IMvnUserDAO.java
package cn.com.mvnbook.ssh.demo.dao;
import java.util.List;
import cn.com.mvnbook.ssh.demo.entity.MvnUser;
/**
* MvnUser实体对象的持久层代码,封装了对MvnUser实体对象的CRUD方法
*
* @author Noble
* @version 1.0
* */
public interface IMvnUserDAO {
/**
* 在数据库中,添加一个新的MvnUser对象
*
* @param user 需要添加的用户实体对象,该对象需要有用户名、密码、年龄和状态属性
*
* @return void
* @throws RuntimeException 添加失败或出现其它意外
* */
public void addUser(MvnUser user) ;
/**
* 更新MvnUser对象。该对象中需要设置年龄、状态和id属性,属性和状态是要更新的新值,id为条件
*
* @param user 需要更新的MvnUser对象
*
* @return void
* @throws RuntimeException 更新失败或出现其它意外
* */
public void update(MvnUser user) ;
/**
* 删除MvnUser对象,该对象中需要有要删除对象的id属性,id属性为删除条件
*
* @param user 要删除的MvnUser对象
*
* @return void
* @throws RuntimeException 删除失败或出现其它意外
* */
public void deleteUser(MvnUser user) ;
/**
* 根据id查询对应的MvnUser对象
*
* @param id 要查询的MvnUser对象的id
* @return MvnUser id对应的MvnUser对象,如果没有对象,返回null
* @throws RuntimeException 出现意外情况
* */
public MvnUser findUserById(int id) ;
/**
* 根据用户名查询对应的MvnUser对象
*
* @param userName 要查询的MvnUser对象的用户名
* @return MvnUser 用户对应的MvnUser对象,如果没有对象,返回null
* @throws RuntimeException 出现意外情况
* */
public MvnUser findUserByUserName(String userName) ;
/**
* 查找数据库中所有的用户对象,以List集合的形式返回
*
* @return List
* @throws RuntimeException 出现意外情况
* */
public List
}
3、安装发布
在工程上鼠标右键 Run As->Maven install,Eclipse会自动将工程代码编译打包,如果没有错误的话,最后以构件的形式,安装在本地仓库中。参考效果图如下:
为了方便公司其它开发人员可以使用,我们接下来将该项目以构件的形式,发布到前面搭建好的私服上去,为了发布成功,请按前面的私服介绍,搭建并且启动私服,同时在当前工程的pom.xml中,添加distributionManagement配置,详细参考前面的pom.xml。具体操作和效果图如下。
1)操作
工程右键选择Run As -> Maven build...
在Goals中输入deploy,点击Run按钮
2)Archiva上关于发布的构件效果图
第二步:基于Hibernate完成DAO接口的实现
团队商量确定好接口,接下来就是对接口的实现和基于接口上的开发工作了。因为有共同的接口,所以这两个工作可以同步进行。这现象同我们现实生活中的电脑的配件一样(硬盘、内存条、CPU、显卡等等),事先定义好标准(插口),不同厂商就可以按同样的标准各自生产,出来后就可以顺利的组装在一起,不用管有哪个厂家,在哪里,用那个流水线生产的。
接下来我们开始研究DAO接口的实现。大概分如下四步进行:
第一步:创建工程,添加相关依赖
这个步骤比较简单,创建工程的方式同以前一样。具体创建的过程,在这里就不重复了。目录结构如下:
虽然不重复说明项目的创建过程,但是要注意如下两点:
1、因为前面我们有创建了公共的Hibernate POM工程,里面有描述好了Hibernate相关的依赖(目的是让所有开发人员重用,不要自己再重复编写),并且有以构件的形式安装发布好了。这里我们要体现的是怎么样继承前面定义好的pom。
2、同样的,因为我们新工程里面要实现MvnBookSSHDemo.DAO中定义的接口,并且使用到它里面定义的公共类,而且根据前面的介绍,MvnBookSSHDemo.DAO,我们也以构件的形式安装发布到私服了。在这里,我们要体现一下怎么样在自己的工程里面,设置我们团队内部自己发布的构件。
这两点注意事项,主要体现在pom.xml中,pom.xml内容如下:
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
说明:
1、
这是pom.xml中的第一个粗体内容,它描述的是当前的pom.xml,继承了Hibernate4MySQLPOM构件中定义的pom内容,其中groupId,artifactId和version共同形成构件的坐标。当我们的pom需要继承别人定义好的pom的话,只需要使用如上parent配置指定就行,不过这里的继承,同java中继承一样,只能单继承,而且只能继承packaging类型为pom的构件(这点可以看Hibernate4MySQLPOM中的pom.xml文件,里面的packaging是pom)。
2、
这是在我们pom.xml中第二个粗体内容,描述的是两个依赖。第一个依赖是我们前面定义的DAO接口和公共类的构件依赖,通过查看代码,其实同使用我们从网上找的其它依赖一样。第二个虽然也是使用的我们前面定义的spring的公共pom依赖,但是有点点不同,里面包含了一个
第二步:编写实现代码
基于Hibernate的DAO实现代码,主要有如下几个类:
MvnUser4Hibernate.java 该类继承MvnUser类,里面用注解描述了实体信息
AbstractDAO.java 该类定义了实体的公共持久化方法,所有的DAO实现类就继承它
MvnUserDAOImpl.java 该类实现MvnUser实体类的所有持久化方法
HibernateConfiguration.java Hibernate的配置类,描述Hibernate的配置信息,代替
hibernate.cfg.xml
db.properties 描述数据库连接信息和hibernate的一些配置信息
各个代码如下:
MvnUser4Hibernate.java
package cn.com.mvnbook.ssh.demo.entity.hibernate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import cn.com.mvnbook.ssh.demo.entity.MvnUser;
@Entity
@Table(catalog="mvn_db",name="mvn_user")
public class MvnUser4Hibernate extends MvnUser {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ur_id")
public int getUrId() {
// TODO Auto-generated method stub
return super.getUrId();
}
@Column(name="ur_user_name",length=20,unique=true,nullable=false)
public String getUrUserName() {
// TODO Auto-generated method stub
return super.getUrUserName();
}
@Column(name="ur_password",length=10,nullable=false)
public String getUrPassword() {
// TODO Auto-generated method stub
return super.getUrPassword();
}
@Column(name="ur_age")
public int getUrAge() {
// TODO Auto-generated method stub
return super.getUrAge();
}
@Column(name="ur_status",length=20,nullable=true)
public String getUrStatus() {
// TODO Auto-generated method stub
return super.getUrStatus();
}
}
AbstractDAO.java
package cn.com.mvnbook.ssh.demo.dao.hibernate;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import cn.com.mvnbook.ssh.demo.entity.MvnUser;
import cn.com.mvnbook.ssh.demo.entity.hibernate.MvnUser4Hibernate;
public abstract class AbstractDAO
private final Class
@SuppressWarnings("unchecked")
public AbstractDAO(){
this.persistentClass =(Class
(ParameterizedType) this.getClass().getGenericSuperclass()
).getActualTypeArguments()[1];
}
@Autowired
private SessionFactory sessionFactory;
protected Session getSession(){
return sessionFactory.getCurrentSession();
}
@SuppressWarnings("unchecked")
public T getByKey(PK key) {
return (T) getSession().get(persistentClass, key);
}
public void persist(T entity) {
getSession().persist(entity);
}
public void delete(T entity) {
getSession().delete(entity);
}
public void update(T entity){
getSession().merge(entity);
}
public List
Criteria cri = this.createEntityCriteria();
cri.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);//消除重复对象
return cri.list();
}
protected Criteria createEntityCriteria(){
return getSession().createCriteria(persistentClass);
}
}
MvnUserDAOImpl.java
package cn.com.mvnbook.ssh.demo.dao.hibernate.impl;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import cn.com.mvnbook.ssh.demo.dao.IMvnUserDAO;
import cn.com.mvnbook.ssh.demo.dao.hibernate.AbstractDAO;
import cn.com.mvnbook.ssh.demo.entity.MvnUser;
import cn.com.mvnbook.ssh.demo.entity.hibernate.MvnUser4Hibernate;
@Repository("userDAO")
@Transactional// 标记使用事务,为了方便DAO设置,是临时的,正式事务应该设置在服务层
public class MvnUserDAOImpl extends AbstractDAO
public void addUser(MvnUser user) {
MvnUser4Hibernate u = this.convertToMvnUser4Hibernate(user);
super.persist(u);
}
public void update(MvnUser user) {
MvnUser4Hibernate u = this.convertToMvnUser4Hibernate(user);
super.update(u);
}
public void deleteUser(MvnUser user) {
MvnUser4Hibernate u = this.convertToMvnUser4Hibernate(user);
super.delete(u);
}
public MvnUser findUserById(int id) {
return super.getByKey(id);
}
public MvnUser findUserByUserName(String userName) {
Criteria criteria = super.createEntityCriteria();
criteria.add(Restrictions.eq("urUserName", userName));
return (MvnUser)criteria.uniqueResult();
}
public List
Criteria criteria = super.createEntityCriteria();
return criteria.list();
}
private MvnUser4Hibernate convertToMvnUser4Hibernate(MvnUser user){
MvnUser4Hibernate u = (MvnUser4Hibernate) this.findUserById(user.getUrId());
// 这里不要轻易new一个同已经存在的一样的对象,否则会抛
//org.hibernate.NonUniqueObjectException:
//a different object with the same identifier value was
//already associated withthe session异常
if (u == null) {
u = new MvnUser4Hibernate();
u.setUrId(user.getUrId());
}
u.setUrAge(user.getUrAge());
u.setUrPassword(user.getUrPassword());
u.setUrStatus(user.getUrStatus());
u.setUrUserName(user.getUrUserName());
return u;
}
}
HibernateConfiguration.java
package cn.com.mvnbook.ssh.demo.dao.hibernate.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//配置类
@Configuration
@EnableTransactionManagement// 要支持事务管理
@ComponentScan({ "cn.com.mvnbook.ssh.demo.dao.hibernate.config" })
@PropertySource(value = { "classpath:db.properties" })// 自动读入的属性文件
public class HibernateConfiguration {
// 自动注入 Spring的环境对象(上下文)
@Autowired
private Environment environment;
// 创建一个SessionFactory
@Bean(name="sessionFactory")
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
// 数据源
sessionFactory.setDataSource(dataSource());
// 指定数据实体类的包
sessionFactory.setPackagesToScan(new String[]
{ "cn.com.mvnbook.ssh.demo.entity.hibernate" });
// hibernate的属性信息
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
// 初始化数据源对象
@Bean(name="dataSource")// 将当前方法返回的对象,当成普通Bean对象,放入IOC容器中
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
// 设置连接数据库的四要素
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
// 将Hibernate除连接数据库之外的配置,封装到Properties
private Properties hibernateProperties() {
Properties properties = new Properties();
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"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
return properties;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
}
db.properties(存放在工程的 src/main/resources目录下)
jdbc.username=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/mvn_db
jdbc.driverClassName=com.mysql.jdbc.Driver
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.show_sql = true
hibernate.format_sql = true
hibernate.hbm2ddl.auto = update
第三步:编写测试代码
测试代码是基于jUnit的,相对比较简单,只有一个类,针对MvnUserDAOImpl.java进行测试,另外有一个spring的配置文件,applicationContext.xml。
需要注意的是,测试的所有代码和资源文件,都是分别放在src/test目录下对应的子目录中的,参考前面提供的工程目录结构图。在Maven中具体文件的存放位置,是有固定约束的(规定死了的)。测试代码和配置文件的内容如下:
TestMvnUserDAOImpl.java
package cn.com.mvnbook.ssh.demo.dao.hibernate.impl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.com.mvnbook.ssh.demo.dao.IMvnUserDAO;
import cn.com.mvnbook.ssh.demo.entity.MvnUser;
import cn.com.mvnbook.ssh.demo.entity.Status;
import junit.framework.Assert;
public class TestMvnUserDAOImpl {
private IMvnUserDAO userDAO;
private ApplicationContext ctx = null;
@Before
public void init() {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
userDAO = (IMvnUserDAO)this.ctx.getBean("userDAO");
//userDAO = (IMvnUserDAO) this.ctx.getBean(MvnUserDAOImpl.class);
}
@Test
public void testAddUser(){
MvnUser user= new MvnUser();
user.setUrAge(11);
user.setUrPassword("11");
user.setUrStatus(Status.ACTIVE.getStatus());
user.setUrUserName("userName11");
this.userDAO.addUser(user);
MvnUser u = this.userDAO.findUserByUserName("userName11");
Assert.assertTrue(u != null && u.getUrAge()==11);
this.userDAO.deleteUser(u);
}
@Test
public void testFindUserById(){
MvnUser user = this.userDAO.findUserById(1);
Assert.assertEquals("zhangsan", user.getUrUserName());
}
@Test
public void testUpdate(){
MvnUser user = this.userDAO.findUserById(1);
user.setUrAge(99);
this.userDAO.update(user);
user = this.userDAO.findUserById(1);
Assert.assertEquals(99, user.getUrAge());
}
@After
public void destory(){
this.userDAO = null;
this.ctx = null;
}
}
applicationContext.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context " >http://www.springframework.org/schema/context/spring-context-4.0.xsd"> base-package="cn.com.mvnbook.ssh.demo">
第四步:测试安装发布
测试:
鼠标右击工程 Run As->Maven test
Maven自动会对jUnit写的测试代码进行测试,并且显示测试结果,如图:
安装:
鼠标右击工程 Run As ->Maven install
Maven会自动将工程代码编译,运行完测试代码,所有通过后,打包成构件,发布到本地仓库。结果如图:
发布:
鼠标右击工程 Run As -> Maven build...
在弹出框的Goals输入框中输入deploy,点击Run按钮,Maven会自动将工程构件,发布到指定的私服仓库中,效果图如下显示,但是要注意,一定要在pom.xml中配置distributionManagement,指定发布的位置。
版权所有,转载请注明。 同类视频请参考 http://cyedu.ke.qq.com