JPA思想架构、Mybatis与Hibernate、通用Mapper的使用

JPA思想架构、Mybatis与Hibernate、通用Mapper的使用


  1. 什么是JPA?

    ​ JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中

    ​ 传统的数据库操作,以编写sql语句的方式,这种方式是面向过程的编程语言。由此提出,是否能以面向对象的方式操作数据库?如:insert(User)是实现新增的操作。

  2. JPA的起源与发展

    ​ JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分。但它又不限于EJB 3.0,你可以在Web应用、甚至桌面应用中使用。JPA的宗旨是为POJO提供持久化标准规范,由此可见,经过这几年的实践探索,能够脱离容器独立运行,方便开发和测试的理念已经深入人心了。Hibernate3.2+、TopLink 10.1.3以及OpenJPA都提供了JPA的实现。

    ​ 以Hibernate为例,操作数据库时,其原理是将对象通过反射的方式再次编译为sql语句。这种方式会在底层生成多条的sql语句,因此在数据量较大的数据库中性能较低。假设在执行insert(User)的sql操作时,会首先查询数据库中是否还有该数据,如果没有,再执行insert语句。

    ​ 之后,经过Hibernate时代后便产生Mybatis框架,其优点在于继承了Hibernate自动化的映射,通过直接操作sql的方式提高性能。目前,许多开源社区(github、gitee等)也开放了通用mapper工具类方便减少sql语句的编写。

  3. Hibernate与Mybatis

​ MyBatis,编写原生态Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

​ Hibernate,完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。通过它强大的映射结构和hql语言,大大降低了对象与数据库(oracle、mysql等)的耦合性,而mybatis由于需要手写sql,因此与数据库的耦合性直接取决于程序员写sql的方法,如果sql不具通用性而用了很多某数据库特性的sql语句的话,移植性也会随之降低很多,成本很高。

区别 Hibernate Mybatis
特性 较完整的ORM映射 基本的字段映射
日志系统 较健全,涵盖异常,优化、缓存、sql记录、脏数据警告等 基本功能
使用 配置复杂,开发效率低,可移植 容易上手
性能 不易维护,有局限性 灵活度较高,直接操作sql
耦合度 强大的映射,低耦合 取决于sql编写,通用性较低
缓存机制 较好,还可以使用第三方缓存 二级缓存机制较差
  1. JPA三大技术

    • ORM映射元数据

      JPA支持XML和JDK5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中

    • API

      用来操作实体对象,执行CRUD操作,框架在后台替代我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来

    • 查询语句

      这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

  2. JPA的优势

    ​ JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。

    具有容器级特性的支持

    ​ JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。

  3. 通用mapper(abel533)的使用

    (以主流框架mybatis为例)

    6.1 引入依赖或导入jar包

    <!-- 通用Mapper -->
    <dependency>
    <groupId>com.github.abel533</groupId>
       <artifactId>mapper</artifactId>
       <version>${mapper.version}</version>
    </dependency>
    <!-- 依赖于JPA的注解 -->
    <dependency>
     <groupId>javax.persistence</groupId>
     <artifactId>persistence-api</artifactId>
     <version>1.0</version>
    </dependency>

    6.2 Mapper插件引入

    <!-- mybatis-config.xml -->
    <configuration>
    ...
        <!-- 通用Mapper插件 -->
        <plugins>
        <plugin interceptor="com.github.abel533.mapperhelper.MapperInterceptor">
            <!--主键自增回写方法,默认值MYSQL,详细说明请看文档 -->
            <property name="IDENTITY" value="MYSQL" />
            <!--通用Mapper接口,多个通用接口用逗号隔开 -->
            <property name="mappers" value="com.xxx.mapper.XxxMapper" />
        </plugin>
    </plugins>
    </configuration>

    6.3 定义Mapper接口

    • mybatis的注解形式用法
    import java.util.List;   
    import org.apache.ibatis.annotations.Delete;  
    import org.apache.ibatis.annotations.Insert;  
    import org.apache.ibatis.annotations.Select;  
    import org.apache.ibatis.annotations.Update;  
    
    //此处省略User对象的创建  
    public interface UserMapper {  
       @Select("select * from user")  
       public List<User> getSelectUser();  
       @Update("update user set userName=#{userName} where id=#{id}")  
       public void getUpdateUser(User user);  
       @Insert("insert into user(userName,userAge) values(#{userName},#{userAge})")  
       public void getInsertUser(User user);  
       @Delete("delete from user where id=#{id}")  
       public void getDeleteUser(int id);      
    } 
    • 通用Mapper的调用形式

      定义Mapper接口继承通用Mapper<泛型>,此处必须指定泛型

    public interface ItemMapper extends 通用Mapper<Item>{
    List<Item> findAll();
    }
    //架构Pojo对象
    @Table(name="tb_item") //与数据库中表名对应
    public class Item extends BasePojo{  
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;//商品id号
    private String title;//商品标题
    private String sellPoint;//商品卖点信息
    private Long price;//商品价格
    private Integer num;//商品数量
    private String barcode; //条形码   
    private String image;//商品图片信息
    private Long cid;//商品分类id
    private Integer status;//状态 1:正常 2:下架 3:删除
     //setter、getter方法

    ​ a)表名默认使用类名,驼峰转下划线,如UserInfo默认对应的表名为user_info.

    ​ b)表名可以使用@Table(name = "tableName")进行指定,对不符合第一条默认规则的可以通过这种方式指定表名.

    ​ c)字段默认和@Column一样,都会作为表字段,表字段默认为Java对象的Field名字驼峰转下划线形式.

    ​ d)可以使用@Column(name = "fieldName")指定不符合第3条规则的字段名

    ​ e)使用@Transient注解可以忽略字段,添加该注解的字段不会作为表字段使用.

    ​ f)建议一定是有一个@Id注解作为主键的字段,可以有多个@Id注解的字段作为联合主键.

    ​ g)默认情况下,实体类中如果不存在包含@Id注解的字段,所有的字段都会作为主键字段进行使用(这种效率极低).

后续如有想了解通用Mapper底层的原理实现的,欢迎交流讨论~~~

​ 1.通用Mapper的架构思路的引入

import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
import org.apache.ibatis.scripting.xmltags.MixedSqlNode;
import org.apache.ibatis.scripting.xmltags.SqlNode;
import org.apache.ibatis.scripting.xmltags.StaticTextSqlNode;
import com.github.abel533.mapper.MapperProvider;
import com.github.abel533.mapperhelper.EntityHelper;
import com.github.abel533.mapperhelper.MapperHelper;

​ 2.通过反射动态执行sql的过程

​ ……

猜你喜欢

转载自blog.csdn.net/han0373/article/details/79101008
今日推荐