我正在使用eclipse-link,我正在从表中检索数据并尝试使用JAXB将检索到的数据存储到XML文件中。写入XML文件时,最后一条记录只保存在该文件中。
这里用户是我的POJO类有两个字段
@XmlRootElement
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
@XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User()
{
}
}
以下是我的代码:
public class ObjectToXml {
private static int startingIndex = 0;
private static int maxIndex= 10;
public static void main(String[] args) {
EntityManager entityManager = EntityManagerUtil.getEmf()
.createEntityManager();
Query query = entityManager.createQuery("Select u from User u");
System.out.println("Total Number of Records"
+ query.getResultList().size());
try {
JAXBContext contextObj = JAXBContext.newInstance(User.class);
Marshaller marshallerObj = contextObj.createMarshaller();
marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
query.setFirstResult(startingIndex );
query.setMaxResults(maxIndex);
List<User> user = query.getResultList();
Iterator iterator = user.iterator();
while (iterator.hasNext()) {
User student = (User) iterator.next();
MarshallerObj.marshal(student, new FileOutputStream("User.xml"));
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
entityManager.close();
}
}
}
这里我得到10条记录。但是存储最后一条记录只保存在XML中
我的结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<user id="10">
<name>prabha</name>
</user>
答案 0 :(得分:1)
也许你应该保留一个FileOutputStream
并连续编入其中,而不是每次迭代都创建一个新的。{/ p>
答案 1 :(得分:1)
因为MarshallerObj.marshal(student, new FileOutputStream("User.xml"));
每次创建新文件o / p流并清除prev内容。从while循环中创建此o / p流实例。应该有所帮助。
答案 2 :(得分:1)
由于您要为每个用户对象创建xml文件,因此当程序从数据库中获取新用户时,对象将继续替换 因此,创建一个POJO类用户,其中包含用户列表作为属性,
public class Users
{
//Users grouping
private List<User> user;
public void setUser(List<ProductInfo> userInfo)
{
this.user = userInfo;
}
@XmlElement(name="user")
public List<User> getUser() {
return user;
}
}
然后在代码部分为类用户创建 JAXBContext 的实例,如下所述
JAXBContext contextObj = JAXBContext.newInstance(Users.class);
现在修改while循环以将所有用户的信息设置为 Users 对象,并 marshar Users对象,而不是编组用户对象。< / p>
Users users = new Users();
while (iterator.hasNext()) {
User student = (User) iterator.next();
users.setUser(student);
}
MarshallerObj.marshal(users, new FileOutputStream("User.xml"));
答案 3 :(得分:1)
您需要使用@XmlElements
注释。
Marshaller.marshal()
只是将对象转换为字节流并写入输出流。因此,它将覆盖ouputstream中的现有数据。在您的情况下,由于marshallerObj.marshal(student, new FileOutputStream("User.xml"));
位于循环内,因此最终文件将始终包含列表中的最后一个对象。即,在第一次迭代中,它将第一个对象写入文件,在第二次迭代中,它将用第二个对象覆盖文件,在第三次迭代中,它将用第三个对象覆盖文件,依此类推。
要编组对象列表,其中一个解决方案是创建一个容器对象,该对象将维护所有用户/学生的列表,然后封送容器对象。
有关类似问题,请参阅link。
在您的情况下,容器类应该类似于:
@XmlRootElement(name = "Users")
public class Users
{
private List<User> users = new ArrayList<User>();
@XmlElements(value = {@XmlElement(name = "User", type = User.class)})
@XmlElementWrapper
public List<User> getUsers() {
return users;
}
public void addUser(User user) {
users.add(user);
}
}
编组用户的代码:
Users users = new Users();
List<User> usersList = query.getResultList();
for(User user : usersList) {
users.addUser(user);
}
marshallerObj.marshal(users, new FileOutputStream("User.xml"));