1.新建register.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <form action="save.action"> username:<input type="text" name="username"><br> password:<input type="text" name="password"><br> <input type="submit" value="submit"> </form> </body> </html>
2.新建listAll.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript"> function del() { if(confirm("are you sure")) { return true; } return false; } </script> </head> <body> <table width="80%" align="center" border="1"> <tr> <th>username</th> <th>password</th> <th>delete</th> </tr> <s:iterator value="#request.list" id="user"> <tr> <td><s:a href="getUser.action?username=%{#user.username}"> <s:property value="user.username" /></s:a></td> <td><s:a href="getUser.action?username=%{#user.username}"></s:a> <s:property value="user.password" /></td> <td><s:a href="deleteUser.action?username=%{#user.username}" onclick="return del()">delete</s:a></td> </tr> </s:iterator> </table> </body> </html>
3.运行后查看控制台会有错误信息显示:
出现了增加用户出现异常,这段代码在UserAction.java中:
说明session.save()没有执行成功,插入数据不成功有几种可能呢,无非是字段类型有错误,主键出现问题,那么我们来看看一看我们的主键就会发现问题:
不知道同学们对前两节的内容有没有什么质疑?那就是主键,我们之前设定主键的生成方式为increment也就是自增方式,什么是increment方式?
对 long , short 或 int 的数据列生成自动增长主键。increment主键生成方式的特点是与底层数据库无关性,大部分数据库如 Mysql,MSSQL 和ORACLE等都支持increament生成方式。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的 时候将此值加1作为主键。increment方式的不足之处是当多个线程并发对数据库表进行写操作时,可能出现相同的主键值,发生主键重复的冲突,因此多线程并发操作时,不应该使用此方法。
显然我们的主键username不应该适应此种方式,而应该用assigned:
主键由外部程序负责生成,无需Hibernate参与。----如果要由程序代码来指定主键,就采有这种.
还有其他几种主键的生成方式:
identity:
如果数据列的类型是 long, short 或 int ,可使用主键生成器生成自动增长Hibernate主键。与底层数据库有关,要求数据库支持identify,如MySQL中是auto_increment,SQL Server中是Identify.支持的数据库有MySQL,SQL Server,DB2,Sybase和HypersonicSQL.(好像不支持oracle) 无需Hibernate和用户的干涉,使用较为方便,但不便于在不同的数据库之间移植程序。identity的优点是不会发生 increment方式的并发错做问题。数据库涉及到的表要设置自动增长。
sequence:
在ORACLE等数据库中使用sequence生成主键。sequence的特点是于数据库的相关性,seqhio要求底层能支持sequence,列如Oracle。
hilo:
通过hi/lo 算法生成主键,需要一个表来保存额外的主键信息。这样生成的标识符只在特定的数据库是唯一的,在使用JTA(Java分布式事务) 获得链接或用户自定义提供的链接中,不要使用这种生成器。hilo方式需要维护表信息,因此对数据的影响的要率会造成一定影响。
seqhio:
与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle。如果数据列的类型是 long, short 或 int可使用该主键生成器。
native:
由Hibernate根据不同的数据库方言,自行判断采用identity、hilo、sequence其中一种作为Hibernate主键生成方式,native的 优点是与底层性无关,便于不同数据库之间的移植,由Hibernate根据不同数据库选择主键的生成方式。在oracle中需要创建叫 Hibernate_sequence名字的sequence,如果设置了Hibernate.hbm2ddl.auto属性,不需要手动建立序列,前提 是数据库帐号必须有Create Sequence这种高级权限。mysql等数据库则不用建立sequence。
uuid.hex:
采用基于128位的算法生成唯一值,并编制成32位长度的唯一字符串作为主键值,uuid.hex的优点是支持大部分数据库,缺点就是要占用较大的存储空间。对于并发Insert要求较高的系统,推荐采用uuid.hex 作为主键生成机制。
uuid.string:
使用UUID算法,UUID被编码为一个16个字符长的任意ASCII字符组成的字符串。不能在PostgreSQL数据库中使用。uuid.string同uuid.hex类似,需要占很大的存储空间。
好,我们改变一下主键的生成方式吧:
执行register.jsp,点击提交按钮,运行结果:
添加一些数据后后有如下显示:
我们庆祝一下吧,说明我们插入数据成功了:
查看数据库会发现数据库中的确增加数据了。