Java对象的持久化,将对象入库保存以及取出转换成对象实例

一、对于一个简单的实体类而言,比如学生类,商品类,订单类等,他们的属性只包含简单类型属性,我们通常的做法是直接入库保存各个字段或直接保存一个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>(User.class));
        } catch (Exception e) {
            return null;
        }
    }

直接使用JdbcTemplate然后给一个返回类型new BeanPropertyRowMapper<User>(User.class)即可,返回查询结果。

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();
    }

执行结果:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hibernate是一个开源的Java对象持久化框架,它提供了一种方便的方式来将Java对象映射到数据库的表,从而实现对象持久化。下面是对Hibernate进行详细解释。 首先,Hibernate是基于ORM(对象关系映射)的技术。ORM是一种编程技术,它允许开发人员将Java对象数据库表进行映射。通过Hibernate,开发人员只需要在Java类的注解或XML配置文件定义对象的映射关系,就能够实现对象数据库之间的转换。 其次,Hibernate提供了丰富的查询语言。Hibernate提供了一种称为HQL(Hibernate Query Language)的查询语言,它类似于SQL,但更加面向对象。开发人员可以利用HQL进行复杂的查询操作,而不需要直接编写SQL语句。 此外,Hibernate还支持事务管理。在Hibernate,开发人员可以通过事务来管理数据库操作的一致性和原子性。通过使用Hibernate的事务管理,开发人员能够确保多个数据库操作在一个事务执行,避免了数据不一致的问题。 另外,Hibernate还具有缓存功能。Hibernate提供了一级缓存和二级缓存,开发人员可以利用这些缓存来提高数据访问的性能。一级缓存是Hibernate默认的缓存机制,它将查询操作的结果缓存到Session对象,减少了与数据库的交互次数。二级缓存是可选的,它将查询操作的结果缓存到SessionFactory,用于多个Session之间的共享。 最后,Hibernate还具备透明的数据库操作功能。通过Hibernate,开发人员可以使用面向对象的方式进行数据库操作,而不需要关心底层数据库的细节。Hibernate会自动处理数据库连接、SQL语句的生成和执行等操作,极大地简化了数据库操作的过程。 综上所述,Hibernate作为一种Java对象持久化技术,提供了方便的对象数据库之间的映射方式,丰富的查询语言,事务管理,缓存机制和透明的数据库操作功能。它的出现极大地简化了开发人员对数据库的操作,提高了开发效率和代码的可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值