总结了一下,这两天开发中的觉得有用的东西
1. Oracle中的sequence
我有两个表,一个是物资表,其主键是数据库自增序列,另一个表是物资明细表,其主键也是自增序列,物资表的主键是此表的外键。现在我有一个插入的操作,需要现在物资表里插入一条数据(id插入使用s_id.nextval,s_id表示序列),然后在物资明细表中也对应的插入数据。然后,问题产生了,当我需要插入物资明细表的时候由于不知道物资表的id是多少,导致没法进行操作。据了解,如果使用了hibernate的话,能够直接配置好了拿到此id,可是我们的项目只用了struts+sping。
别人给的解决方案:
(1) 将这两个表的操作放到一个事务中去做,物资表插入完之后,直接查找该表拿到最后一个插入的id进行操作。
(2) 使用s_id的nextval和currval操作,由于每次使用currval的时候必须是先进行过nextval操作,如果插入之后使用查询currval取值,这样取到的值肯定是正确的,不用考虑是否有别人同时也对此表进行操作,导致取出的值不一样,这个方法我尝试了,但由于在一个方法中要两次执行sql语句,觉得太麻烦。
(3) 最后我才明白了sequence是怎么回事,在数据库中sequences和表是独立的,如果在设计数据库表的时候,比如id字段不让它绑定序列值,这样序列就是自己增加,和id没关系。所以解决方法就是,在插入数据库表的时候首先使用sql语句:
"select s_id.nextval from dual"拿到唯一的id,然后使用这个id进行插入操作。以前很纠结是因为总以为只要没有插入操作,nextval是从数据库表中具体数据的下一条开始的,真是无知啊。
2. Oracle中的dual表是什么东西
因为发现在数据库中没有存在dual表,却可以进行操作,原来dual是oracle数据库的虚表,是Oracle与数据字典一起自动创建的一个表,只有一行一列,返回值只有一条数据,即使进行的是多条数据的操作,这样像调用系统时间select to_char(SYSDATE,'yyyy-mm-dd hh24:mi:ss') from dual之类的都可以使用,真是简便。
3. 在J2EE项目中对数据库中的BLOB类型数据的读取
(1)sping中的配置
<bean id="defaultLobHandler"
class="org.springframework.jdbc.support.lob.DefaultLobHandler"
lazy-init="true" />
(2) 在DAOImpl中添加资源及对应的setter getter
@Resource
private LobHandler lobHandler;
(3) 对于插入数据库方法add(),使用jdbcTemplate的时候请使用lobCreator,例子如下:
jdbcTemplate.execute(sql,new AbstractLobCreatingPreparedStatementCallback(this.lobHandler)
{ protected void setValues(PreparedStatement ps,LobCreator lobCreator)
throws SQLException
{
ps.setString(1, bean.getDeviationReportNumber());
ps.setString(2, bean.getMaterialsName());
lobCreator.setBlobAsBytes(ps, 3, bean.getDeviationReportAttachment());
}
});
(4) 对于读取数据库方法,使用jdbcTemplate时请使用lobHandler.getBlobAsBytes,例子如下:
jdbcTemplate.query(sql, new AbstractLobStreamingResultSetExtractor() {
protected void streamData(ResultSet rs) throws SQLException,IOException
{
reportBean.setId(rs.getLong("ID"));
reportBean.setDeviationReportAttachment(lobHandler
.getBlobAsBytes(rs, 9));
}
}, params);
4.InputStream与byte[]转换
private byte[] InputStreamToByte(InputStream is) throws IOException {
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
int ch;
while ((ch = is.read()) != -1) {
bytestream.write(ch);
}
byte imgdata[] = bytestream.toByteArray();
bytestream.close();
return imgdata;
}
5.使用struts2实现文件上传与下载
(1)文件的上传是在jsp页面中使用<s:file />即可生成一个“浏览”按钮,在写一个 在action中对文件进行处理。
(2)文件下载
在struts.xml中配置如下:
<action name="download" class="com.cnpc.action.MaterialReceiveAction" >
<result name="success" type="stream">
<param name="contentType">application/msword</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename="${exportFilename}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
在action中写:
/**
* 获取下载文件名 中文名
* @return
*/
public String getExportFilename()
{
try {
return new String(this.exportFilename.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "default";
}
}
public void setExportFilename(String exportFilename) {
this.exportFilename = exportFilename;
}