美文网首页
JAVA总结(六)

JAVA总结(六)

作者: wangxiaoda | 来源:发表于2017-08-20 23:32 被阅读67次

    持久层设计要考虑的问题有哪些?你用过的持久层框架有哪些?

    所谓”持久”就是将数据保存到可掉电式存储设备中以便今后使用,简单的说,就是将内存中的数据保存到关系型数据库、文件系统、消息队列等提供持久化支持的设备中。持久层就是系统中专注于实现数据持久化的相对独立的层面。
    持久层设计的目标包括:

    • 数据存储逻辑的分离,提供抽象化的数据访问接口。
    • 数据访问底层实现的分离,可以在不修改代码的情况下切换底层实现。
    • 资源管理和调度的分离,在数据访问层实现统一的资源调度(如缓存机制)。
    • 数据抽象,提供更面向对象的数据操作。

    持久层框架有:

    Hibernate中SessionFactory是线程安全的吗?Session是线程安全的吗(两个线程能够共享同一个Session吗)?

    SessionFactory对应Hibernate的一个数据存储的概念,它是线程安全的,可以被多个线程并发访问。SessionFactory一般只会在启动的时候构建。对于应用程序,最好将SessionFactory通过单例模式进行封装以便于访问。Session是一个轻量级非线程安全的对象(线程间不能共享session),它表示与数据库进行交互的一个工作单元。Session是由SessionFactory创建的,在任务完成之后它会被关闭。Session是持久层服务对外提供的主要接口。Session会延迟获取数据库连接(也就是在需要的时候才会获取)。为了避免创建太多的session,可以使用ThreadLocal将session和当前线程绑定在一起,这样可以让同一个线程获得的总是同一个session。Hibernate 3中SessionFactory的getCurrentSession()方法就可以做到。

    Hibernate三种状态的概念及互相转化

    image.png
    • 瞬时态:当new一个实体对象后,这个对象处于瞬时态,即这个对象只是一个保存临时数据的内存区域,如果没有变量引用这个对象,则会被JVM的垃圾回收机制回收。这个对象所保存的数据与数据库没有任何关系,除非通过Session的save()、saveOrUpdate()、persist()、merge()方法把瞬时态对象与数据库关联,并把数据插入或者更新到数据库,这个对象才转换为持久态对象。
    • 持久态:持久态对象的实例在数据库中有对应的记录,并拥有一个持久化标识(ID)。对持久态对象进行delete操作后,数据库中对应的记录将被删除,那么持久态对象与数据库记录不再存在对应关系,持久态对象变成移除态(可以视为瞬时态)。持久态对象被修改变更后,不会马上同步到数据库,直到数据库事务提交。
    • 游离态:当Session进行了close()、clear()、evict()或flush()后,实体对象从持久态变成游离态,对象虽然拥有持久和与数据库对应记录一致的标识值,但是因为对象已经从会话中清除掉,对象不在持久化管理之内,所以处于游离态(也叫脱管态)。游离态的对象与临时状态对象是十分相似的,只是它还含有持久化标识。

    简述Hibernate常见优化策略

    ① 制定合理的缓存策略(二级缓存、查询缓存)。
    ② 采用合理的Session管理机制。
    ③ 尽量使用延迟加载特性。
    ④ 设定合理的批处理参数。
    ⑤ 如果可以,选用UUID作为主键生成器。
    ⑥ 如果可以,选用基于版本号的乐观锁替代悲观锁。
    ⑦ 在开发过程中, 开启hibernate.show_sql选项查看生成的SQL,从而了解底层的状况;开发完成后关闭此选项。
    ⑧ 考虑数据库本身的优化,合理的索引、恰当的数据分区策略等都会对持久层的性能带来可观的提升,但这些需要专业的DBA(数据库管理员)提供支持

    谈一谈Hibernate的一级缓存、二级缓存和查询缓存

    Hibernate的Session提供了一级缓存的功能,默认总是有效的,当应用程序保存持久化实体、修改持久化实体时,Session并不会立即把这种改变提交到数据库,而是缓存在当前的Session中,除非显示调用了Session的flush()方法或通过close()方法关闭Session。通过一级缓存,可以减少程序与数据库的交互,从而提高数据库访问性能。
    SessionFactory级别的二级缓存是全局性的,所有的Session可以共享这个二级缓存。不过二级缓存默认是关闭的,需要显示开启并指定需要使用哪种二级缓存实现类(可以使用第三方提供的实现)。一旦开启了二级缓存并设置了需要使用二级缓存的实体类,SessionFactory就会缓存访问过的该实体类的每个对象,除非缓存的数据超出了指定的缓存空间。
    一级缓存和二级缓存都是对整个实体进行缓存,不会缓存普通属性,如果希望对普通属性进行缓存,可以使用查询缓存。查询缓存是将HQL或SQL语句以及它们的查询结果作为键值对进行缓存,对于同样的查询可以直接从缓存中获取数据。查询缓存默认也是关闭的,需要显示开启

    MyBatis中使用#和$书写占位符有什么区别?

    #将传入的数据都当成一个字符串,会对传入的数据自动加上引号;$将传入的数据直接显示生成在SQL中。注意:使用$占位符可能会导致SQL注射攻击,能用#的地方就不要使用$,写order by子句的时候应该用$而不是#

    解释一下MyBatis中命名空间(namespace)的作用

    在大型项目中,可能存在大量的SQL语句,这时候为每个SQL语句起一个唯一的标识(ID)就变得并不容易了。为了解决这个问题,在MyBatis中,可以为每个映射文件起一个唯一的命名空间,这样定义在这个映射文件中的每个SQL语句就成了定义在这个命名空间中的一个ID。只要我们能够保证每个命名空间中这个ID是唯一的,即使在不同映射文件中的语句ID相同,也不会再产生冲突了。

    MyBatis中的动态SQL是什么意思

    MyBatis中用于实现动态SQL的元素主要有:

    • if
    • choose / when / otherwise
    • trim
    • where
    • set
    • foreach

    下面是映射文件的片段

    <select id="foo" parameterType="Blog" resultType="Blog">
         select * from t_blog where 1 = 1
         <if test="title != null">
             and title = #{title}
         </if>
         <if test="content != null">
             and content = #{content}
         </if>
         <if test="owner != null">
             and owner = #{owner}
         </if>
    </select>
    

    当然也可以像下面这些书写

    <select id="foo" parameterType="Blog" resultType="Blog">
        select * from t_blog where 1 = 1
        <choose>
            <when test="title != null">
                and title = #{title}
            </when>
            <when test="content != null">
                and content = #{content}
            </when>
            <otherwise>
                and owner = "owner1"
            </otherwise>
        </choose>
    </select>
    

    再看看下面这个例子

    <select id="bar" resultType="Blog">
        select * from t_blog where id in
        <foreach collection="array" index="index"
            item="item" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>
    

    MVC思想

    MVC思想将一个应用分成三个基本部分:Model(模型)、View(视图)和Controller(控制器),这三个部分以最少的耦合协同工作,从而提高应用的可扩展性及可维护性。

    相关文章

      网友评论

          本文标题:JAVA总结(六)

          本文链接:https://www.haomeiwen.com/subject/lpytdxtx.html