设计的时候不一定设置具体的关联关系,也可以手动维护关联关系。在公司里开发很多时候不设置关联,基本都是单表操作。一个表拆分成为多个表。(垂直分割)
多对一
第一步:数据库设计
图书信息表
CREATE TABLE t_book_info
(
book_id
bigint(20) NOT NULL AUTO_INCREMENT,
book_name
varchar(255) DEFAULT NULL,
book_author
varchar(255) DEFAULT NULL,
book_price
double(10,2) DEFAULT NULL,
book_date
timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
book_publish
varchar(255) DEFAULT NULL,
book_desc
varchar(255) DEFAULT NULL,
type_id
bigint(20) DEFAULT NULL,
PRIMARY KEY (book_id
),
KEY type_id
(type_id
),
CONSTRAINT type_id
FOREIGN KEY (type_id
) REFERENCES t_book_type
(type_id
) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
图书分类表
CREATE TABLE t_book_type
(
type_id
bigint(20) NOT NULL AUTO_INCREMENT,
type_name
varchar(100) DEFAULT NULL,
type_desc
varchar(255) DEFAULT NULL,
PRIMARY KEY (type_id
)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
关联:
虽然这里设置了级联删除以及级联更新,但是工作中不操作。
如下图所示 需要修改级联个更新的参数

注意 :
工作中时间字段处理方案?long,Date,页面交互部分String。
第二步:使用插件生成映射文件和实体类
生成的时候需要重点关注关联的部分。
Idea逆向工程时,勾选关联对象关系,不勾选单个关联字段。别忘记在核心配置文件中注册实体。
勾选显示关联关系的复选框:

勾选关联的对象关系,但是不勾选关联的具体字段。



修改生成的内容:
主键策略手动加


观察 BookInfo表的配置文件里面 many-to-one
<many-to-one name="bookTypeByTypeId" class="com.zyh.pojo.BookType" fetch="select" lazy="false">
<column name="type_id" />
</many-to-one>
观察 BookType表里面的配置文件: set 以及 one-to-many
<set name="bookInfosByTypeId" cascade="all" inverse="false" lazy="false">
<key>
<column name="type_id" />
</key>
<one-to-many not-found="ignore" class="com.zyh.pojo.BookInfo" />
</set>
生成的ORM映射文件必须注册。
第三步:创建核心配置文件
注意加入编码支持。
含注册实体:
配置文件如下所示:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/testmybatis01?characterEncoding=utf-8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">zyh</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL55Dialect</property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<!-- 注册实体 -->
<mapping resource="com/zyh/pojo/TUserInfo.hbm.xml"></mapping>
<mapping resource="com/zyh/pojo/BookInfo.hbm.xml"></mapping>
<mapping resource="com/zyh/pojo/BookType.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
第四步:开发DAO测试
获取关联多对一的对象信息:
/**
* 下面演示多对一的查询
*/
public BookInfo findById(Long bookId){
Session session = HibernateUtils.getSession();
BookInfo bookInfo = session.get(BookInfo.class, bookId);
/**
* 这里不能关闭 打开注释会发现报错了 报错列表如下所示:
*/
session.close();
return bookInfo;
}
@Test
public void testBookInfoList(){
BookInfo byId = findById(7L);
System.out.println(byId.getBookAuthor());
BookType bookTypeByTypeId = byId.getBookTypeByTypeId();
System.out.println(bookTypeByTypeId.getTypeName());
}
打印关联信息出现异常:(Bug积累)

默认方式session关闭后输出打印关联表信息会失败。因为默认延迟检索。
因为使用了延迟检索,会延迟到使用关联表BookType的具体属性的时候,才找DB发送SQL语句查询记录。但是这个时候我们已经关闭了session,所以不能发送SQL语句了。
关联表的信息默认是延迟加载。还有一种检索方式是立即检索?
默认使用延迟检索关联表的信息没有加载,解决方案:
方案一:session不关闭:

方案二:session关闭之前获取关联表的信息:

方案三:使用立即检索
多对一添加:
注意:关联字段是对象
/**
* 下面演示多对一的添加 这里面有个问题
* 为什么不能 新建一个 BookType
* 新建几个 BookInfo 并且将此类型加入
* 输出结果为什么报错 如果想实现这个结果必须用 一对多
*/
@Test
public void testAddBookInfo(){
Session session = HibernateUtils.getCuurentSession();
Transaction transaction = session.beginTransaction();
BookInfo bookInfo=new BookInfo();
/* BookType byIdThrough = findByIdThrough(2L);*/
BookType bookType=new BookType();
bookType.setTypeId(5L);
bookType.setTypeName("不知道啥类型");
bookType.setTypeDesc("不知道什么描述");
bookInfo.setBookName("傻逼书");
bookInfo.setBookAuthor("xx");
bookInfo.setBookDate(new Date().getTime());
bookInfo.setBookDesc("这是一个描述");
bookInfo.setBookPrice(10000.01);
bookInfo.setBookPublish("中国出版社");
bookInfo.setBookTypeByTypeId(bookType);
session.save(bookInfo);
transaction.commit();
}
网友评论