一、对于一个简单的实体类而言,比如学生类,商品类,订单类等,他们的属性只包含简单类型属性,我们通常的做法是直接入库保存各个字段或直接保存一个JsonString字符串,取出时直接查询转换即可。
1)比如查询出用户信息:
public User getUser(String userId, String password) {
try {
final Object[] obj = new Object[]{userId, password};
return this.jdbcTemplate.queryForObject("select * from t_user where userId=? and password=?", obj, new BeanPropertyRowMapper(User.class));
} catch (Exception e) {
return null;
}
}
直接使用JdbcTemplate然后给一个返回类型new BeanPropertyRowMapper
2)查询出JsonString 类型数据
public FtpBean getFtpBean() {
FtpBean ftpBean = null;
try {
String ftp = this.jdbcTemplate.queryForObject("select newValue from SYS_LOG where type ='1006' order by opttime desc limit 1", String.class);
ftpBean = JSONObject.parseObject(ftp, FtpBean.class);
} catch (EmptyResultDataAccessException e) {
e.printStackTrace();
}
return ftpBean;
}
查询出一个JsonString字符串后,使用fastjson做一个转换就行了。
------------------------------------------------------------------------分割线------------------------------------------------------------------------
----重点来了 >>>>>>>>>>>
当我们的需要保存的对象中依赖其他对象,比如我们聊天系统中的一条messsge:
public class Message implements Serializable {
private static final long serialVersionUID = -7386510778099026418L;
private String msgId;
private ChatType chatType = ChatType.Chat;
private Direct direct;
private Status status;
private Type type;
private String from;
private String to;
private long localTime;
private int progress = 0;
private long msgTime;
private boolean unread;
private boolean isListened;
private EMCallbackHolder messageStatusCallBack;
private transient TranState transtat;
private MessageBody body;
// Setter/Getter 略
}
消息中不仅有msgId,发送时间(localTime)等这些简单类型的属性,还有“消息的类型”ChatType,消息状态Status等这些枚举类型的属性,当然还会有一些其他对象类型的属性,如:消息的监听EMCallbackHolder, 消息的body抽象类:MessageBody,他可以是 一个文本消息 TextMessageBody,图片: ImageMessageBody,视屏: EMVideoMessageBody,语音:EMVoiceMessageBody,文件:EMFileMessageBody等这些实现类,去完成不同消息体的属性。
像这种messsge实体类的入库保存,简单类型的可以创建字段 一一对应保存或者直接toJsonString保存,但是其中的监听类、消息体类,我们就需要进一步拆分,然后将这些对象中的属性也保存,OK,入库虽然有点小麻烦,还可以解决;当我要你取出时,还原成这个message对象时,是不是 又要比保存时更麻烦了,你需要把 MessageBody根据类型是文本、图片、文件的属性值从新初始化,然后监听重新初始化,然后再把message初始化,最后再将这些对象类型的属性,setter到消息类型。
对于这种比较复杂的实体类,我没可以,使用持久化保存到数据库,使用时直接转换即可。
步骤:
1)实体类实现 Serializable
Student.java 以及内部类 enum sex.java
public class Student implements Serializable {
private String id;
private String name;
private int age;
// 性别 enum
private Student.sex sex;
// 课程抽象类
private Course course;
// setter/getter 略
public static enum sex {
MALE, FEMALE;
}
}
课程抽象类: Course.java
public abstract class Course implements Serializable {
private static final long serialVersionUID = -7386510778099026418L;
}
public class English extends Course {
public void Say() {
System.out.println("You had select English..");
}
}
public class PE extends Course {
public void Say() {
System.out.println("You had select PE..");
}
}
2)数据库表 ,注意这里 字段类型要设置成 blob
CREATE TABLE `chat_msg` (
`id` int(20) NOT NULL,
`content` blob
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3) 入库保存转换成字节数组保存入库:
private static void insert() {
String jdbcDriver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/agcc?characterEncoding=UTF-8";
String userName = "root";
String password = "root123456";
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection con = null;
try {
Student student = new Student();
student.setId("123");
student.setName("xiaoww");
student.setAge(16);
student.setSex(Student.sex.FEMALE);
// 设置课程为英语实体类
student.setCourse(new English());
con = DriverManager.getConnection(url, userName, password);
String sql = "insert into chat_msg(`id`, `content`) values(?,?)";
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(byteArrayOutputStream);
oo.writeObject(student);
byte[] bytes = byteArrayOutputStream.toByteArray();
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, student.getId());
pstmt.setBytes(2, bytes);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
调用测试方法:
public static void main(String[] args) {
insert();
}
插入成功
4)取出转换成对象实例
public static void buildStudent() {
String jdbcDriver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/agcc?characterEncoding=UTF-8";
String userName = "root";
String password = "root123456";
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection con = null;
try {
con = DriverManager.getConnection(url, userName, password);
String sql = "select content from chat_msg where id=?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, "123");
ResultSet resultSet = pstmt.executeQuery();
while (resultSet.next()) {
byte[] bytes = resultSet.getBytes(1);
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
// 直接转换成Student实体类
Student student = (Student) objectInputStream.readObject();
// 获取Student实体类中课程类 Course,上面存进去的是Englis。这里转成Englis
English english = (English) student.getCourse();
english.Say();
}
} catch (Exception e) {
e.printStackTrace();
}
}
测试调用执行:
public static void main(String[] args) {
buildStudent();
}
执行结果: