我正在开发一个Web应用程序,除其他外,我需要将文件上传到mysql表中的BLOB列。从我可以看到这可以通过JDBC调用(PrepareStatement()等)完成,但我希望能够在EJB类中完成此操作 - 我拼凑在一起的内容如下所示:
@Stateless
public class ItemsSession {
@PersistenceContext(unitName ="officePU")
private EntityManager em;
private List<Items> itl;
private static final Logger logger=
Logger.getLogger(ItemsSession.class.getName());
...
public String updateDocument(Integer id,InputStream is) throws SQLException{
String msg="";
try{
java.sql.Connection conn = em.unwrap(java.sql.Connection.class);
PreparedStatement pstmt=conn.prepareStatement("UPDATE Documents SET doc = ? WHERE id = ?");
pstmt.setBinaryStream(1, is);
pstmt.setLong(2, id);
pstmt.executeUpdate();
pstmt.close();
}
catch (PersistenceException e){
msg=e.getMessage();
}
return msg;
}
...
}
但我有两个问题:
我不想直接使用JDBC - 有没有办法做到这一点,纯粹的JPA&#39; (编辑:不是EJB)?
如果我必须这样做,PreparedStatement是否包含在容器管理的交易中?
另一个编辑:上面的代码完成了工作 - 我现在已经测试过了。但我觉得它并不漂亮。
答案 0 :(得分:0)
我认为您使用EJB intergate与JPA,因为您正在使用它:
@PersistenceContext(unitName ="officePU")
参考:http://www.adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_for
答案 1 :(得分:0)
要保持BLOB值JPA方式的第一件事就是定义一个实体。以下是一个示例pseodo代码:
@Entity
public class Documents {
@Id
private Long id;
@Lob
private byte[] doc;
// .... getters + setters
}
然后按如下方式修改EJB:
@Stateless
public class ItemsSession {
@PersistenceContext(unitName ="officePU")
private EntityManager em;
// ... the rest of your code
public String updateDocument(Integer id,InputStream is) throws SQLException{
String msg = "";
Documents docs = em.find(Documents.class, id); // fetch record from DB
// Assuming your InputStream is a ByteArrayInputStream
byte[] doc = new byte[is.available()]; // create target array
is.read(doc, 0, doc.length); // read bytes into byte array
docs.setDoc(doc); //
return msg; // returning exception message from method call?????
}
...
}
如果您没有更改默认值,默认情况下会在事务中调用EJB方法。因此,当您的方法退出时,更新应该与数据库同步。
如果您阅读并理解JPA的基础知识,这个答案kann只会帮助您。 here是JPA持久性在网络上其他许多教程中的官方教程。
<强>更新强>
我不想直接使用JDBC - 有没有办法做到这一点纯粹的JPA&#39;
没有
如果我必须这样做,PreparedStatement是否包含在容器管理事务中?
没有。但是你可以使用bean管理的事务。如果您想使用BMT,以下伪代码可能会对您有所帮助:
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class ItemsSession {
@Resource UserTransaction ut;
@Resource DataSource datasource; // you should define datasource on your application server
...
public String updateDocument(Integer id,InputStream is) throws SQLException{
// ...
try (java.sql.Connection conn = datasource.getConnection();
PreparedStatement pstmt=conn.prepareStatement("UPDATE Documents SET doc = ? WHERE id = ?")) {
pstmt.setBinaryStream(1, is);
pstmt.setLong(2, id);
ut.begin();
pstmt.executeUpdate();
ut.commit();
} catch (PersistenceException e){
// ... error handling
}
return ...;
}
...
}