前言:JPA全稱Java Persistence API.JPA經過JDK 5.0註解或XML描述對象-關係表的映射關係,並將運行期的實體對象持久化到數據庫中,在Spring 2.0.1中,正式提供對JPA的支持,這也促成了JPA的發展,要知道JPA的好處在於能夠分離於容器運行,變得更加的簡潔。以前上一家公司就是用的jpa,感受很簡單,特別是註解的實現徹底解決了xml配置的繁瑣,這個案例只是一個超級簡單的demo,若是須要分頁和一對多關聯關係須要本身查閱一下其餘資料,反正我是不推薦使用join 創建表關聯關係。java
1 .導入maven依賴mysql
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
2.配置數據庫鏈接屬性spring
spring.datasource.url=jdbc:mysql:///test?useUnicode=true&characterEncoding=utf8&autoReconnect=true spring.datasource.username=root spring.datasource.password=root spring.datasource.driverClassName=com.mysql.jdbc.Driver # Specify the DBMS spring.jpa.database=MYSQL # Show or not log for each sql query spring.jpa.show-sql=true # Hibernate ddl auto (create, create-drop, update) spring.jpa.hibernate.ddl-auto=update # Naming strategy spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy # stripped before adding them to the entity manager) spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
以上配置就是hibernate的相關配置sql
3.建立實體類數據庫
@Entity @Table(name = "good") public class Good { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column private String goodName; @Column private Integer number; }
@Table註解的name是數據庫的表名maven
@Id 聲明id爲主鍵ide
@GeneratedValue 爲主鍵生成的規則spring-boot
@Column 設置該屬性爲字段 能夠用name指定名length指定長度測試
org.hibernate.cfg.ImprovedNamingStrategy 會自動 映射屬性和字段名(goodName ==> good_name) 通常沒有特殊狀況 一致就好了。ui
4.建立Dao數據訪問層
@Repository public interface GoodDao extends JpaRepository<Good, Serializable> { Good findByGoodName(String goodName); }
默認的 經常使用方法都有了 save(保存更新) findAll delete findOne.....
若是須要find某個屬性的話 只須要findByGoodName 屬性名首字母大寫就能夠了,須要實現這個接口
若是須要自定義sql的話 ,也是能夠加@Query註解來自定義
@Query(value = "select id from User where name=:name",nativeQuery = true) public Integer getId(String name);
5.測試就能夠了
Good good = goodDao.getOne(1);
6.分頁加排序
Sort sort = new Sort(Sort.Direction.ASC,"name"); Pageable pageable = new PageRequest(0, 20,sort); Page<User> page = dao.findAll(pageable); List<User> users = page.getContent(); System.out.println("一共多少條:" + page.getTotalElements());//一共多少條 System.out.println("一共多少頁:" + page.getTotalPages());//一共多少頁 System.out.println("開始位置:" + page.getNumber());//開始位置 System.out.println("顯示多少行" + page.getSize());//顯示多少行 System.out.println(page.getSort());
7.多數據源
7.1 配置兩個數據庫的鏈接用戶名密碼
datasource.primary.url=jdbc:mysql://12.12.12.12/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true datasource.primary.username=root datasource.primary.password=root datasource.primary.driverClassName=com.mysql.jdbc.Driver datasource.secondary.url=jdbc:mysql://11.11.11.11/test_db?useUnicode=true&characterEncoding=utf8&autoReconnect=true datasource.secondary.username=root datasource.secondary.password=root datasource.secondary.driverClassName=com.mysql.jdbc.Driver
7.2 配置兩個DatasourceBean
@Configuration public class DataSourceConfiguration { @Bean(name = "primaryDataSource") @Primary @Qualifier("primaryDataSource") @ConfigurationProperties(prefix = "datasource.primary") public DataSource primaryDataSource() { System.out.println("-------------------- primaryDataSource初始化 ---------------------"); return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @Qualifier("secondaryDataSource") @ConfigurationProperties(prefix = "datasource.secondary") public DataSource secondaryDataSource() { System.out.println("-------------------- secondaryDataSource初始化---------------------"); return DataSourceBuilder.create().build(); }
7.3 分開配置 EntityManager以及JpaProperties
package com.wangnian.repositoryConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.sql.DataSource; import java.util.Map; @Configuration @EnableTransactionManagement @EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryPrimary", transactionManagerRef = "transactionManagerPrimary", basePackages = {"com.wangnian.model1"})//設置dao(repo)所在位置 public class RepositoryPrimaryConfig { @Autowired private JpaProperties jpaProperties; @Autowired @Qualifier("primaryDataSource") private DataSource primaryDS; @Bean(name = "entityManagerPrimary") @Primary public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); } @Bean(name = "entityManagerFactoryPrimary") @Primary public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) { return builder .dataSource(primaryDS) .properties(getVendorProperties(primaryDS)) .packages("com.wangnian.model1") //設置實體類所在位置 .persistenceUnit("primaryPersistenceUnit") .build(); } private Map<String, String> getVendorProperties(DataSource dataSource) { return jpaProperties.getHibernateProperties(dataSource); } @Bean(name = "transactionManagerPrimary") @Primary PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } }
7.4 使用接口的方式或者使EntityManager測試
/** * Created by http://my.oschina.net/wangnian on 2016/10/26. */ @Repository public interface Dao1 extends JpaRepository<User, Serializable> { }
8.使用EntityManager 返回 MAP
query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
上面我設置了自動建立表 update,千萬不要用create,不然會刪點數據重建。
9.分頁計算
第1頁顯示10行 limit 計算公式 (page-1)*count
10條數據顯示10行有多少頁 計算公式 (total-1)/count+1
10.封裝原生sql方法
package com.example; import java.util.List; import java.util.Map; /** * Created by wangnian on 2017/3/22. */ public interface BaseDao { /** * 增刪改 * * @param sql 自定義sql語句 * @param parameters 參數<:key,value> * @return 執行條數 */ int executeUpdate(String sql, Map<String, Object> parameters); /** * 查詢 * * @param sql 自定義sql語句 * @param parameters 參數<:key,value> * @param page 第幾頁 * @param pageSize 顯示多少行 * @return 集合 Map<列名,值> */ List<Map<String, Object>> getList(String sql, Map<String, Object> parameters, Integer page, Integer pageSize); /** * 查詢sql的總條數 * * @param sql 自定義sql語句 * @param parameters 參數<:key,value> * @param page 第幾頁 * @param pageSize 顯示多少行 * @return 總條數 total,當前第幾頁 pageSize,總共多少頁 sumPage,顯示多少行 count */ Map<String, Object> getListTotal(String sql, Map<String, Object> parameters, Integer page, Integer pageSize); }
package com.example; import org.hibernate.SQLQuery; import org.hibernate.transform.Transformers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.persistence.Query; import java.math.BigInteger; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by wangnian on 2017/3/22. */ @Repository public class BaseDaoImpl implements BaseDao { private static final Logger LOGGER = LoggerFactory.getLogger(BaseDaoImpl.class); @Autowired(required = false) private EntityManager entityManager; @Override @Transactional public int executeUpdate(String sql, Map<String, Object> parameters) { long startTime = System.currentTimeMillis(); Query query = entityManager.createNativeQuery(sql); for (Map.Entry<String, Object> entry : parameters.entrySet()) { query.setParameter(entry.getKey(), entry.getValue()); } int updateCount = query.executeUpdate(); LOGGER.info("ExecuteUpdate ExecuteSQL Time:{}ms UpdateCount:{} Sql:{} {}", System.currentTimeMillis() - startTime, updateCount, sql, parameters); return updateCount; } @Override public List<Map<String, Object>> getList(String sql, Map<String, Object> parameters, Integer page, Integer pageSize) { long startTime = System.currentTimeMillis(); Query query = entityManager.createNativeQuery(sql); for (Map.Entry<String, Object> entry : parameters.entrySet()) { query.setParameter(entry.getKey(), entry.getValue()); } query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); Integer fistResult = (page - 1) * pageSize; query.setFirstResult(fistResult); query.setMaxResults(pageSize); List<Map<String, Object>> list = query.getResultList(); LOGGER.info("GetList ExecuteSQL Time:{}ms ResultSize:{} Sql:{} limit {} {} {} ", System.currentTimeMillis() - startTime, list.size(), sql, fistResult, pageSize, parameters); return list; } @Override public Map<String, Object> getListTotal(String sql, Map<String, Object> parameters, Integer page, Integer pageSize) { long startTime = System.currentTimeMillis(); Query query = entityManager.createNativeQuery(sql); for (Map.Entry<String, Object> entry : parameters.entrySet()) { query.setParameter(entry.getKey(), entry.getValue()); } BigInteger bigInteger = (BigInteger) query.getSingleResult(); Integer total = bigInteger.intValue(); int sumPage = (total + pageSize - 1) / pageSize; Map<String, Object> resultMap = new HashMap<>(); resultMap.put("total", total); resultMap.put("page", page); resultMap.put("pageSize", pageSize); resultMap.put("sumPage", sumPage); LOGGER.info("GetListTotal ExecuteSQL Time:{}ms Total:{} Sql:{} {}", System.currentTimeMillis() - startTime, total, sql, parameters); return resultMap; } }
博客地址:http://my.oschina.net/wangnian