Jimoshi成长经历:前面的笔记后面再慢慢整理-------方便自己
目录:正向开发、逆向开发、悲观锁和乐观锁、session中对象的4种状态
Hibernate 框架学习(三):
一、正向开发(先根据数据库设计建立实体类,然后进行数据库表设计)
例子:用户( uid,name,rid),角色(rid,rname ),功能(fid,fname),角色_ 功能(rid,fid)
描述:一个用户有一个角色,一个角色对应多个功能,一个功能对应多个角色
(用户与角色之间一对一关系,角色与功能之间多对多的关系)
代码示例(注解配置):
1、建立对应实体User类、Role类、Func类对象
User实体类的建立,
@Entity
@Table(name="t_user")
public class User {
private int uid;
private String uname;
private Role role;
@Id
@GeneratedValue
public int getUid() { return uid; }
public void setUid(int uid) { this.uid = uid; }
public String getUname() { return uname; }
public void setUname(String uname) { this.uname = uname; }
@ManyToOne
public Role getRole() { return role; }
public void setRole(Role role) { this.role = role;}
}
Role实体类的建立,
@Entity
@Table(name="t_role")
public class Role {
private int rid;
private String rname;
private Set<Func> funcs;
@Id
@GeneratedValue
public int getRid() { return rid; }
public void setRid(int rid) { this.rid = rid; }
public String getRname() { return rname; }
public void setRname(String rname) { this.rname = rname; }
@ManyToMany
public Set<Func> getFuncs() { return funcs; }
public void setFuncs(Set<Func> funcs) { this.funcs = funcs; }
}
Func实体类的建立,
@Entity
@Table(name="t_func")
public class Func {
private int fid;
private String fname;
private Set<Role> roles;
@Id
@GeneratedValue
public int getFid() { return fid; }
public void setFid(int fid) { this.fid = fid; }
public String getFname() { return fname; }
public void setFname(String fname) { this.fname = fname; }
@ManyToMany(mappedBy="funcs")
public Set<Role> getRoles() { return roles; }
public void setRoles(Set<Role> roles) { this.roles = roles; }
}
2、将对应映射文件加入到session-factory配置(hibernate.cfg.xml)中
代码示例:
<mapping class="com.zr.model.Role" />
<mapping class="com.zr.model.User" />
<mapping class="com.zr.model.Func" />
3、测试
二、逆向开发(先进行数据库表设计,然后根据数据库设计建立实体类)
通过工具(HibernateTools-3.2.4.Beta1-R200810311334)把数据库的表自动帮你生成实体和注解或者XML
工具类的使用:直接将工具放入Eclipse安装包中
引入工具类(在pom.xml配置文件中配置)
代码示例:
<exclusions>
<exclusion>
<artifactId>javassist</artifactId>
<groupId>javassist</groupId>
</exclusion>
</exclusions>
步骤示例:创建数据库表---》 window--->Show View--->other--->Data Source Explorer --->右键Database Connections --->new--->MySQL--->输入密码并且把URL中改成你需要连接的数据库名--->点击Drivers后面第一个图标--->Name/Type中选中5.1版本--->JAR List中添加mysql-connector-java-5.1.18-bin.jar点击Edit--->window--->Show view --->other--->Hibernate Configurations --->右键Add Configurations--->Browse选中你的需要添加的项目名--->Datavase connection 中选中MySql--->Apply--->ok--->点击运行键右边第二个图标的下箭头选中Hibernate Code Generation Configurations --->Main中的Output directory 选择你要放表的地址--->package填写你要放入的包(com.zr.model)--->Exporters中的 勾选Generate EJB3 annotations,Domain code(.java){注解,如果配置xml文件选中Hibernate XML Mappings}--->Run
运行结束后需要注意:1.泛型需要指定 2. lazy 属性删掉
三、悲观锁和乐观锁(不同用户操作同一个数据)
1、悲观锁(需要由底层数据库提供支持,使用for update)
描述:指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数 据,为了保持数据被操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现
基于jdbc实现的数据库加锁如下:
select * from account where name="mary" for update
(在更新的过程中,数据库处于加锁状态,任何其他的针对本条数据的操作都将被延迟,本次事务提交后解锁。)
显示用户指定的方式:
Session.get()
Session.load() 指定锁的方式
Session.lock()
Query.setLockMode()
测试:
//加锁
@Test
public void test1(){
User user = (User) session.get(User.class, Integer.valueOf(1),LockMode.UPGRADE);
Role currentUserRole = user.getRole();
Set<Func> funcs = currentUserRole.getFuncs();
for (Func func : funcs) {
System.out.println(func.getFname());
}
}
2、乐观锁(为对象加上 一个版本号或者是时间戳)
描述:乐观的认为资料的存取很少发生同时存取的问题,因而不作数据库层次上的锁定,为了维护正确的数据,乐观锁定采用应用程序上的逻辑实现版本控制的方法。
可以利用Hibernate提供的版本控制功能来实现乐观锁。对象-关系映射文件中的<version>元素和<timestamp>元素 都具有版本控制功能:
<version>元素利用一个递增的整数来跟踪数据库表中记录的版本
<timestamp>元素用时间戳来跟踪数据库表中记录的版本。
代码示例:
1.在类中定义一个代表版本信息的属性:
private int version;
(进行get,set)
2.在表中定义一个代表版本信息的字段
3.在hbm.xml配置文件中用<version>元素来建立类的version属性与表中VERSION字段的映射:
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<version name="version" column="VERSION" />
4.找不到匹配的记录,此时Hibernate会抛出StaleObjectStateException。
在应用程序中应该捕获该异常,这种异常有两种处理方式:
4.1。自动撤销事务,通知用户账户信息已被其他事务修改,需要重新开始事务。
4.2。通知用户账户信息已被其他事务修改,显示最新存款余额信息,由用户决定如何继续事务,用户也可以决定立刻撤销事务。
5.如果数据库表中不包含代表版本或时间戳的字段,Hibernate提供了其他实现乐观锁的办法。把<class>元素的optimistic-lock属性设为“all”。
四、session中对象的4种状态
注:session 缓存(拿空间换时间)我们用的session 一级缓存,在缓存中就使用OID标识符
1、临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的 Java对象被称为临时对象。
(session缓存当中没有,数据库中当中也没有)
2、持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久 化对象。
(session缓存当中有,数据库中当中也有)
3、游离状态(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对 象。
(session缓存当中没有,数据库中当中有)
4、删除状态(removed):OID不为null。从一个Session实例的缓存中删除。被删除对象和数据库中的相关记录对 应。Session已经计划将其从数据库中删除。Session在清理缓存时,会执行SQL delete语句,删除数据库中的相应 记录。一般情况下,应用程序不应该再使用被删除的对象。
(session缓存当中没有,数据库中当中也没有)
代码示例:
@Test
public void test2(){
session = sf.openSession();
session.beginTransaction();
//临时状态
Student s = new Student();
s.setSname("wwj");
//持久化状态
session.save(s);
session.delete(s);
session.getTransaction().commit();
//关闭session
session.close();
//游离状态
// System.out.println(s.getSname());
//删除状态
System.out.println(s.getSname());
}
//将游离状态变为持久状态
@Test
public void update(){
Session session1 = sf.openSession();
session1.beginTransaction();
Student s = new Student();
s.setSname("yyy");
session1.save(s);
session1.getTransaction().commit();
session1.close();
Session session2 = sf.openSession();
session2.beginTransaction();
s.setSname("bcd");
session2.update(s);
session2.load(Student.class, Integer.valueOf(19));
System.out.println(s.getSname());
session2.getTransaction().commit();
session2.close();
}
5、关于get 和 load 方法的区别(都是优先从session一级缓存中寻找)
采用get加载数据,如果数据库中不存在相应的数据,那么返回null;
采用load加载数据,如果数据库中不存在相应的数据,那么抛出ObjectNotFoundException
load方法可返回实体的代理类实例,如果需要用到数据,在执行SQL语句。而get方法永远直接返回实体类。直接就 发出了SQL语句
代码示例:
@Test
public void testLoad(){
Session session = sf.openSession();
session.beginTransaction();
Student s = (Student) session.load(Student.class, Integer.valueOf(2));
System.out.println(s);
session.getTransaction().commit();
session.close();
}
@Test
public void testGet(){
Session session = sf.openSession();
session.beginTransaction();
Student s = (Student) session.get(Student.class, Integer.valueOf(2));
System.out.println(s);
s.getSname();
session.getTransaction().commit();
session.close();
}
目录:正向开发、逆向开发、悲观锁和乐观锁、session中对象的4种状态
Hibernate 框架学习(三):
一、正向开发(先根据数据库设计建立实体类,然后进行数据库表设计)
例子:用户( uid,name,rid),角色(rid,rname ),功能(fid,fname),角色_ 功能(rid,fid)
描述:一个用户有一个角色,一个角色对应多个功能,一个功能对应多个角色
(用户与角色之间一对一关系,角色与功能之间多对多的关系)
代码示例(注解配置):
1、建立对应实体User类、Role类、Func类对象
User实体类的建立,
@Entity
@Table(name="t_user")
public class User {
private int uid;
private String uname;
private Role role;
@Id
@GeneratedValue
public int getUid() { return uid; }
public void setUid(int uid) { this.uid = uid; }
public String getUname() { return uname; }
public void setUname(String uname) { this.uname = uname; }
@ManyToOne
public Role getRole() { return role; }
public void setRole(Role role) { this.role = role;}
}
Role实体类的建立,
@Entity
@Table(name="t_role")
public class Role {
private int rid;
private String rname;
private Set<Func> funcs;
@Id
@GeneratedValue
public int getRid() { return rid; }
public void setRid(int rid) { this.rid = rid; }
public String getRname() { return rname; }
public void setRname(String rname) { this.rname = rname; }
@ManyToMany
public Set<Func> getFuncs() { return funcs; }
public void setFuncs(Set<Func> funcs) { this.funcs = funcs; }
}
Func实体类的建立,
@Entity
@Table(name="t_func")
public class Func {
private int fid;
private String fname;
private Set<Role> roles;
@Id
@GeneratedValue
public int getFid() { return fid; }
public void setFid(int fid) { this.fid = fid; }
public String getFname() { return fname; }
public void setFname(String fname) { this.fname = fname; }
@ManyToMany(mappedBy="funcs")
public Set<Role> getRoles() { return roles; }
public void setRoles(Set<Role> roles) { this.roles = roles; }
}
2、将对应映射文件加入到session-factory配置(hibernate.cfg.xml)中
代码示例:
<mapping class="com.zr.model.Role" />
<mapping class="com.zr.model.User" />
<mapping class="com.zr.model.Func" />
3、测试
二、逆向开发(先进行数据库表设计,然后根据数据库设计建立实体类)
通过工具(HibernateTools-3.2.4.Beta1-R200810311334)把数据库的表自动帮你生成实体和注解或者XML
工具类的使用:直接将工具放入Eclipse安装包中
引入工具类(在pom.xml配置文件中配置)
代码示例:
<exclusions>
<exclusion>
<artifactId>javassist</artifactId>
<groupId>javassist</groupId>
</exclusion>
</exclusions>
步骤示例:创建数据库表---》 window--->Show View--->other--->Data Source Explorer --->右键Database Connections --->new--->MySQL--->输入密码并且把URL中改成你需要连接的数据库名--->点击Drivers后面第一个图标--->Name/Type中选中5.1版本--->JAR List中添加mysql-connector-java-5.1.18-bin.jar点击Edit--->window--->Show view --->other--->Hibernate Configurations --->右键Add Configurations--->Browse选中你的需要添加的项目名--->Datavase connection 中选中MySql--->Apply--->ok--->点击运行键右边第二个图标的下箭头选中Hibernate Code Generation Configurations --->Main中的Output directory 选择你要放表的地址--->package填写你要放入的包(com.zr.model)--->Exporters中的 勾选Generate EJB3 annotations,Domain code(.java){注解,如果配置xml文件选中Hibernate XML Mappings}--->Run
运行结束后需要注意:1.泛型需要指定 2. lazy 属性删掉
三、悲观锁和乐观锁(不同用户操作同一个数据)
1、悲观锁(需要由底层数据库提供支持,使用for update)
描述:指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数 据,为了保持数据被操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现
基于jdbc实现的数据库加锁如下:
select * from account where name="mary" for update
(在更新的过程中,数据库处于加锁状态,任何其他的针对本条数据的操作都将被延迟,本次事务提交后解锁。)
显示用户指定的方式:
Session.get()
Session.load() 指定锁的方式
Session.lock()
Query.setLockMode()
测试:
//加锁
@Test
public void test1(){
User user = (User) session.get(User.class, Integer.valueOf(1),LockMode.UPGRADE);
Role currentUserRole = user.getRole();
Set<Func> funcs = currentUserRole.getFuncs();
for (Func func : funcs) {
System.out.println(func.getFname());
}
}
2、乐观锁(为对象加上 一个版本号或者是时间戳)
描述:乐观的认为资料的存取很少发生同时存取的问题,因而不作数据库层次上的锁定,为了维护正确的数据,乐观锁定采用应用程序上的逻辑实现版本控制的方法。
可以利用Hibernate提供的版本控制功能来实现乐观锁。对象-关系映射文件中的<version>元素和<timestamp>元素 都具有版本控制功能:
<version>元素利用一个递增的整数来跟踪数据库表中记录的版本
<timestamp>元素用时间戳来跟踪数据库表中记录的版本。
代码示例:
1.在类中定义一个代表版本信息的属性:
private int version;
(进行get,set)
2.在表中定义一个代表版本信息的字段
3.在hbm.xml配置文件中用<version>元素来建立类的version属性与表中VERSION字段的映射:
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<version name="version" column="VERSION" />
4.找不到匹配的记录,此时Hibernate会抛出StaleObjectStateException。
在应用程序中应该捕获该异常,这种异常有两种处理方式:
4.1。自动撤销事务,通知用户账户信息已被其他事务修改,需要重新开始事务。
4.2。通知用户账户信息已被其他事务修改,显示最新存款余额信息,由用户决定如何继续事务,用户也可以决定立刻撤销事务。
5.如果数据库表中不包含代表版本或时间戳的字段,Hibernate提供了其他实现乐观锁的办法。把<class>元素的optimistic-lock属性设为“all”。
四、session中对象的4种状态
注:session 缓存(拿空间换时间)我们用的session 一级缓存,在缓存中就使用OID标识符
1、临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的 Java对象被称为临时对象。
(session缓存当中没有,数据库中当中也没有)
2、持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久 化对象。
(session缓存当中有,数据库中当中也有)
3、游离状态(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对 象。
(session缓存当中没有,数据库中当中有)
4、删除状态(removed):OID不为null。从一个Session实例的缓存中删除。被删除对象和数据库中的相关记录对 应。Session已经计划将其从数据库中删除。Session在清理缓存时,会执行SQL delete语句,删除数据库中的相应 记录。一般情况下,应用程序不应该再使用被删除的对象。
(session缓存当中没有,数据库中当中也没有)
代码示例:
@Test
public void test2(){
session = sf.openSession();
session.beginTransaction();
//临时状态
Student s = new Student();
s.setSname("wwj");
//持久化状态
session.save(s);
session.delete(s);
session.getTransaction().commit();
//关闭session
session.close();
//游离状态
// System.out.println(s.getSname());
//删除状态
System.out.println(s.getSname());
}
//将游离状态变为持久状态
@Test
public void update(){
Session session1 = sf.openSession();
session1.beginTransaction();
Student s = new Student();
s.setSname("yyy");
session1.save(s);
session1.getTransaction().commit();
session1.close();
Session session2 = sf.openSession();
session2.beginTransaction();
s.setSname("bcd");
session2.update(s);
session2.load(Student.class, Integer.valueOf(19));
System.out.println(s.getSname());
session2.getTransaction().commit();
session2.close();
}
5、关于get 和 load 方法的区别(都是优先从session一级缓存中寻找)
采用get加载数据,如果数据库中不存在相应的数据,那么返回null;
采用load加载数据,如果数据库中不存在相应的数据,那么抛出ObjectNotFoundException
load方法可返回实体的代理类实例,如果需要用到数据,在执行SQL语句。而get方法永远直接返回实体类。直接就 发出了SQL语句
代码示例:
@Test
public void testLoad(){
Session session = sf.openSession();
session.beginTransaction();
Student s = (Student) session.load(Student.class, Integer.valueOf(2));
System.out.println(s);
session.getTransaction().commit();
session.close();
}
@Test
public void testGet(){
Session session = sf.openSession();
session.beginTransaction();
Student s = (Student) session.get(Student.class, Integer.valueOf(2));
System.out.println(s);
s.getSname();
session.getTransaction().commit();
session.close();
}