項目目錄結構
pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bodi</groupId> <artifactId>onlineretailers</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>onlineretailers</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> </dependency> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.1-api</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.6</version> </dependency> <dependency> <groupId>jdom</groupId> <artifactId>jdom</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.46</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20180130</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <!--data source spring data jpa 需要用c3p0 連接池--> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.properties文件配置
ms.db.driverClassName=com.mysql.jdbc.Driver ms.db.url=jdbc:mysql://47.100.96.85:3306/vending_test?prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&characterEncoding=utf-8&allowMultiQueries=true ms.db.username=vending_test ms.db.password=PedC6TfiDZ ms.db.maxActive=500 #修改監聽端口號 server.port = 8081 #輸出sql log logging.level.org.hibernate.SQL = DEBUG
配置類DBConfig
@Configuration public class DBConfig { @Autowired private Environment env; @Bean(name="dataSource") public ComboPooledDataSource dataSource() throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass(env.getProperty("ms.db.driverClassName")); dataSource.setJdbcUrl(env.getProperty("ms.db.url")); dataSource.setUser(env.getProperty("ms.db.username")); dataSource.setPassword(env.getProperty("ms.db.password")); dataSource.setMaxPoolSize(20); dataSource.setMinPoolSize(5); dataSource.setInitialPoolSize(10); dataSource.setMaxIdleTime(300); dataSource.setAcquireIncrement(5); dataSource.setIdleConnectionTestPeriod(60); return dataSource; } }
配置類JpaConfig
@Configuration //此處是你dao文件所在的包名 @EnableJpaRepositories("com.bodi.domain") @EnableTransactionManagement public class JpaConfig { @Autowired private DataSource dataSource; @Bean public EntityManagerFactory entityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); //此處com.example.*.model是你的java bean所在的包名 factory.setPackagesToScan("com.bodi.entity"); factory.setDataSource(dataSource); Map<String, Object> jpaProperties = new HashMap<String, Object>(); jpaProperties.put("hibernate.ejb.naming_strategy","org.hibernate.cfg.ImprovedNamingStrategy"); jpaProperties.put("hibernate.jdbc.batch_size",50); factory.setJpaPropertyMap(jpaProperties); factory.afterPropertiesSet(); return factory.getObject(); } @Bean public PlatformTransactionManager transactionManager() { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory()); return txManager; } }
主要部分 接口JpaDao extends JpaRepository<AdminUser, Long> (AdminUser是Entity類型,Long是主鍵類型(這個具體是什麼類型我也沒搞清楚 目前沒因爲這個報錯過))
nativeQuery = true(是否使用原生sql)
public interface AdminUserJpaDao extends JpaRepository<AdminUser, Long> { /** * Find by name. * * @param name the name * @return the user */ AdminUser findByStatus(Integer status); /** * Find by name and user name. * 如果參數名爲多個字母組成,請首字母大寫。勿使用駝峯命名,jpa不識別駝峯 * @param name the name * @param age the age * @return the user */ AdminUser findByStatusAndMobile(String status, Integer mobile); /** * Find user. * User爲@Entity 的名字 * @param name the name * @return the user */ @Query(value = "SELECT user.* FROM admin_user user WHERE user.status = ?1",nativeQuery = true) Page<AdminUser> findUser(@Param("status") Integer status,Pageable pageable); /** * @Title: findByName * @Description: 測試一下分頁 * @param @param name * @param @param pageable * @param @return 參數 * @return Page<Girl> 返回類型 * @throws */ Page<AdminUser> findByStatus(Integer status,Pageable pageable); }
Entity (實體類)
@GeneratedValue註解的strategy屬性提供四種值:
-AUTO主鍵由程序控制, 是默認選項 ,不設置就是這個
-IDENTITY 主鍵由數據庫生成, 採用數據庫自增長, Oracle不支持這種方式
-SEQUENCE 通過數據庫的序列產生主鍵, MYSQL 不支持
-Table 提供特定的數據庫產生主鍵, 該方式更有利於數據庫的移植
如果 Save Entity 不設置strategy屬性 會報錯
@Entity @Table(name = "admin_user") public class AdminUser { @Id @GeneratedValue @Column(name = "user_id") private Integer userId; @Column(name = "status") private Integer status; @Column(name = "owner_id") private Integer ownerId; @Column(name = "mobile") private String mobile; @Column(name = "password_hash") private String passwordHash; @Column(name = "created_at") private Timestamp createdAt; @Column(name = "updated_at") private Timestamp updatedAt; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public Integer getOwnerId() { return ownerId; } public void setOwnerId(Integer ownerId) { this.ownerId = ownerId; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public String getPasswordHash() { return passwordHash; } public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; } public Timestamp getCreatedAt() { return createdAt; } public void setCreatedAt(Timestamp createdAt) { this.createdAt = createdAt; } public Timestamp getUpdatedAt() { return updatedAt; } public void setUpdatedAt(Timestamp updatedAt) { this.updatedAt = updatedAt; } }
service 和 controller 這裏我不貼代碼了 和正常的是一樣的
啓動類
@SpringBootApplication @EnableTransactionManagement @ServletComponentScan public class OnlineretailersApplication { public static void main(String[] args) { SpringApplication.run(OnlineretailersApplication.class, args); } }
創建項目 啓動類旁邊 多了個類 我也不知道幹嘛的 我也貼出來把
public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(OnlineretailersApplication.class); } }
Jpa分頁
分頁的代碼邏輯很簡單 簡單看一下就明白了 有一點需要注意的
1、sorts 這個排序字段 是根據你要分頁的sql定的 如果說是原生的就寫表列名字 如果不是原生的 就寫Entity 屬性名
/** * @Title: bynamePaging * @Description: 測試一下分頁 * @author yihj * @param @param status * @param @param page * @param @param size * @param @param sorts * @param @param request 參數 * @return void 返回類型 * @throws */ @SuppressWarnings("deprecation") @RequestMapping(value = "/bynamePaging", method = RequestMethod.GET) public void bynamePaging(@RequestParam(value = "status", defaultValue = "1") Integer status, @RequestParam(value = "page", defaultValue = "0") Integer page, //從第0個開始查 @RequestParam(value = "size", defaultValue = "15") Integer size, //每頁展示幾個 @RequestParam(value = "sorts", defaultValue = "userId") String sorts, HttpServletRequest request) { Sort sort = new Sort(Sort.Direction.DESC, sorts); //排序 Pageable pageable =new PageRequest(page,size,sort); Page<AdminUser> pages =userService.findByStatus(status, pageable); Iterator<AdminUser> it=pages.iterator(); while (it.hasNext()){ log.info("---------------------->id:" + ((AdminUser) it.next()).getUserId()); } }
重點記錄一下
Jpa 自定義實體 自定義查詢 這塊我幾乎寫了5個小時(記錄的可能是一個笨方法 別嫌棄。。。 有更好的方式可以互相交流學習)
Controller
@SuppressWarnings({ "deprecation", "unchecked" }) @RequestMapping(value = "/findMyOrders", method = RequestMethod.GET) public void findMyOrders(@RequestParam(value = "openId", defaultValue = "",required=false) String openId, @RequestParam(value = "page", defaultValue = "0",required=false) Integer page, //從第0個開始查 @RequestParam(value = "size", defaultValue = "4",required=false) Integer size, //每頁展示幾個 @RequestParam(value = "sorts", defaultValue = "createdAt") String sorts, HttpServletRequest request,HttpServletResponse response) { log.info("查詢我的訂單接口start"); //創建返回對象 JSONObject result = new JSONObject(); //排序 Sort sort = new Sort(Sort.Direction.DESC, sorts); //分頁 Pageable pageable =new PageRequest(page,size,sort); log.info("參數openId:"+openId); log.info("參數page:"+page); log.info("參數size:"+size); //自定義查詢 Page<List<Map<String, Object>>> pages =salesOrderService.selectMyOrders(openId, pageable); //迭代 Iterator<List<Map<String, Object>>> it= pages.iterator(); //最終返回list List<SalesOrderDto> dtos = new ArrayList<SalesOrderDto>(); //循環迭代 while(it.hasNext()) { //拿到hash值 HashMap<String, Object> mapNext = (HashMap<String, Object>) it.next(); //創建臨時對象 SalesOrderDto dto = new SalesOrderDto(); //設置屬性 dto.setStatus(Configuration.KEYMAP.get(mapNext.get("0").toString())); dto.setGrandTotal(new BigDecimal(mapNext.get("1").toString())); dto.setName(mapNext.get("2").toString()); dto.setImage("http://vending_client.bb-dd.cn/media/catalog/product/"+mapNext.get("3").toString()); dto.setCreatedAtView(mapNext.get("4").toString()); //對象添加到集合 dtos.add(dto); } //成功返回數據 result.put("status", "1"); //數據集合 result.put("list", JSONArray.fromObject(dtos).toString()); //數據總條數 result.put("listLength", salesOrderService.findMyOrdersCount(openId)); log.info("查詢我的訂單接口end"); log.info("list:"+JSONArray.fromObject(dtos).toString()); log.info("listLength:"+result.getString("listLength")); //返回前端 JsonUtils.outJsonString(result.toString(), response); }
service 就正常的 調用dao方法 我沒寫任何邏輯 主要是這個dao
Dao
/** * @Title: findMyOrders * @Description: 我的訂單查詢 * @author yihj * @param @param openId * @param @param pageable * @param @return 參數 * @return Page<SalesOrder> 返回類型 * @throws */ @Query(value = "select new map(salesOrder.status,salesOrder.grandTotal,product.name, product.image, date_format(salesOrder.createdAt, '%Y-%m-%d %H:%i:%s')) from SalesOrder salesOrder " + " INNER JOIN Customer customer ON customer.customerId = salesOrder.customerId" + " INNER JOIN SalesOrderItem orderItem ON orderItem.orderId = salesOrder.orderId" + " INNER JOIN CatalogProduct product ON product.productId = orderItem.productId" + " WHERE customer.openId = ?1") Page<List<Map<String, Object>>> selectMyOrders(String openId,Pageable pageable);