12月8日——培训第16天
来源:互联网 发布:rar在linux下解压 编辑:程序博客网 时间:2024/05/13 07:09
昨天晚上借着喝酒交心的功夫,同寝室的宁艳超和兰献斌和田老师好好的作了一番交流,聊了很长时间,提到
上课时间不要安排的过于紧密,要留有一定的练习时间等等。于是今天上午田老师安排我们练习昨天的Hibernate
连接数据库取数据的方法。
好好试了试,还是明白了一些东西的,附上我的源代码如下:
数据库:mysql
建立的库:j2ee
数据表users
字段:
id :主键,默认自增,整型
name:varchar型,不能为空
password:varchar型,不能为空
loginTimes:int型,不能为空
loginTime:Timestamp型(最好设置为Datetime型比较好),不为空
当然了,还是得先导入包,lib文件夹下的所有jar包,还有那个mysql的驱动。
配置文件如下:
1. hibernate.cfg.xml:
------------------------------------
<?xml version="1.0"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///j2ee</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="show_sql">true</property> 注意这条语句是表示每和数据库交互一次就必须显示sql语句!
<property name="format_sql">true</property>这条语句是表示要让sql语句按照比较好看的格式来显示出来
</session-factory>
</hibernate-configuration>
---------------------------------------------------------------------------
2. Entity.hbm.xml
---------------------------------------------------------
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping> 注意包名是practice,实体类名是Entity,对应表名是users,下面的两个参数可以自己根据情况设置!
<class name="practice.Entity" table="users" dynamic-update="true" dynamic-insert="false">
<id name="id" column="id">
<generator class="identity"/>
</id>
<property name="name" column="name"/>
<property name="password" column="password"/>
<property name="loginTimes" column="loginTimes"/>
<property name="loginTime" column="loginTime"/>
</class>
</hibernate-mapping>
--------------------------------------------------------------------------
我自己建立的一个实体类Entity:
package practice;
import java.sql.Timestamp;
public class Entity {
private int id ;
private String name ;
private String password ;
private int loginTimes ;
private Timestamp loginTime ;
private Integer test ;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Timestamp getLoginTime() {
return loginTime;
}
public void setLoginTime(Timestamp loginTime) {
this.loginTime = loginTime;
}
public int getLoginTimes() {
return loginTimes;
}
public void setLoginTimes(int loginTimes) {
this.loginTimes = loginTimes;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public static void main(String[] args)
{
Entity e = new Entity();
System.out.println(e.getLoginTimes());
System.out.println(e.getLoginTime());
}
public Integer getTest() {
return test;
}
public void setTest(Integer test) {
this.test = test;
}
}
-------------------------------------
我写的测试类Test:
package practice;
import java.sql.Timestamp;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//下面这两行是用来得到工厂session,用来操作实体类对象的,最后记得要关闭它!
SessionFactory factory =
new Configuration().addClass(Entity.class).configure().buildSessionFactory();
Session session = factory.openSession();
//插入
/*Entity e = new Entity();
//e.setLoginTime(new Timestamp(System.currentTimeMillis()));
e.setLoginTimes(2);
e.setName("yyy");
e.setPassword("yyy");
session.beginTransaction();
session.save(e);
session.getTransaction().commit(); */
//选取(当然还有一种选取是不用load,而是用get,load延迟选取,get不延迟)
/*Entity e = (Entity)session.load(Entity.class,new Integer(1));
System.out.println(e.getName());
*/
//第一种更新
session.beginTransaction();
Entity e = (Entity)session.load(Entity.class,new Integer(5));
e.setName("43112");
session.getTransaction().commit();
//删除
/*session.beginTransaction();
Entity e = (Entity)session.load(Entity.class,new Integer(7));
session.delete(e);
session.getTransaction().commit();*/
//persist插入:
/*session.beginTransaction();
Entity e = new Entity();
e.setName("newyuan");
e.setPassword("newyuan");
//e.setLoginTime(new Timestamp(System.currentTimeMillis()));
session.persist(e);
session.getTransaction().commit();*/
//第二种更新:
/*session.beginTransaction();
Entity e = new Entity();
e.setId(5);
e.setName("123456");
e.setPassword("123456");
e.setLoginTimes(2);
session.update(e);
session.getTransaction().commit();*/
session.close();
}
}
------------------------------------------------------
中午把就业协议发了下来,下午课程开始:
先是走一遍流程:新建工程,导入lib包、mysql驱动,新建一个和数据库中的表对应的类User,
新建配置文件,选other,找MyEclipse中的XML中的dtd选项,选择create xml from dtd
来建立hibernate.cfg.xml。
1 在session-factory中加入多行property元素,
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///j2ee</property> ……………………
还有u用户名和密码
注意还要设置show_sql和format_sql属性。
一般我们现在配置的文件都是以DriverManager的方式来连接的,以后会改为DataSource方式连接!
2 新建User.hbm.xml映射文件,可以在hibernate-mapping中加入package属性,这样底下的class的table中
就不用引入包名了!
而且如果name和column同名的话只写一个name就可以了。
3 然后是自己写一个Demo类来测试Hibernate元素
注意:可以在session-factory的后面加上:<mapping resource="包名/User.hbm.xml"/> 这样就不用建立配置Configuration
时加载class了,但是这样可能会出现内存浪费的情况,可能会加载了许多不需要使用的类!
SessionFactory factory = new Configuration().configure().buildSessionFactory();
Session session = factory.openSession() ;
User u = new User();
u.setUsername("aaa");
session.beginTransaction();
sessin.save(u)
session.getTransaction().commit();
注意:如果发生异常的话,可以在catch中写上session.getTransaction().rollback();
在finally中要记得关闭session,使用session.close();
-----------------------------------
-----------------------------------
今天要掌握的知识点:
对象三种状态以及主键:
1 知道如何在不使用默认文件名时,也能配置Hibernate。知道SessionFactory和Session在编程的时候需要注意什么问题?
2 对象的三种状态分别是什么?含义?
3 update方法和merge方法的区别,应用场合?
4 saveOrUpdate方法应用场合?
5 主键生成器什么意思?为什么实体一定要有标识符?如果数据表中没有主键的话,能否映射对象???
------------------------------------
不使用默认名来配置Hibernate:
一 配置文件Hibernate.cfg.xml:
1 SessionFactory factory = new Configuration().addClass(User.class).
configure("hibernate.xml").buildSessionFactory();
注意:hibernate.xml就是我自己写的configure配置文件
2 而且我还可以不configure("hibernate.xml")直接去buildSessionFactory();
也就是:
SessionFactory factory = new Configuration().addClass(User.class).
buildSessionFactory();
但是这时候记得要把hibernate.property属性文件导入类根目录中,去掉其中的相关注释,比如mysql
这时候引入了property文件的话就不用那个xmlconfiguration配置文件了,使用property文件的话
确实也就不用调用那个configure()方法了
3 当property文件和xml配置文件同时使用的话,以xml配置文件为优先
4 再次注意一点:构造会话工厂SessionFactory时,可以不使用添加类的语句,也就是那个
addClass(User.class), 执行到这句话的时候,会去读取那个映射文件,如果在配置文件
中的session-factory元素中加入了<mapping resource="包名/User.hbm.xml"/> 的话,
这样就不用那个addClass方法了!但是不可以同时使用mapping resource标签和addClass方法!!!!
满江红网站上有个叫曹晓钢的人组织了很多人一起翻译Hibernate和Spring的官方文档
--------------------------------------
假设在一个映射文件User.hbm.xml中映射了两个类,那么使用addClass(User.class)就可以
它会直接去找类路径中和User同名的那个User.hbm.xml文件,由于该映射文件中已经有了两个
类映射到了不同的两个表,所以找一个User的映射文件就可以了,所以只需要add一个User.class
就可以了……
或者你在配置文件中去用<mapping resource="包名/User.hbm.xml"/>也是可以的。
注意:addClass还可以替换为addResource("包名/User.hbm.xml")!!!这也是可以的,
而且只要使用了addResource方法的话,映射文件可以任意命名!!
之所以以前一直用 实体类名.hbm.xml是因为使用的是addClass方法,而不是addResource,
要使用addClass必须得用默认的命名!
-------------------------------------
对配置文件和映射文件配置方法的小总结
一 配置文件
1.使用XML文件:(1)默认情况下,Hibernate会到类路径的根路径下(工程文件夹下)去找hibernate.cfg.xml文件,
这时候调用Configuration.configure()方法时,不需要传入任何参数
(2)如果使用了其他路径或其他文件名的话,在调用configure时要传入参数,参数类型可以是Document,
File或者是String类型。
2.使用property属性文件:文件名只能是hibernate.properties,而且在创建Configuration的时候
不用再调用configure方法,可以直接去调用buildSessionFactory。如果调用了
configure()方法的话,那么XML配置信息将会覆盖原来已经有的属性文件信息。
二 映射文件:
1 静态:直接在Hibernate.cfg.xml文件中,以mapping元素的形式加入映射文件,属性是resource,例如:
<mapping resource="包名/user.xml"/> 这里user.xml是映射文件
或者:<mapping file="f:/cfg/user.xml"/>
resource是往类路径中去找,file是去找本地的文件(要用完整的绝对路径!!)
2 动态:
(1)addClass方法:在类所在的包中去找与类同名的,并且以hbm.xml结尾的文件(不能任意命名映射文件)
(2)addFile方法:文件系统路径(可以任意命名映射文件)
(3)addResource方法:类路径(可以任意命名映射文件)
------------------------------------------------
SessionFactory和session使用时要注意的问题:
一个hibernate.cfg.xml文件与一个SessionFactory相对应,SessionFactory是重量级的,
一个应用程序中只创建一个SessionFactory就可以了,使用单例模式做到这一点。
单例模式也就是让那个类的构造方法私有,然后类的内部返回一个对象就可以,同时,把对象声明为私有静态的final常量对象!
这样整个应用程序中就只有一个对象了!
但是SessionFactory是公共的构造方法,SessionFactory用的不是单例模式,是使用了一个HibernateUtil辅助类,
是为了确保SessionFactory在整个应用程序中只有一个实例!
private static final SessionFactory sessionFactory;
static
{
try
{
sessionFactory = new Configuration.configure().buildSessionFactory();
}
catch(HibernateException ex)
{
throw new RuntimeException(ex.getMessage(),ex);
}
}
Session对象是非线程安全的,要保证一个线程只创建一个session
非线程安全:两个线程同时用一个session修改一个资源的话会造成冲突!!要保证一个线程里面只创建一个Session的话,
public static final ThreadLocal session = new ThreadLocal(); //ThreadLocal是线程本地变量
public static Session currentSession() throws HibernateException
{
Session s = (Session)thread.get();
if(s==null)
{
s = sessionFactory.openSession();
thread.set(s); //如果线程本地变量中没有Session的话,我就创建一个Session,然后把它塞进ThreadLocal中
//每个线程中都有一块儿ThreadLocal,只有该线程自己才可以访问这块存储空间!其他线程无法访问,该空间用来存储
//程序员自定义的对象。
}
return s ;
}
注意:java的每一个线程中有且仅有一个ThreadLocal,每个ThreadLocal里面仅仅能存放一个对象!!
如果使用HibernateUtil.currentSession的话,必须使用HibernateUtil.closeSession,
而不能使用session.close();
HibernateUtil类的closeSession方法:
public static void closeSession() throws HibernateException
{
Session s = (Session)thread.get(); //先从线程本地变量中得到要被关的session,然后将线程置空,然后再把session关掉!
//当然也可以先关掉session,然后再把线程置空,这是一样的。
thread.set(null);
if(s!=null) s.close();
}
注意:session.close()被调用后,是会话资源被关闭了,但是java虚拟机里面的引用仍然指向了那个对象
因为如果使用session.close()的话,session结束了,但是线程还没有结束呢,在线程本地变量中的session对象也被关了,
但是注意session对象仍然存在!!!
但是如果之后别人再次调用currentSession()方法的话,得到的session是已经被关闭的session,必然会有问题
我可以把s置为null值,但是注意的是thread必须设为null值,也就是thread.set(null)必不可少!因为currentSession()方法中,
有一个Session s = (Session)thread.get()语句,如果thread没有被置空的话,那么仍然会取出那个已经被关闭的对象!!这是
不能允许的,所以要把thread置空才行,不能简单的只是关闭session就完了。
- 12月8日——培训第16天
- 12月16日——培训第23天
- 12月3日——培训第12天
- 12月12日——培训第20天
- 1月16日——培训第47天
- 3月16日——培训第81天
- 12月1日——培训第10天
- 12月2日——培训第11天
- 12月4日——培训第13天
- 12月5日——培训第14天
- 12月7日——培训第15天
- 12月9日——培训第17天
- 12月10日——培训第18天
- 12月11日——培训第19天
- 12月14日——培训第21天
- 12月15日——培训第22天
- 12月17日——培训第24天
- 12月18日——培训第25天
- 正则表达式全部符号解释
- Repeater或者DataList中如果要使用Custom User Control可以使用如下方法
- 远程备份数据库
- 12月7日——培训第15天
- 寻找我的女孩儿。。。
- 12月8日——培训第16天
- 下面代码实现将 GridView 导出到 Excel文件中。
- XML基础 (4)
- 改就改
- 关于所谓的“软件学院”的问题
- 12月9日——培训第17天
- 用 ASP.NET 2.0 创建自定义 Web 控件
- 等待彼此
- Java SE 6.0 发布啦!