前段时间写了一个项目,用hibernate修改字段值,用了比较原始的sql方式,今天想换种方式,先查询获得对象,再使用set某字段的方式修改值。
先搭建环境,需要如下的jar包:
需要hibernate的一个配置文件 hibernate.cfg.xml,包括后面需要的配置文件和java类,直接放src根目录就行,
com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc:sqlserver://localhost:1433; DatabaseName=haitun sa sqlserver 1 org.hibernate.dialect.SQLServerDialect true true update
类与数据库的映射文件 Person.hbm.xml
Person类:
public class Person { private int personId; private String personName; private String personPass; public String getPersonPass() { return personPass; } public void setPersonPass(String personPass) { this.personPass = personPass; } public int getPersonId() { return personId; } public void setPersonId(int personId) { this.personId = personId; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; }}
HibernateUtil.java,提供SessionFactory,hibernate官方提供,表示session工厂,官方建议这样用。
import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; }}
Test.java,测试类
import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;public class Test { public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); Transaction tx = session.getTransaction(); tx.begin(); Person person = new Person(); //游离态,在session中 person.setPersonName("lyj"); person.setPersonPass("123"); session.save(person); //持久态,在session中,与数据库关联,但未保存进数据库,虽然打印了insert语句 //person =(Person)session.get(Person.class, 1); //立即查询, person =(Person)session.load(Person.class, 1); //延迟查询,用到对象时,比如person.getPersonName());,才去查询 System.out.println("华丽丽的分割线---------------------------------------------"); System.out.println(person.getPersonName()); System.out.println(person.getPersonPass()); person.setPersonName("lyjlyj"); //对session中的对象进行修改 tx.commit(); //事务,提交后才能保存进数据库 session.close(); sf.close(); }}
运行时,打印的sql语句为:
log4j:WARN No appenders could be found for logger (org.jboss.logging).log4j:WARN Please initialize the log4j system properly.log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.Hibernate: insert into person (person_name, person_pass) values (?, ?)华丽丽的分割线---------------------------------------------Hibernate: //save()后立即查询,是不会有查询语句的,因为此时的session中是有Person对象的,hibernate在缓存中找到了对象,就不会去数据中查询 select person0_.person_id as person_i1_0_0_, person0_.person_name as person_n2_0_0_, person0_.person_pass as person_p3_0_0_ from person person0_ where person0_.person_id=?lyj123Hibernate: update person set person_name=?, person_pass=? where person_id=?
可以看出,最后的更新语句,虽然程序中只更新了姓名字段,但hibernate执行时却更新了全部字段。
程序中只做了这一步操作person.setPersonName("lyjlyj");并没有保存到数据库,但为何会执行update呢,因为程序结束时,session会关闭,也就清空了session中的缓存,数据会被更新到数据库中,于是打印了update语句。
如果使用sql方式的update:
String hql = "update Person p set p.personName='lyjlyjlyj' where p.personId=1"; session.createQuery(hql).executeUpdate();
就会只更新想要修改的字段,打印如下:
update person set person_name='lyjlyjlyj' where person_id=1
查询时,set和load的区别也就是 是否延迟查询的区别,从sql语句的打印顺序上来看是这样。