JPA:DAO层的一个框架,简化了SQL,据说前身是SSH 中的Hibernate,所以他给我的感觉和Hibernate很类似,目的都是为了减少SQL语句的使用,尽可能用“注解”和“方法”代替SQL语句。
但是为了减少SQL的书写,它必然会在其他方面更复杂一些,例如他构造主体类的时候需要在每个参数上加上一些注解,来说明这个实体类在数据库中的定位:
@Column(name = "user_id")
@Id private
Long userId;
它使用方法之前,往往需要先构造一个UserRepository 的接口,继承JpaRepository<User, Long>,来指定主键类型和实体类。
然后就可以使用他的内置的方法了:save方法完成插入,用findAll方法完成查询。findById方法根据id查询等等。
但面对一些复杂查询的时候还是得需要老老实实来写SQL:
通过@Query注解来写原生SQL
@Query("update User set username=?1 where id=?2")
int updateUsernameByIds(String username,Long id)
与mybaties的对比还是比较明显的,我们日常用mybaties都是在Mapper类中定义很多方法,
public interface IUserMapper {
\* 查询所有操作 \*
List<User> findAll();
然后在XML配置文件中声明一个和Mapper同名的结构体,namespace来指定包名.类名,id来指定方法名
<mapper namespace="com.Mapper.IUserMapper" >
<select id="findAll" resultType="com.Pojo.User" >
select * from usr
</select>
</mapper>
说实话,用惯了mybaties,感觉这个JPA也就那样。
另外,之前接手的一个小项目上还用过mybatiesPlus,那个框架给我的感觉还不如这俩,明明都是为了简化开发而创造的,但是mybatiesPlus有额外的学习成本,需要一套专门的业务语句,当时刚接手那个项目的时候,想写几个业务语句没把我难死。
类似这种:
@Override
public IPage<ProductBean> findByItem(Integer pageNO,
String name, LocalDate startDate, LocalDate endDate) {
QueryWrapper<ProductBean> qw = new QueryWrapper<>();
if (name != null && name.length() != 0){
qw.like("p_name",name);
}
if (startDate != null){
qw.ge("p_createDate",startDate);
}
if (endDate != null){
qw.le("p_createDate",endDate);
}
return mapper.selectPage(new Page(pageNO,3),qw);
}
它相当于没有业务层,把所有业务层的操作全都用SQL来实现了,说实话我个人浅薄的认为这有点违背MVC结构初衷。
另外关于mybatis什么时候用#,什么时候用$:
大部分时候都用#,因为可以有效防止SQL注入,但有的时候不得不用$,比如有一次有一个业务,我需要先用
select table_name from information_schema.tables where table_schema='csdb' and table_type='base table';
查询出所有的表名,再根据表名去查一个特定的表,此时表名会被当成参数传入,这时如果还继续用#就会把表名识别为字符串,会报SQL语法错误,因此要使用$.
<select id="findUserListByIdList" parameterType="java.lang.Long" resultType="User">
select * from ${tableName} where id = #{id};
</select>