文档章节

Spring3.1.1+Hibernate3.6.10整合

yope
 yope
发布于 2015/02/26 16:03
字数 1895
阅读 101
收藏 1

本文通过hibernate注解实现对象映射

一、viewspace-dao.xml配置

 <!-- 扫描com.sunsharing.dao包下所有标注@Repository的DAO组件 -->
    <context:component-scan base-package="com.sunsharing.springdemo.dao"/>
    <!--使用spring提供的PropertyPlaceholderConfigurer读取数据库配置信息.properties-->
    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:jdbc.properties"/>
    </bean>
    <!--数据源配置-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close"
          p:driverClassName="${jdbc.driverClassName}"
          p:url="${jdbc.url}"
          p:username="${jdbc.username}"
          p:password="${jdbc.password}"/>
<!--SessionFactory接口负责初始化Hibernate,是重量级的,一般一个项目只要一个SessionFactory-->
    <bean id="sessionFactory"
          class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="com.sunsharing.springdemo.domain"/>
        <property name="hibernateProperties">
            <props>
                <!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>-->
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.use_query_cache">true</prop>
            </props>
        </property>
    </bean>

    <bean id="hibernateTemplate"
          class="org.springframework.orm.hibernate3.HibernateTemplate"
          p:sessionFactory-ref="sessionFactory" />
    <bean id="jdbcTemplate"
          class="org.springframework.jdbc.core.JdbcTemplate"
          p:dataSource-ref="dataSource"/>

在此配置过程中遇到过两个问题:

1、数据源问题,参看网友的代码案例,引入spring(org.springframework.jdbc.datasource.DriverManagerDataSource) 的数据源,发现destroy-method="close"处报错,经过查证后发现,DriverManagerDataSource数据源不存在这个关闭的方法,后改用BasicDataSource 数据源解决。关于数据源介绍请参看

Spring学习总结3——配置datasource三种方式 ,在此不做累述。

2、maven 中Oracle驱动没有授权问题,不能够引入Oracle的驱动包,解决方法见

在Maven仓库中添加Oracle JDBC驱动(11g)

二、模型层的User POJO

package com.sunsharing.springdemo.domain;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;

/**
 * Created by nyp on 2015/2/5.
 */
@Entity
@SequenceGenerator(name = "USER_ID_SEQUENCE",allocationSize=1,initialValue=1, sequenceName = "USER_ID_SEQUENCE")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "T_USER")
public class User extends BaseDomain {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_ID_SEQUENCE")
    @Column(name="USER_ID")
    private int userId;
    @Column(name="USER_NAME")
    private String userName;
    @Column(name="PASSWORD")
    private String password;
    @Column(name="LAST_IP")
    private String lastIp;
    @Column(name="LAST_VISIT")
    private String lastVisit;
    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    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 String getLastIp() {
        return lastIp;
    }

    public void setLastIp(String lastIp) {
        this.lastIp = lastIp;
    }


    public String getLastVisit() {
        return lastVisit;
    }

    public void setLastVisit(String lastVisit) {
        this.lastVisit = lastVisit;
    }
}

注解的过程中需要注意的是Oracle中的主键生成策略与mysql 有所差别,Oracle需要自己建立序列(sequence的好处主要是在数据库各种情况下,不会生成重复值,保证插入的唯一性)。

1.首先需要在实体类前面申明一个Sequence如下

方法:

@SequenceGenerator(name="SEQ_Name",sequenceName="SEQ_DB_Name") 

参数注意:

SEQ_Name:表示为申明的这个Sequence指定一个名称,以便使用 

SEQ_DB_Name:表示为数据库中的Sequence指定一个名称。两个参数的名称可以一样。

此时主键id的增长是按照hibernate自动处理的方式,而并非数据库中定义的sequence来处理。

必须加allocationSize=1,initialValue=1这两项配置才可以解决上述问题。

2.然后使用@GeneratedValue注解 

方法:@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="SEQ_Name") 

参数:

strategy:固定为GenerationType.SEQUENCE 

Generator:在实体类前面申明的sequnce的名称 

以上这部分就是对Oracle中的序列主键的详细注解说明了。

三、dao层java代码

首先是BaseDao 作为DAO基类

package com.sunsharing.springdemo.dao;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.List;
/**
 * Created by nyp on 2015/2/9.
 */
/**
 * DAO基类,其它DAO可以直接继承这个DAO,不但可以复用共用的方法,还可以获得泛型的好处。
 */
public class BaseDao<T>{
    private Class<T> entityClass;
    @Autowired
    private HibernateTemplate hibernateTemplate;
    // 查询条件
    private String hql;
    /**
     * 通过反射获取子类确定的泛型类
     */
    public BaseDao() {
        Type genType = getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        entityClass = (Class) params[0];
    }

    /**
     * 根据ID加载PO实例
     *
     * @param id
     * @return 返回相应的持久化PO实例
     */
    public T load(Serializable id) {
        return (T) getHibernateTemplate().load(entityClass, id);
    }

    /**
     * 根据ID获取PO实例
     *
     * @param id
     * @return 返回相应的持久化PO实例
     */
    public T get(Serializable id) {
        return (T) getHibernateTemplate().get(entityClass, id);
    }

    /**
     * 获取PO的所有对象
     *
     * @return
     */
    public List<T> loadAll() {
        return getHibernateTemplate().loadAll(entityClass);
    }

    /**
     * 保存PO
     *
     * @param entity
     */
    public void save(T entity) {
        getHibernateTemplate().save(entity);
    }

    /**
     * 删除PO
     *
     * @param entity
     */
    public void remove(T entity) {
        getHibernateTemplate().delete(entity);
    }

    /**
     * 更改PO
     *
     * @param entity
     */
    public void update(T entity) {
        getHibernateTemplate().update(entity);
    }

    /**
     * 执行HQL查询
     *
     * @param sql
     * @return 查询结果
     */
    public List find(String hql) {
        return this.getHibernateTemplate().find(hql);
    }

    /**
     * 执行带参的HQL查询
     *
     * @param sql
     * @param params
     * @return 查询结果
     */
    public List find(String hql, Object... params) {
        return this.getHibernateTemplate().find(hql,params);
    }

    /**
     * 对延迟加载的实体PO执行初始化
     * @param entity
     */
    public void initialize(Object entity) {
        this.getHibernateTemplate().initialize(entity);
    }
    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

   
}

UserDao中java代码

package com.sunsharing.springdemo.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
/**
 * Created by nyp on 2015/2/5.
 */
@Repository
public class UserDao extends BaseDao<User> {
    private final String GET_USER_BY_USERNAME = "from User u where u.userName = ?";
    private final String QUERY_USER_BY_USERNAME = "from User u where u.userName like ?";
//注意上面的User表示的是User对象
    @Autowired
    private JdbcTemplate jdbcTemplate;
    /**
     * 根据用户名查询User对象
     * @param userName 用户名
     * @return 对应userName的User对象,如果不存在,返回null。
     */
    public User getUserByUserName(String userName){
        List<User> users = (List<User>)find(GET_USER_BY_USERNAME,userName);
        if (users.size() == 0) {
            return null;
        }else{
            return users.get(0);
        }
    }

    /**
     * 根据用户名为模糊查询条件,查询出所有前缀匹配的User对象
     * @param userName 用户名查询条件
     * @return 用户名前缀匹配的所有User对象
     */
    public List<User> queryUserByUserName(String userName){
        return (List<User>)find(QUERY_USER_BY_USERNAME,userName+"%");
    }
 

}

四、junit测试代码

package com.sunsharing.springdemo.dao;
import com.sunsharing.springdemo.domain.User;
import com.sunsharing.component.utils.base.DateUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import static org.testng.Assert.*;
/**
 * Created by nyp on 2015/2/5.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/viewspace-dao.xml"})
public class UserDaoTest{
    @Autowired
    private UserDao userDao;
   
   @Test
    public void findALLUserByHibernate() {
        List<User> list = userDao.loadAll();
        System.out.println("list="+list);
        Iterator<User> it=list.iterator();
        while(it.hasNext()){
            User u=it.next();
            System.out.println("name="+u.getUserName());
        }     
    }
   @Test
    public void findUserByIdHibernate() {
       User user= userDao.get(70);
       System.out.println("user:"+user.getUserName());
        assertNotNull(user);
        assertEquals(user.getUserName(), "admin");
    }
   @Test
    public void addUserByHibernate(){
        DateUtils.transFormat(new Date(),"yyyyMMddHHmmss");
        System.out.println("date="+DateUtils.transFormat(new Date(), "yyyyMMddHHmmss"));
        User user=new User();
        user.setUserName("HibernateTest15");
        user.setPassword("123456");
        user.setLastVisit(DateUtils.transFormat(new Date(), "yyyyMMddHHmmss"));
        user.setLastIp("255.255.255.255");
        userDao.save(user);
        assertEquals(user.getPassword(),"123456");
    }

}

在此过程中比较头疼的就是Oracle中的date在hibernate中的映射问题

oracle结合hibernate 时日期类型报

java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
at java.sql.Timestamp.valueOf(Timestamp.java:235)
at oracle.jdbc.driver.CharCommonAccessor.getTimestamp(CharCommonAccessor.java:544)
at oracle.jdbc.driver.T4CCharAccessor.getTimestamp(T4CCharAccessor.java:862)
at oracle.jdbc.driver.OracleResultSetImpl.getTimestamp(OracleResultSetImpl.java:1422)
at oracle.jdbc.driver.OracleResultSet.getTimestamp(OracleResultSet.java:516)
at org.apache.commons.dbcp.DelegatingResultSet.getTimestamp(DelegatingResultSet.java:262)
at org.hibernate.type.descriptor.sql.TimestampTypeDescriptor$2.doExtract(TimestampTypeDescriptor.java:62)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:254)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:250)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:230)
at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:331)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2283)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1527)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1455)
at org.hibernate.loader.Loader.getRow(Loader.java:1355)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:611)
at org.hibernate.loader.Loader.doQuery(Loader.java:829)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.doList(Loader.java:2542)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
at org.hibernate.loader.Loader.list(Loader.java:2271)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
at org.springframework.orm.hibernate3.HibernateTemplate$5.doInHibernate(HibernateTemplate.java:590)
at org.springframework.orm.hibernate3.HibernateTemplate$5.doInHibernate(HibernateTemplate.java:1)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.loadAll(HibernateTemplate.java:584)
at com.sunsharing.springdemo.dao.BaseDao.loadAll(BaseDao.java:56)
at com.sunsharing.springdemo.dao.TesthTest.findUserByHibernate(TesthTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)

注解配置那边有加这些:@Temporal(value = TemporalType.TIMESTAMP)
private Date user_date;(Date引的是java.util.date;oracle 数据库那边用的是char(34))

问题解决:此问题是由POJO中对应Oracle 中的char字段导致,把char改为date 即可。

此为一种解决方法,但结合实际开发,并不一定都这么用。另外一种解决方法为就是数据库中的日期用char,而模型层中对应的属性用String类型即可。(上面给出的源码即为次种解决方案)

最后补充下SQL语句:

CREATE SEQUENCE user_id_sequence
INCREMENT BY 1 -- 每次加几个
START WITH 1 -- 从1开始计数
NOMAXVALUE -- 不设置最大值
NOCYCLE -- 一直累加,不循环
NOCACHE;            
--不缓存
--创建用户表
 CREATE TABLE t_user (
   user_id   NUMBER(6) primary key,
   user_name VARCHAR2(30),
   password  VARCHAR2(32),
   last_visit CHAR(28),
   last_ip  VARCHAR2(23)
);
insert into t_user(USER_ID,U_TYPE,LOGIN_ID,NAME,PWD,DEL,CREATE_TIME,UPDATE_TIME)
 values(USER_ID_SEQUENCE.NEXTVAL,1,'admin','管理员','123456',0,sysdate, sysdate);


© 著作权归作者所有

共有 人打赏支持
yope
粉丝 16
博文 40
码字总数 34264
作品 0
厦门
程序员
私信 提问
snakerflow/snaker-springmvc

Introduction Snaker-SpringMVC项目主要是基于springMVC、spring3、hibernate3、snaker框架整合的一个最基本的流程管理模块,方便大家轻松地完成流程引擎的整合 ###整合步骤 ####1).依赖包整...

snakerflow
2014/11/30
0
0
vSphere 5.5 VM整合磁盘失败之—文件被锁定无法访问

vSphere 5.5 VM整合磁盘失败之—文件被锁定无法访问 环境:vSPhere 5.5u3,虚机使用EMC的networker备份 问题现象:在vc上发现,晚上经过networker的备份之后,虚机提示需要整合磁盘 解决前相...

Makka_Pakka
07/06
0
0
ThinkPHP 常用功能和 SDK 合集--thinkphp-bjyadmin

简介 使用 thinkphp 开发项目的过程中把一些常用的功能或者第三方 sdk 整合好;开源供亲们参考; 这些都是经过线上运营考验的;无毒害可以免费放心折腾使用;只要不会某一天找到我说因为借鉴了...

白俊遥
2017/09/01
1K
2
struts + spring + hibernate 不太理解这种搭配,请指点一下。

struts + spring + hibernate 整合这是到底什么意思嘛?struts 是一个java的web开发框架,spring也是,为什么很多时候总是struts+spring ,是不是把这两个框架整合?如何整合开发? 使用php...

hstaewg
2015/08/29
181
5
白俊遥/thinkphp-bjyadmin

创建 QQ 群及捐赠渠道 链接 博客:http://baijunyao.com github:https://github.com/baijunyao/thinkphp-bjyadmin oschina:http://git.oschina.net/shuaibai123/thinkphp-bjyadmin 简介 使......

白俊遥
2016/06/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

windows上类似dnsmasq的软件Dual DHCP DNS Server

官网地址:http://dhcp-dns-server.sourceforge.net/官网定向的下载地址:https://sourceforge.net/projects/dhcp-dns-server/files/ 设置参考地址:http://blog.51cto.com/zhukeqiang/18264......

xueyuse0012
15分钟前
0
0
LinkedHashMap源码解析

前言 HashMap中的元素时无序的,也就是说遍历HashMap的时候,顺序和放入的顺序是不一样的。 如果需要有序的Map,就可以采用LinkedHashMap. LinkedHashMap通过维护一个包含所有元素的双向链表,...

grace_233
24分钟前
1
0
初识flask

文档 0.10.1版本 http://www.pythondoc.com/flask/index.html 1.0.2版本 https://dormousehole.readthedocs.io/en/latest/ 安装flask $ pip3 install flaskCollecting flask Downloading......

yimingkeji
昨天
2
0
Akka系统《sixteen》译

Actor是一个封装状态(state)和行为(behavior)的对象,它们只通过交换消息通信(放入收件人邮箱的邮件)。从某种意义上说,Actor是最严格的面向对象编程形式,但它更适合将他们视为人:在与Act...

woshixin
昨天
1
0
技术工坊|如何开发一款以太坊钱包(深圳)

【好消息!】HiBlock区块链技术工坊已经成功举办了26期,其中北京1期,西安1期,成都2期,上海22期。经常有社区的小伙伴问定期举办技术工坊的除了上海以外,其他城市有没有?现在区块链技术工...

HiBlock
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部