gpt4 book ai didi

java - EJB和preparedStatement?

转载 作者:行者123 更新时间:2023-11-29 18:11:17 25 4
gpt4 key购买 nike

我正在开发一个 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”的方法(编辑:不是 EJB)?

  • 如果我必须这样做,PreparedStatement 是否包含在容器管理的事务中?

<小时/>

另一个编辑:上面的代码完成了这项工作 - 我现在已经测试了它。但我认为这并不漂亮。

最佳答案

要以 JPA 方式持久保存 BLOB 值,您要做的第一件事就是定义一个实体。下面是一个伪代码示例:

@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 的基础知识时,这个答案才会对您有帮助。和here是网络上众多教程中关于 JPA 持久性的官方教程。

更新

I would like not to use JDBC directly - is there a way to do this that is 'pure JPA'

没有。

If I have to do it this way, is the PreparedStatement included in the container managed transaction?

没有。但您可以使用 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 ...;
}
...
}

关于java - EJB和preparedStatement?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47391187/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com