概述
Jpa (Hibernate) debug
设置以下属性为true:
hibernate.show_sql=true //显示sql
hibernate.format_sql=true //格式化显示的sql
hibernate.use_sql_comments=true //显示sql注释,比如sql的执行方式:原生sql还是hql
hibernate.generate_statistics=true //开启统计功能,比如统计sql执行时间,返回的数据条数
此外还需配置org.hibernate.stat包的日志级别为DEBUG, 如logback.xml配置为:
<logger name="org.hibernate.stat" level="DEBUG" />
这样,我们在执行sql之后可以看到如下输出:
DEBUG o.hibernate.stat.internal.ConcurrentStatisticsImpl - HHH000117: HQL: 执行的sql语句, time: 1000ms, rows: 10000
可以看到返回10000条数据,耗时1秒
Tips:
如果用JUnit的方式运行,需要将logback.xml文件放在目录src/test/resources下面,否则logback.xml的
修改不会生效,从而无法看到debug语句的输出.
2018-03-16
使用spring-data-jpa实现持久层时, jpa提供了基本的持久化接口类:CrudRepository, JpaRepository.
接口中有对数据进行事务操作的save方法,可以做单条和批量操作。但是这个save方法实现的是插入数据或
更新数据的操作。当我只需要插入数据或是只需要更新一条(批)数据时,就没有现成的接口。 这个时候
就需要自定义repository实现。
【详细请参考Spring Data JPA-reference 文档】
自定义repository实现有两种方式:
方式一. 给单个repository创建自定义的repository实现;
方式二. 创建可以被多个repository使用的repository实现;
方式一:
示例1:
interface BatchRepository {
public void update(Customer customer);
}
class CustomerRepositoryImpl implements BatchRepository {
public void update(Customer customer) {
...
}
}
//修改主repository
interface CustomerRepository extends CrudRepository<User, Long>, BatchRepository
{
// Declare query methods here
}
Tips: 注意此处的实现类的类名必须是CustomerRepository + Impl, 就是说必须是主repository的名加上Impl,
使用其他名字的话, 编译时会报错:No property 方法名(此处为update) found for type 实体类名(此处为Customer)
方式二: 【该方式的实现类的类名没有实现方式一的限制】
示例二:
@NoRepositoryBean
public interface BatchRepository<T, ID extends Serializable>
extends Repository<T, ID> {
void update(ID id);
}
public class BatchRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements BatchRepository<T, ID> {
private final EntityManager entityManager;
//必须添加此构造器
public BatchRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Transactional
public List<T> update(List<T> list) {
for(int i=0; i<list.size(); i++){
//merge方法做数据更新, persist方法做数据插入, 具体请参考接口EntityManager
entityManager.merge(list.get(i));
}
entityManager.flush();
entityManager.clear();
return list;
}
}
//在配置类中声明此自定义的repository实现, 否则编译时报错:No property 方法名(此处为update) found for type 实体类名(此处为Customer)
@Configuration
@EnableJpaRepositories(repositoryBaseClass = BatchRepositoryImpl.class)
class ApplicationConfiguration { … }
2018-03-13
Tips:
Entity类里面的字段可以不是主表的字段, 用@Column(name="xxx")与查询语句里面的字段名(或别名)映射就可以了,
就像一个普通字段一样。
------------------------------------------------------------------------------------------------------------
1. 查询个别字段时(比如t.id, t.name, ...)易报Invalid column name(列名无效), 采用t.*的方式问题解决;
2. 采用@Id声明的字段,必须在查询出的结果集中具有唯一性;
否则,当被@Id声明的字段对应多条数据时,将会映射多条一样的数据到java类。
因此,当需要多个字段才能唯一确定一条数据的唯一性时,需要采用联合主键。
联合主键的声明如下:
step1: 创建一个联合主键类,该类采用注解类javax.persistence. Embeddable声明, 并且必须实现接口java.io. Serializable;包含对应的字段和其 getter/setter方法:@Embeddable
public class SalesManPk implements Serializable{
private static final long serialVersionUID = xxxxxxxxxxxxxL;
private long id;
private Date date;
public long getId(){return id;}
public void setId(long id){ this.id = id;}
public Date getDate(){return date;}
public void setDate(Date date){this.date = date;}
}
step2: 在与表映射的类里面引用该联合主键类和字段, 需要给字段添加getter/setter方法:
@Entity
@ IdClass(SalesManPk.class)
@Table(name = "t_sales_performance")
public class SalesPerformance {
@Id
@Column(name = "id")
private long id;
@Id
@Column(name = "date")
private Date date;
public long getId(){return id;}
public void setId(long id){ this.id = id;}
public Date getDate(){return date;}
public void setDate(Date date){this.date = date;}
/* 省略其他相关字段 */
}
最后
以上就是震动咖啡为你收集整理的Spring Data Jpa 学习笔记的全部内容,希望文章能够帮你解决Spring Data Jpa 学习笔记所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复