不想说什么,都是多余的.
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的查询过程中锁定数据.