(5)Hibernate中的many-to-many和并发

不想说什么,都是多余的.

 

 

Hibernate 因为中间涉及到数据库的操作,事务同步这些就是必须的.

1 Hibernate 中many-to-many 的相关操作.

2 Hibernate 中的数据隔离,Hibernate 中的乐观锁,悲观锁

3 HQL和SQL 的命名查询.

 

UserBO.hbm.xml如下:

<!-- dynamic-update="true" optimistic-lock="dirty" -->
<class name="com.isw2.bo.UserBO" table="t_user"
	catalog="many_to_many" lazy="true">
	<id name="userId" column="userId">
		<generator class="native"></generator>
	</id>
	<version name="version" column="version"></version>
        <!-- 时间戳最小时间1s 在此间发生的更改无法识别 -->
       	<!--  <timestamp name="" column=""></timestamp> -->
        <property name="userName" length="32" type="string"
		column="userName">
	</property>
	<!-- t_user_role_info 为中间表 -->
	<set name="roles" lazy="true" table="t_user_role_info" cascade="all" inverse="false">
		<key column="userId"></key>
		<many-to-many column="roleId" class="com.isw2.bo.RoleBO"></many-to-many>
	</set>
</class>
<!-- HQL 查询语句 -->
<query name="findUserBO">
		<![CDATA[from UserBO]]>
</query>
<!-- SQL查询语句,组装成对象 UserBO 放入 List -->
<sql-query name="findUserBOBySQL">
		<![CDATA[select userId {u.userId},userName {u.userName},version {u.version} from t_user]]>
		<return alias="u" class="com.isw2.bo.UserBO"></return>
</sql-query

 RoleBO.hbm.xml如下:

<class name="com.isw2.bo.RoleBO" table="t_role" catalog="many_to_many" lazy="true">
	<id name="roleId" column="roleId">
		<generator class="native"></generator>
	</id>

        <version name="version" column="version"></version>
 	<property name="roleName" column="roleName" type="string"
		length="32">
	</property>
	<set name="users" lazy="true" table="t_user_role_info" cascade="all" inverse="true">
		<key column="roleId"></key>
		<many-to-many class="com.isw2.bo.UserBO" column="userId"></many-to-many>
	</set>
</class>

 hibernate.cfg.xml如下:

<session-factory>
	<property name="connection.username">root</property>
	<property name="connection.url">
		jdbc:mysql://127.0.0.1:3306/many_to_many
	</property>
	<property name="dialect">
		org.hibernate.dialect.MySQLDialect
	</property>
	<property name="myeclipse.connection.profile">MySQL</property>
	<property name="connection.password">123456</property>
	<property name="connection.driver_class">
		com.mysql.jdbc.Driver
	</property>
	<property name="show_sql">true</property>
	<!-- 设置全局隔离级别 -->
	<!-- 
		1读未提交级别(可能会脏读)
		2读已提交级别(不可重复读)
		4可重复读级别(幻读)
		8可串行化级别(死锁)
	-->
	<property name="hibernate.connection.isolation ">4</property>

	<mapping resource="com/isw2/bo/RoleBO.hbm.xml" />
	<mapping resource="com/isw2/bo/UserBO.hbm.xml" />

</session-factory>
 

相关的查询操作:

/**
 * 使用命名HQL查询
 */
public void findByHQL() {
	Session session = HibernateSessionFactory.getSession();
	Query query = session.getNamedQuery("findUserBO");
	List list = query.list();
	for (Object object : list) {
		System.out.println(object);
	}
	session.close();
}

/**
 * 使用命名SQL 查询
 */
public void findBySQL() {
	Session session = HibernateSessionFactory.getSession();
	// SQLQuery query = session.createSQLQuery("select userId
	// {ub.userId},userName {ub.userName} from t_user");
	// query.addEntity("ub",UserBO.class);
	Query query = session.getNamedQuery("findUserBOBySQL");
	List list = query.list();
	for (Object object : list) {
		System.out.println(object);
	}
	session.close();
}

/**
 * 查询中使用悲观锁
 */
public void findLock() {
	Session session = HibernateSessionFactory.getSession();
	/**
	 * Hibernate: select userbo0_.userId as userId2_0_, userbo0_.version as
	 * version2_0_, userbo0_.userName as userName2_0_ from
	 * many_to_many.t_user userbo0_ where userbo0_.userId=?  for update  因为
	 * 悲观锁LockMode.UPGRADE 查询语句通过 for update被锁定
	 */
	// UserBO userBO = (UserBO) session.load(UserBO.class, new Long(24),
	// LockMode.UPGRADE);
	// System.out.println(userBO);
	Query query = session.createQuery("select ub from UserBO ub");
	query.setLockMode("ub", LockMode.UPGRADE);
	List list = query.list();
	for (Object object : list) {
		System.out.println(object);
	}
	session.close();
}

 1 在many-to-many 中要注意的是 cascade , inverse 它们分别指出有哪些关系需要维护,这些关系由谁来维护.

在这里有一张中间表"t_user_role_info" 用于存放many-to-many 关系.

 

2 关于数据隔离。

<!-- 设置全局隔离级别 -->
		<!-- 
			1读未提交级别(可能会脏读)
			2读已提交级别(不可重复读)
			4可重复读级别(幻读)
			8可串行化级别(死锁)
		-->
		<property name="hibernate.connection.isolation ">4</property>

 这里可串行化级别,隔离性能最好,但易死锁,而且很消耗数据库性能。建议使用4

 

3 关于乐观锁. 它有三种方式version(标注版本),timestamp(时间戳,1s 内的变更无法识别),这两个都需要数据库及对象中有相关字段支持。dynamic-update="true" optimistic-lock="dirty"  通过对比更新前字段值判断是否被更改。

 

4 悲观锁。乐观锁假设数据不会被更改,而悲观锁则相反。它会利用数据库的锁机制实现。比如:

select userbo0_.userId as userId2_0_ ....for update

 即在MySQL的查询过程中锁定数据.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值