hibernate之一对一 外键关联 left join

在项目紧急这个节骨眼上,这个问题把我卡了两天。。。

上一个我写的小例子吧

首先,数据库建表。网上搜的好多例子都不带建表的,参考的时候真不知道数据库该怎么设计

create table tuser(
id int primary key,
username varchar(20),
password varchar(20)
)


create table card(
id int primary key ,
userid int,//外键
NO varchar(20)
)

alter table card add constraint cardFk foreign key(userid) references tuser(id)
一个用户对应一张卡片,很简单的业务

这样分析表:card的外键是userid和tuser的id相关联,

实体类User

private int id;
	
	private String userName;
	
	private String password;
	
	private Card card;//关联Card
实体类Card

private int id;
	
	private String NO;
	
	private User user;//关联User,注意,数据库表中userid列并没有出现在Card类参数中
配置文件
User.hbm,xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test2.model">

    <class name="User" table="tuser">
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="identity" />
        </id>
        <property name="userName" column="username"
            length="20" />
        <property name="password" column="password"
            length="20" />
         <one-to-one name="card" class="Card"></one-to-one>//将card配置one-to-one,类是class而不是什么class-ref,配过那个,不成功
        </class>
</hibernate-mapping>
Card.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test2.model">

    <class name="Card" table="card">
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="identity" />
        </id>
        <property name="NO" column="NO"
            length="20" />
       	<many-to-one name="user" column="userid" unique="true"></many-to-one>//表中未写进去实体类的column在这里呢,人家都是别的表的主键了,要加unique哦
        </class>
</hibernate-mapping>
left join语句:

List<User> list = getHibernateTemplate().find("select u from User u left join u.card c where c.user.id is null");
这个hql语句有很大的学问,User实体类中配置了Card参数,因此用到Card的时候要u.card为什么是u.card而不是u.Card呢,因为card在user中的参数名称叫card,小写

这个查询语句如果用sql写应该是  select from tuser left join card on tuser.id = card.userid where card.userid is null

但是hibernate中没有on要把关系写在where中或者直接可以不写,因为你已经在配置文件中配置他们的关系了嘛,它自己知道在哪里做连接

最后c.user.id is null或者c.user is null 都行

开头的 select u 要不要都行


事后更改,上面的hql语句有点问题,查出来的是表中的所有数据,自己又写了个例子,

from JDskuList skuList where skuList.sku not in (select skuState.skuList.sku from JDskuState skuState)

据说纯sql的用in在数据量大的情况下效率很低,不知道hibernate会不会做更好的处理

这个hql等于没有用上左连接

a表主键id,b表aid通过外键与a表id关联,现在找a中id存在b中aid不存在的记录,这个用hibernate的left join 和not null能写出来吗

在纯sql中,left join和not null会效率很低,http://blog.csdn.net/freeeyu/article/details/5804491

另外,因为真正项目中主表的主键是string,一直报org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.test2.model.JDskuState. Expected: class java.lang.Integer, got class java.lang.String,这个问题直接导致辛辛苦苦研究出来的hibernate一对一没有在项目中用上,一个同事帮我把问题解决了,由于hibernate对string的主键不识别,不管你表中配置的是什么类型的,到实体类和配置文件中都不能配置成string。

代码写好测试了下hibernate in的效率,1条数据的话是1s,100条2s,5000条7s,10000条21s,时间会随着条数的增加而增加

hibernate增删改查都会在内存中创建单个的对象,看控制台打印语句也是,查出来多少条就输出几条sql语句:

select jdskulist0_.SKU as SKU0_, jdskulist0_.PAGENUM as PAGENUM0_, jdskulist0_.RECODE_TIME as RECODE3_0_ from JD_SKU_LIST2 jdskulist0_ where jdskulist0_.SKU not in  (select jdskustate1_.SKU from JD_SKU_STATE jdskustate1_)

 select jdskustate0_.id as id1_0_, jdskustate0_.STATE as STATE1_0_, jdskustate0_.UPDATE_TIME as UPDATE3_1_0_, jdskustate0_.SKU as SKU1_0_ from JD_SKU_STATE jdskustate0_ where jdskustate0_.id=?。。。。。

不知道sql not in的原理是什么。。。

综合考虑,我还是没用表关联




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值