很长时间对join方法感到疑惑,不明白到底是谁要阻塞,谁要继续执行(线程这部分亟需加强)。今天和一网友交流后疑惑得到解决,在此表示感谢Stephen_Liu。
假如在main方法中有个线程A,执行了A.join(),那么线程A继续执行,而main线程这阻塞在A.join()处,直到线程A执行完毕并正常退出,此时main方法中的A.join()才返回,然后继续执行A.join()后面的代码。
public class ThreadJoin extends Thread {
public static int n = 0;
static synchronized void inc() {
n++;
}
public void run() {
try {
for (int i = 0; i < 10; i++) {
inc();
sleep(3);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Thread thread[] = new Thread[100];
for (int i = 0; i < thread.length; i++) {
thread[i] = new ThreadJoin();
}
for (int i = 0; i < thread.length; i++) {
thread[i].start();
}
for (int i = 0; i < thread.length; i++) {
thread[i].join(); //不使用这句话n是个随机数,使用n=1000
}
System.out.println("n=" + ThreadJoin.n);
}
}
public class ReadXmlByDom4J {
public static void main(String args[]){
File f=new File("F:\\car.xml");
Dom4J(f);
}
public static void Dom4J(File f){
try {
SAXReader reader=new SAXReader(); //使用SAXReader方式读取XML文件
Document doc=reader.read(f); //加载XML配置文件,得到Document对象
Element root=doc.getRootElement(); //获得根节点
//取得某节点的单个子节点
System.out.println("-------取得某节点的单个子节点开始----------");
Element value=root.element("VALUE");
// System.out.println(value.getName()+","+value.getText());
Element no=value.element("NO"); //只获得第一个元素
Element addr=value.element("ADDR");
System.out.println(no.getName()+":"+no.getText());
System.out.println(addr.getName()+":"+addr.getText());
System.out.println("--------取得某节点的单个子节点结束----------");
for(Iterator i=root.elementIterator("VALUE");i.hasNext();){
Element temp=(Element) i.next();
System.out.println(temp.selectSingleNode("NO").getName()+":"+temp.selectSingleNode("NO").getText());
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
car.xml
<?xml version="1.0" encoding="GB2312"?>
<RESULT>
<VALUE>
<NO>A1234</NO>
<ADDR>河南省郑州市金水区</ADDR>
</VALUE>
<VALUE>
<NO>B1234</NO>
<ADDR>河南省郑州市二七区</ADDR>
</VALUE>
</RESULT>
输出结果:
-------取得某节点的单个子节点开始----------
NO:A1234
ADDR:河南省郑州市金水区
--------取得某节点的单个子节点结束----------
NO:A1234
NO:B1234
Mysql:
String Driver="com.mysql.jdbc.Driver"; //驱动程序
String URL="jdbc:mysql://localhost:3306/db_name"; //连接的URL,db_name为数据库名
String Username="username"; //用户名
String Password="password"; //密码
Class.forName(Driver).new Instance(); //加载数据库驱动
Connection con=DriverManager.getConnection(URL,Username,Password);
Oracle:
String Driver="oracle.jdbc.driver.OracleDriver";
String URL="jdbc:oracle:thin:@loaclhost:1521:orcl"; //orcl为数据库的SID
DB2:
String Driver="com.ibm.db2.jdbc.app.DB2.Driver"; //连接具有DB2客户端的Provider实例
//String Driver="com.ibm.db2.jdbc.net.DB2.Driver"; //连接不具有DB2客户端的Provider实例
String URL="jdbc:db2://localhost:50000/db_name"; //db_name为数据可名
SQL Server:
1)
String Driver="com.microsoft.jdbc.sqlserver.SQLServerDriver"; //连接SQL数据库的方法
String URL="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=db_name"; //db_name为数据库名
2)
String Driver="com.microsoft.sqlserver.jdbc.SQLServerDriver";
String URL="jdbc:sqlserver://localhost:1433;DatabaseName=db_name";
Informix:
String Driver="com.informix.jdbc.IfxDriver";
String URL="jdbc:Informix-sqli://localhost:1533/db_name:INFORMIXSER=myserver";
JDBC-ODBC:
String Driver="sun.jdbc.odbc.JdbcOdbcDriver";
String URL="jdbc:odbc:dbsource"; //dbsource为数据源名
Sysbase:
String Driver="com.sybase.jdbc.SybDriver"; //驱动程序
String URL="jdbc:Sysbase://localhost:5007/db_name"; //db_name为数据可名
PostgreSQL:
String Driver="org.postgresql.Driver"; //连接数据库的方法
String URL="jdbc:postgresql://localhost/db_name"; //db_name为数据可名
各种数据库连接大同小异,区别的是Driver和URL,其他的区别不大。参考:http://www.cnblogs.com/itat/archive/2011/08/22/2149924.html
ClassA.java
public class ClassA implements Serializable {
private static final long serialVersionUID = 6013572251564847381L;
private String name = "My name is a";
private ClassB b = null;
ClassA() {
b = new ClassB();
}
public String show() {
System.out.println("a.toString <a.name=\"" + this.name
+ "\" a.b.name=\"" + this.b.getName() + "\">");
return "a.toString <a.name=" + this.name + " a.b.name="
+ this.b.getName() + ">";
// \" 双引号
// \' 单引号
// \\ 反斜线
}
public int add(int a, int b) {
return a + b;
}
public int divide(int a, int b) throws Exception {
if (0 == b) {
throw new Exception("除数不能为零");
}
return a / b;
}
public int exception(int a, int b) throws Exception {
if (a == 2) {
throw new Exception("进入我设置的异常啦!");
}
return a + b;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ClassB getB() {
return b;
}
public void setB(ClassB b) {
this.b = b;
}
}
ClassB.java
public class ClassB implements Serializable{
private static final long serialVersionUID = -4324044767844361076L;
private String name="My name is b";
ClassB(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
JUin测试
public class ClassATest extends TestCase {
ClassA a = new ClassA();
public void testShow() {
// 覆盖原来的name
a.setName("hello TestA");
a.getB().setName("hello TestB");
a.show();
}
public void testAdd() {
// boolean b=false;
// Assert.assertEquals(true, b);
int result = 0;
result = a.add(2, 5);
Assert.assertEquals(7, result);
}
public void testDivide() {
int result = 0;
try {
result = a.divide(10, 5);
} catch (Exception e) {
e.printStackTrace(); // 如果进入到catch中说明执行divide失败
System.out.println("执行上面那句话了");
Assert.fail();
}
Assert.assertEquals(2, result);
}
public void testException() {
int result = 0;
try {
result = a.exception(3, 4);
} catch (Exception e) {
e.printStackTrace();
System.out.println("执行上面那句话了");
Assert.fail();
}
Assert.assertEquals(7, result);
}
}
实现Serializable借口的对象可以被转换成一系列字节,并可以在以后使用时完全恢复原来的样子。这一过程也可以在网络中进行,这样就可以先在windows机器上创建一个对象,对其序列化,然后通过网络发送给Linux机器,就可以在Linux机器上准确无误地恢复成原来的样子。整个过程不必关心数据在不同机器上如何表示,也不必关心字节的顺序或其他细节。
序列化的思想就是“冻结”对象,操作对象(写到磁盘,通过网络传输等),然后“解冻”对象,重新获得可用的Java对象。功能的实现要靠ObjectInputStream/ObjectOutputStream类,完全保真原数据,并且开发愿意用Serializable。
实现了Serializable接口的类为保证serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。
ClassA.java
public class ClassA implements Serializable {
private static final long serialVersionUID = 6013572251564847381L;
private String name = "My name is a";
private ClassB b = null;
ClassA() {
b = new ClassB();
}
public String show() {
System.out.println("a.toString <a.name=\"" + this.name
+ "\" a.b.name=\"" + this.b.getName() + "\">");
return "a.toString <a.name=" + this.name + " a.b.name="
+ this.b.getName() + ">";
// \" 双引号
// \' 单引号
// \\ 反斜线
}
.......................
}
ClassB.java
public class ClassB implements Serializable{
private static final long serialVersionUID = -4324044767844361076L;
private String name="My name is b";
ClassB(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
将对象内容保存到文本中
WriteSeri.java
public class WriteSeri {
public static void main(String args[]){
ObjectOutputStream outObj=null;
try {
//将对象内容写入到文本中
FileOutputStream outStr=new FileOutputStream("obj.txt");
outObj=new ObjectOutputStream(outStr);
ClassA a=new ClassA();
outObj.writeObject(a);
System.out.println("write obj:"+a.show());
outObj.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (outObj != null) {
outObj.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出结果:
a.toString <a.name="My name is a" a.b.name="My name is b">
write obj:a.toString <a.name=My name is a a.b.name=My name is b>
将文本内容还原给对象
ReadSeri.java
public class ReadSeri {
public static void main(String args[]) {
ObjectInputStream inObj = null;
try {
FileInputStream inStr = new FileInputStream("obj.txt");
inObj = new ObjectInputStream(inStr);
ClassA a = (ClassA) inObj.readObject();
System.out.println("read object:" + a.show());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (inObj != null) {
try {
inObj.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
输出结果:
a.toString <a.name="My name is a" a.b.name="My name is b">
read object:a.toString <a.name=My name is a a.b.name=My name is b>
先把字符串日期转换成对应的格式,然后再转换成日期
public static void main(String args[]){
String str="2010/05/06";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
str=str.replace("/", "-");
System.out.println("str="+str);
System.out.println("time="+sdf.parse(str));
System.out.println("formateTime="+sdf.format(sdf.parse(str)));
} catch (ParseException e) {
e.printStackTrace();
}
}
结果:
str=2010-05-06
time=Thu May 06 00:00:00 CST 2010
formateTime=2010-05-06
开发中碰到了一个需求,需要把键值对字符串分隔,但键值之间空格很多,只用split("")肯定不行,最后通过正则表达式解决了问题。
public class StringToArray {
public static void main(String args[]) {
String s = "北京天竺出口加工区 C1101";
String[] arry = s.split("\\s+");
System.out.println(arry.length);
System.out.println("arry[0]=" + arry[0]);
System.out.println("arry[1]=" + arry[1]);
}
}
结果:
2
arry[0]=北京天竺出口加工区
arry[1]=C1101
创建一个接口
XmlInterface.java
public interface XmlInterface {
/**
* 建立XML文档
* @param fileName 文件全路径名称
*/
public void createXml(String fileName);
/**
* 解析XML文档
* @param fileName 文件全路径名称
*/
public void parserXml(String fileName);
}
接口实现
XmlImpl.java
package com.test.xml;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XmlImpl implements XmlInterface{
private Document document;
public void init() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
this.document = builder.newDocument();
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
}
}
public void createXml(String fileName) {
Element root = this.document.createElement("scores");
this.document.appendChild(root);
Element employee = this.document.createElement("employee");
Element name = this.document.createElement("name");
name.appendChild(this.document.createTextNode("wangchenyang"));
employee.appendChild(name);
Element sex = this.document.createElement("sex");
sex.appendChild(this.document.createTextNode("m"));
employee.appendChild(sex);
Element age = this.document.createElement("age");
age.appendChild(this.document.createTextNode("26"));
employee.appendChild(age);
root.appendChild(employee);
TransformerFactory tf = TransformerFactory.newInstance();
try {
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
StreamResult result = new StreamResult(pw);
transformer.transform(source, result);
System.out.println("生成XML文件成功!");
} catch (TransformerConfigurationException e) {
System.out.println(e.getMessage());
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (TransformerException e) {
System.out.println(e.getMessage());
}
}
public void parserXml(String fileName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(fileName);
NodeList employees = document.getChildNodes();
for (int i = 0; i < employees.getLength(); i++) {
Node employee = employees.item(i);
NodeList employeeInfo = employee.getChildNodes();
for (int j = 0; j < employeeInfo.getLength(); j++) {
Node node = employeeInfo.item(j);
NodeList employeeMeta = node.getChildNodes();
for (int k = 0; k < employeeMeta.getLength(); k++) {
System.out.println(employeeMeta.item(k).getNodeName()
+ ":" + employeeMeta.item(k).getTextContent());
}
}
}
System.out.println("解析完毕");
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
} catch (SAXException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
测试
public class Main {
public static void main(String args[]){
XmlImpl dd=new XmlImpl();
String str="D:/grade.xml";
dd.init();
dd.createXml(str); //创建xml
dd.parserXml(str); //读取xml
}
}
结果
生成xml
<?xml version="1.0" encoding="GB2312"?>
<scores>
<employee>
<name>wangchenyang</name>
<sex>m</sex>
<age>26</age>
</employee>
</scores>
读取xml
生成XML文件成功!
#text:
name:wangchenyang
#text:
sex:m
#text:
age:26
#text:
解析完毕
一对一关联包括两种类型:
1.主键关联
2.惟一外键关联
主键关联:
两张关联表通过主键形成一对一映射关系
实例:一个公民对应一个身份证
1.主键关联
实体类
TUser .java
/**
* 主键关联
*
*/
public class TUser implements Serializable {
private static final long serialVersionUID = -133439792227297972L;
private Integer id;
private Integer age;
private String name;
private TPassport passport;
..........................
}
TPassport.java
/**
* 主键关联
*
*/
public class TPassport implements Serializable{
private static final long serialVersionUID = -2207892280100301351L;
private Integer id;
private String serial;
private Integer expiry;
private TUser user;
}
配置文件
Tuser.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- 主键关联 -->
<hibernate-mapping>
<class
name="com.model.TUser"
table="t_user"
dynamic-update="true"
>
<id
name="id"
type="java.lang.Integer"
column="id"
unsaved-value="0"
>
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="java.lang.Integer"/>
<one-to-one name="passport" class="com.model.TPassport" cascade="all" outer-join="false"/>
</class>
</hibernate-mapping>
Tpassport.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- 主键关联 -->
<hibernate-mapping>
<class
name="com.model.TPassport"
table="t_passport"
dynamic-update="true"
>
<id
name="id"
type="java.lang.Integer"
column="id"
unsaved-value="0"
>
<!-- 由于采用了主键关联方式,那么通过主键关联的两张表,其关联记录的主键值必须保持同步。
这也就意味着,我们只需为一张表设定主键生成策略,而另一张表的主键与之共享相同的主键值
通过“foreign”类型的主键生成策略与外键共享主键值
-->
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<property name="serial" column="serial" type="string"/>
<property name="expiry" column="expiry" type="java.lang.Integer"/>
<!-- constrained必须是“true”,以告知hibernate当前表主键上存在一个约束:t_passport表引用了t_user表的主键 -->
<one-to-one name="user" class="com.model.TUser" constrained="true"/>
</class>
</hibernate-mapping>
测试代码(部分)
//主键关联
public void testSave() {
TUser user = new TUser();
user.setName("zhangsan");
user.setAge(20);
TPassport passport = new TPassport();
passport.setExpiry(445555);
passport.setSerial("PCN2324");
// 设置相互关联
passport.setUser(user);
user.setPassport(passport);
try {
Transaction tx = session.beginTransaction();
// 由于TUser类的one-to-one节点被设置为cascade=all,其关联的passport对象将被级联保存
session.save(user);
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
}
}
//主键关联
public void testLoad1() {
try {
TUser user = (TUser) session.load(TUser.class, 1);
System.out.println("user name---->" + user.getName());
System.out.println("passport serial---->"
+ user.getPassport().getSerial());
} catch (HibernateException e) {
e.printStackTrace();
}
/** out-join="true" 加载TUser实例时 hibernate通过left outer join将t_user表及其关联的t_group表同时读出
* Hibernate: select tuser0_.id as id1_, tuser0_.name as name1_,
* tuser0_.age as age1_, tpassport1_.id as id0_, tpassport1_.serial as
* serial0_, tpassport1_.expiry as expiry0_ from t_user tuser0_
* left outer join
* t_passport tpassport1_ on tuser0_.id=tpassport1_.id where tuser0_.id=?
*/
}
//主键关联
public void testLoad2() {
try {
TUser user = (TUser) session.load(TUser.class, 1);
System.out.println("user name---->" + user.getName());
System.out.println("passport serial---->"
+ user.getPassport().getSerial());
} catch (HibernateException e) {
e.printStackTrace();
}
/** one-to-one节点设定为 out-join="false"时,分别读取
* Hibernate: select tuser0_.id as id0_, tuser0_.name as name0_, tuser0_.age as age0_ from t_user tuser0_ where tuser0_.id=?
* Hibernate: select tpassport0_.id as id1_, tpassport0_.serial as serial1_, tpassport0_.expiry as expiry1_, tuser1_.id as id0_, tuser1_.name as name0_, tuser1_.age as age0_ from t_passport tpassport0_ left outer join t_user tuser1_ on tpassport0_.id=tuser1_.id where tpassport0_.id=?
*/
}
2.惟一外键关联
实体类
TGroup.java
/**
* 惟一外键关联实体
*/
public class TGroup implements Serializable {
private static final long serialVersionUID = 263676571059714064L;
private Integer id;
private String name;
// 不加实现的是单向一对一关系 通过Tuser2对象可以获得其相对应的Tgroup对象,但不能反过来
// 增加是为了实现双向一对一关系 可以互相获得 并且还要在TGroup.cfg.xml中追加one-to-one配置
private TUser2 user;
.............................
}
TUser2.java
/**
*惟一外键关联实体
*/
public class TUser2 implements Serializable{
private static final long serialVersionUID = -1898408468538505300L;
private Integer id;
private Integer age;
private String name;
private TGroup group;
..................
}
配置文件
TGroup.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<class
name="com.model.TGroup"
table="t_group"
dynamic-update="true"
>
<id
name="id"
type="java.lang.Integer"
column="id"
unsaved-value="0"
>
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<one-to-one name="user" class="com.model.TUser2" property-ref="group"/>
</class>
</hibernate-mapping>
Tuser2.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<class
name="com.model.TUser2"
table="t_user2"
dynamic-update="true"
>
<id
name="id"
type="java.lang.Integer"
column="id"
unsaved-value="0"
>
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="java.lang.Integer"/>
<!-- 惟一外键关联的一对一关系只是多对一关系的一个特例而已 -->
<many-to-one name="group" class="com.model.TGroup" column="group_id" unique="true"/>
</class>
</hibernate-mapping>
测试代码(部分)
public void testSave2(){
TGroup group=new TGroup();
group.setName("group-one");
TUser2 user=new TUser2();
user.setName("lisi");
user.setAge(20);
user.setGroup(group);
try {
Transaction tx=session.beginTransaction();
session.save(user);
session.save(group); //必须保存 但先后顺序不要求
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
}
}
//单向 user---->group
public void testLoad3(){
try {
TUser2 user=(TUser2) session.load(TUser2.class, 1);
System.out.println("group name--->"+user.getGroup().getName());
} catch (HibernateException e) {
e.printStackTrace();
}
}
//双向 group-->user
public void testLoad4(){
/**
* 在TGroup.cfg.xml中不添加one-to-one配置时,查不到user信息
* Hibernate: select tgroup0_.id as id0_, tgroup0_.name as name0_ from t_group tgroup0_ where tgroup0_.id=?
Group name---->group-one
*/
try {
TGroup group=(TGroup) session.load(TGroup.class, 1);
System.out.println("Group name---->"+group.getName());
System.out.println("group user---->"+group.getUser().getName());
} catch (HibernateException e) {
e.printStackTrace();
}
/** 添加配置后
* Hibernate: select tgroup0_.id as id1_, tgroup0_.name as name1_, tuser21_.id as id0_, tuser21_.name as name0_, tuser21_.age as age0_, tuser21_.group_id as group_id0_ from t_group tgroup0_ left outer join t_user2 tuser21_ on tgroup0_.id=tuser21_.group_id where tgroup0_.id=?
Hibernate: select tuser20_.id as id1_, tuser20_.name as name1_, tuser20_.age as age1_, tuser20_.group_id as group_id1_, tgroup1_.id as id0_, tgroup1_.name as name0_ from t_user2 tuser20_ left outer join t_group tgroup1_ on tuser20_.group_id=tgroup1_.id where tuser20_.group_id=?
Group name---->group-one
group user---->lisi
*/
}
三种状态:
生命周期:
代码表示:
//三种状态
public void testThreeState(){
TUser user=new TUser();
user.setName("spark"); //此时user处于Transient
try {
Transaction tx=session.beginTransaction();
session.save(user); //user对象已经由hibernate纳入管理器,处于persistent状态
tx.commit();
session.close(); //user对象此时为Detached状态,因为与其关联的session已经关闭
Transaction tx2=session2.beginTransaction();
session2.update(user);//user对象借助session2,由hibernate纳入管理容器,恢复persistent状态 update并没有发送sql语句
user.setName("spark_1");//处于persistent状态,其属性变更将自动由hibernate固话到数据库中 !!!!
tx2.commit(); //commit之前调用session.flush()在其中发送sql语句
} catch (HibernateException e) {
e.printStackTrace();
}
}