1. Jpa的使用
1.1 pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.springdataJpa</groupId> 8 <artifactId>springdataJpa</artifactId> 9 <packaging>pom</packaging> 10 <version>1.0-SNAPSHOT</version> 11 <modules> 12 <module>jdbcTemplate</module> 13 <module>jpa</module> 14 </modules> 15 16 <!-- Spring boot 父引用--> 17 <parent> 18 <groupId>org.springframework.boot</groupId> 19 <artifactId>spring-boot-starter-parent</artifactId> 20 <version>1.4.1.RELEASE</version> 21 </parent> 22 23 <dependencies> 24 <!-- Spring boot 核心web--> 25 <dependency> 26 <groupId>org.springframework.boot</groupId> 27 <artifactId>spring-boot-starter-web</artifactId> 28 </dependency> 29 <dependency> 30 <groupId>org.springframework.boot</groupId> 31 <artifactId>spring-boot-starter-data-jpa</artifactId> 32 </dependency> 33 <dependency> 34 <groupId>org.projectlombok</groupId> 35 <artifactId>lombok</artifactId> 36 <version>1.16.18</version> 37 </dependency> 38 <dependency> 39 <groupId>com.alibaba</groupId> 40 <artifactId>fastjson</artifactId> 41 <version>1.2.29</version> 42 </dependency> 43 <dependency> 44 <groupId>org.springframework.boot</groupId> 45 <artifactId>spring-boot-starter-logging</artifactId> 46 </dependency> 47 <dependency> 48 <groupId>org.springframework.boot</groupId> 49 <artifactId>spring-boot-starter-test</artifactId> 50 </dependency> 51 <dependency> 52 <groupId>com.oracle</groupId> 53 <artifactId>ojdbc14</artifactId> 54 <version>10.2.0.4.0</version> 55 </dependency> 56 <!--<dependency> 57 <groupId>mysql</groupId> 58 <artifactId>mysql-connector-java</artifactId> 59 </dependency>--> 60 </dependencies> 61 62 <build> 63 <plugins> 64 <plugin> 65 <groupId>org.springframework.boot</groupId> 66 <artifactId>spring-boot-maven-plugin</artifactId> 67 <executions> 68 <execution> 69 <goals> 70 <goal>repackage</goal> 71 </goals> 72 </execution> 73 </executions> 74 <configuration> 75 <executable>true</executable> 76 </configuration> 77 </plugin> 78 </plugins> 79 </build> 80 </project>
1.2 application.properties
1 server.port=8089 2 server.servlet-path=/ 3 spring.resources.static-locations=classpath:/static/,classpath:/templates/ 4 spring.mvc.view.suffix=.html 5 6 #配置數據源 7 #mysql 8 #spring.datasource.driver-class-name=com.mysql.jdbc.Driver 9 #spring.datasource.url=jdbc:mysql://localhost:3306/jpa 10 #spring.datasource.username=root 11 #spring.datasource.password=root 12 13 #oracle 14 spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver 15 spring.datasource.url=jdbc:oracle:thin:@localhost:1521:orcl 16 spring.datasource.username=scott 17 spring.datasource.password=scott 18 19 spring.jpa.hibernate.ddl-auto=update 20 21 spring.jpa.properties.hibernate.hbm2ddl.auto=update 22 spring.jpa.show-sql=true 23 ##懶加載默認就為true 24 spring.jpa.open-in-view=true 25 26 #在控制台輸出彩色日志 27 spring.output.ansi.enabled=always
1.3 model
1.3.1 BaseDomain.class
1 package com.springdatajpa.model.base; 2 3 import com.alibaba.fastjson.annotation.JSONField; 4 5 import javax.persistence.Column; 6 import javax.persistence.MappedSuperclass; 7 import javax.persistence.PrePersist; 8 import javax.persistence.PreUpdate; 9 import java.io.Serializable; 10 import java.util.Date; 11 12 /** 13 * @date 2018/7/30 14 */ 15 @MappedSuperclass 16 abstract public class BaseDomain implements Serializable { 17 18 /** 19 * 創建日期 20 */ 21 @Column(name = "date_created") 22 @JSONField(format = "yyyy-MM-dd HH:mm:ss") 23 private Date dateCreated; 24 25 /** 26 * 最后更新日期 27 */ 28 @Column(name = "last_updated") 29 @JSONField(format = "yyyy-MM-dd HH:mm:ss") 30 private Date lastUpdated; 31 32 @Column(name = "version") 33 private Integer version; 34 35 @Column(name = "is_delete") 36 private Boolean isDelete = false; 37 38 @JSONField(format = "yyyy-MM-dd HH:mm:ss") 39 private Date deleteDate; 40 41 public Date getDateCreated() { 42 return dateCreated; 43 } 44 45 public void setDateCreated(Date dateCreated) { 46 this.dateCreated = dateCreated; 47 } 48 49 public Date getLastUpdated() { 50 return lastUpdated; 51 } 52 53 public void setLastUpdated(Date lastUpdated) { 54 this.lastUpdated = lastUpdated; 55 } 56 57 public Integer getVersion() { 58 return version; 59 } 60 61 public void setVersion(Integer version) { 62 this.version = version; 63 } 64 65 public Boolean getIsDelete() { 66 return isDelete; 67 } 68 69 public void setIsDelete(Boolean isDelete) { 70 if (isDelete != null && isDelete) { 71 this.deleteDate = new Date(); 72 } 73 this.isDelete = isDelete; 74 } 75 76 @PrePersist 77 protected void prePersist() { 78 dateCreated = new Date(); 79 version = 1; 80 } 81 82 83 @PreUpdate 84 private void preUpdate() { 85 lastUpdated = new Date(); 86 if (version == null) { 87 version = 1; 88 } else { 89 version++; 90 } 91 } 92 }
1.3.2 Student.class
1 package com.springdatajpa.model; 2 3 import com.springdatajpa.model.base.BaseDomain; 4 import lombok.Data; 5 import org.hibernate.annotations.GenericGenerator; 6 7 import javax.persistence.*; 8 import java.io.Serializable; 9 import java.util.List; 10 11 /** 12 * @date 2018/7/30 13 */ 14 @Entity 15 @Data 16 public class Student extends BaseDomain implements Serializable { 17 /** 18 * 主鍵. 19 */ 20 @Id 21 @GenericGenerator(name = "PKUUID", strategy = "uuid2") 22 @GeneratedValue(generator = "PKUUID") 23 private String id; 24 /** 25 * 姓名. 26 */ 27 private String name; 28 /** 29 * 編號. 30 */ 31 private String studentNo; 32 /** 33 * 年齡 34 */ 35 private Integer age; 36 37 /** 38 * 地址列表 39 */ 40 @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "student") 41 private List<Address> addresses; 42 43 }
1.3.3 Address.class
1 package com.springdatajpa.model; 2 3 import com.springdatajpa.model.base.BaseDomain; 4 import lombok.Data; 5 import org.hibernate.annotations.GenericGenerator; 6 7 import javax.persistence.*; 8 import java.io.Serializable; 9 10 /** 11 * @author12 * @date 2018/7/30 13 */ 14 @Entity 15 @Data 16 public class Address extends BaseDomain implements Serializable { 17 /** 18 * 主鍵. 19 */ 20 @Id 21 @GenericGenerator(name = "PKUUID", strategy = "uuid2") 22 @GeneratedValue(generator = "PKUUID") 23 private String id; 24 /** 25 * 地址 26 */ 27 private String addressDetail; 28 /** 29 * 學生id. 30 */ 31 @ManyToOne 32 @JoinColumn(name = "STUDENT_ID", foreignKey = @ForeignKey(name = "FK_STUDENT_ADDRESS")) 33 private Student student; 34 35 }
1.4 repository
1.4.1 StudentRepo.class
1 package com.springdatajpa.repository; 2 3 import com.springdatajpa.model.Student; 4 import org.springframework.data.jpa.repository.JpaRepository; 5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 6 import org.springframework.data.repository.CrudRepository; 7 8 /** 9 * @author10 * @date 2018/7/30 11 */ 12 public interface StudentRepo extends JpaRepository<Student,String>,JpaSpecificationExecutor<Student> { 13 14 Student findById(String id); 15 }
1.4.2 AddressRepo.class
1 package com.springdatajpa.repository; 2 3 import com.springdatajpa.model.Address; 4 import org.springframework.data.jpa.repository.JpaRepository; 5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 6 7 /** 8 * @author 9 * @date 2018/7/30 10 */ 11 public interface AddressRepo extends JpaRepository<Address,String>,JpaSpecificationExecutor<Address> { 12 Address findById(String id); 13 }
1.5 specification
1.5.1 StudentSpecification.class
1 package com.springdatajpa.specification; 2 3 import com.springdatajpa.dto.StudentQuery; 4 import org.springframework.data.jpa.domain.Specification; 5 import org.springframework.util.StringUtils; 6 7 import javax.persistence.criteria.CriteriaBuilder; 8 import javax.persistence.criteria.CriteriaQuery; 9 import javax.persistence.criteria.Predicate; 10 import javax.persistence.criteria.Root; 11 import java.util.ArrayList; 12 import java.util.List; 13 14 /** 15 * @author16 * @date 2018/7/30 17 */ 18 public class StudentSpecification<T> implements Specification<T> { 19 private StudentQuery studentQuery; 20 21 public StudentSpecification() { 22 } 23 24 public StudentSpecification(StudentQuery studentQuery) { 25 this.studentQuery = studentQuery; 26 } 27 28 @Override 29 public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 30 List<Predicate> predicates = new ArrayList<>(); 31 predicates.add(cb.equal(root.get("isDelete"), false)); 32 if (!StringUtils.isEmpty(studentQuery.getName()) && !studentQuery.getName().isEmpty()) { 33 predicates.add(cb.equal(root.get("name"), studentQuery.getName())); 34 } 35 if (!StringUtils.isEmpty(studentQuery.getAge()) && !studentQuery.getAge().isEmpty()) { 36 predicates.add(cb.equal(root.get("age"), studentQuery.getAge())); 37 } 38 if (!StringUtils.isEmpty(studentQuery.getStudentNo()) && !studentQuery.getStudentNo().isEmpty()) { 39 predicates.add(cb.equal(root.get("studentNo"), studentQuery.getStudentNo())); 40 } 41 if (studentQuery.getStartTime() != null) { 42 predicates.add(cb.greaterThanOrEqualTo(root.get("dateCreated"), studentQuery.getStartTime())); 43 } 44 if (studentQuery.getEndTime() != null) { 45 predicates.add(cb.lessThanOrEqualTo(root.get("dateCreated"), studentQuery.getEndTime())); 46 } 47 return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction(); 48 } 49 }
1.5.2 AddressSpecification.class
package com.springdatajpa.specification; import com.springdatajpa.dto.AddressQuery; import com.springdatajpa.dto.StudentQuery; import org.springframework.data.jpa.domain.Specification; import org.springframework.util.StringUtils; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import java.util.ArrayList; import java.util.List; /** * @author luoxianwei * @date 2018/7/30 */ public class AddressSpecification<T> implements Specification<T> { private AddressQuery addressQuery; public AddressSpecification() { } public AddressSpecification(AddressQuery addressQuery) { this.addressQuery = addressQuery; } @Override public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> predicates = new ArrayList<>(); predicates.add(cb.equal(root.get("isDelete"), false)); if (!StringUtils.isEmpty(addressQuery.getAddressDetail()) && !addressQuery.getAddressDetail().isEmpty()) { predicates.add(cb.equal(root.get("addressDetail"), addressQuery.getAddressDetail())); } if (!StringUtils.isEmpty(addressQuery.getStudentNo()) && !addressQuery.getStudentNo().isEmpty()) { predicates.add(cb.equal(root.get("student").get("studentNo"), addressQuery.getStudentNo())); } if (!StringUtils.isEmpty(addressQuery.getName()) && !addressQuery.getName().isEmpty()) { predicates.add(cb.equal(root.get("student").get("name"), addressQuery.getName())); } if (addressQuery.getStartTime() != null) { predicates.add(cb.greaterThanOrEqualTo(root.get("dateCreated"), addressQuery.getStartTime())); } if (addressQuery.getEndTime() != null) { predicates.add(cb.lessThanOrEqualTo(root.get("dateCreated"), addressQuery.getEndTime())); } return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction(); } }
1.6 dto
1.6.1 StudentQuery.class
package com.springdatajpa.dto; import com.alibaba.fastjson.annotation.JSONField; import lombok.Data; import java.util.Date; /** * @author luoxianwei * @date 2018/7/30 */ @Data public class StudentQuery { /** * 姓名. */ private String name; /** * 編號. */ private String studentNo; /** * 年齡 */ private String age; @JSONField(format = "yyyy-MM-dd HH:mm:ss") private Date startTime; @JSONField(format = "yyyy-MM-dd HH:mm:ss") private Date EndTime; }
1.6.2 AddressQuery.class
package com.springdatajpa.dto; import com.alibaba.fastjson.annotation.JSONField; import lombok.Data; import java.util.Date; /** * @author luoxianwei * @date 2018/7/30 */ @Data public class AddressQuery { /** * 地址 */ private String addressDetail; /** * 姓名. */ private String name; /** * 編號. */ private String studentNo; @JSONField(format = "yyyy-MM-dd HH:mm:ss") private Date startTime; @JSONField(format = "yyyy-MM-dd HH:mm:ss") private Date EndTime; }
1.7 service
1.7.1 StudentService.class
package com.springdatajpa.service; import com.springdatajpa.dto.StudentQuery; import com.springdatajpa.model.Student; import com.springdatajpa.repository.StudentRepo; import com.springdatajpa.specification.StudentSpecification; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; /** * @author luoxianwei * @date 2018/7/30 */ @Service public class StudentService { @Autowired StudentRepo studentRepo; public Student add(Student student) { return studentRepo.save(student); } public Student update(Student student) { Student student1 = studentRepo.findById(student.getId()); student1.setName(student.getName()); return studentRepo.save(student1); } public void delete(Student student) { studentRepo.delete(student.getId()); } public List<Student> adds(List<Student> students) { return studentRepo.save(students); } public Student findStudent(Student student) { return studentRepo.findById(student.getId()); } public List<Student> findStudentList() { return studentRepo.findAll(); } public Page<Student> findByPage(Pageable pageable) { return studentRepo.findAll(pageable); } public Page<Student> findPageByQuery(StudentQuery studentQuery,Pageable pageable) { StudentSpecification studentSpecification = new StudentSpecification(studentQuery); return studentRepo.findAll(studentSpecification,pageable); } }
1.7.2 AddressService.class
package com.springdatajpa.service; import com.springdatajpa.dto.AddressQuery; import com.springdatajpa.dto.StudentQuery; import com.springdatajpa.model.Address; import com.springdatajpa.model.Student; import com.springdatajpa.repository.AddressRepo; import com.springdatajpa.repository.StudentRepo; import com.springdatajpa.specification.AddressSpecification; import com.springdatajpa.specification.StudentSpecification; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; /** * @author luoxianwei * @date 2018/7/30 */ @Service public class AddressService { @Autowired AddressRepo addressRepo; public Address add(Address address) { return addressRepo.save(address); } public Address update(Address address) { Address address1 = addressRepo.findById(address.getId()); address1.setAddressDetail(address.getAddressDetail()); return addressRepo.save(address1); } public void delete(Address address) { addressRepo.delete(address.getId()); } public Address findAddress(Address address) { return addressRepo.findById(address.getId()); } public List<Address> findAddressList() { return addressRepo.findAll(); } public Page<Address> findByPage(Pageable pageable) { return addressRepo.findAll(pageable); } public Page<Address> findPageByQuery(AddressQuery addressQuery, Pageable pageable) { AddressSpecification addressSpecification = new AddressSpecification(addressQuery); return addressRepo.findAll(addressSpecification,pageable); } }
1.8 test
1.8.1 StudentServiceTest.class
package com.springdatajpa.test; import com.springdatajpa.JpaApplication; import com.springdatajpa.dto.StudentQuery; import com.springdatajpa.model.Address; import com.springdatajpa.model.Student; import com.springdatajpa.service.StudentService; import javafx.scene.control.Pagination; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * @author luoxianwei * @date 2018/6/26 */ @SpringBootTest(classes = JpaApplication.class) @RunWith(SpringRunner.class) public class StudentServiceTest { @Autowired StudentService studentService; @Test public void addStudent() { Student student = new Student(); student.setName("張三"); student.setAge(20); student.setStudentNo("001"); List<Address> addressList = new ArrayList<>(); Address address1 = new Address(); address1.setAddressDetail("上海"); address1.setStudent(student); Address address2 = new Address(); address2.setAddressDetail("北京"); address2.setStudent(student); addressList.add(address1); addressList.add(address2); student.setAddresses(addressList); Student student1 = studentService.add(student); System.out.println("成功插入:" + student1.getStudentNo()); } @Test public void updateStudent() { Student student = new Student(); student.setId("43a24b05-fe69-4bb8-8fc3-69fea4ae82cd"); student.setName("李四"); Student student1 = studentService.update(student); System.out.println("成功修改:" + student1.getName()); } @Test public void deleteStudent() { Student student = new Student(); student.setId("43a24b05-fe69-4bb8-8fc3-69fea4ae82cd"); studentService.delete(student); System.out.println("成功刪除:"); } @Test public void addStudents() { List<Student> students = new ArrayList<>(); for (int i = 0; i < 1000; i++) { Student student = new Student(); student.setName("張三"); student.setAge(20); student.setStudentNo(String.valueOf(i)); List<Address> addressList = new ArrayList<>(); Address address1 = new Address(); address1.setAddressDetail("上海"); address1.setStudent(student); Address address2 = new Address(); address2.setAddressDetail("北京"); address2.setStudent(student); addressList.add(address1); addressList.add(address2); student.setAddresses(addressList); students.add(student); } List<Student> adds = studentService.adds(students); System.out.println("批量添加:" + adds.size()); } @Test public void findStudent() { Student student = new Student(); student.setId("0010161b-651e-417d-90be-ec9b03d8ece6"); Student student1 = studentService.findStudent(student); System.out.println(student1.getName()); } @Test public void findStudentList() { List<Student> studentList = studentService.findStudentList(); System.out.println("查詢:" + studentList.size()); } @Test public void findByPage() { Pageable pageable = new PageRequest(0, 10); Page<Student> page = studentService.findByPage(pageable); System.out.println("查詢:" + page.getContent().size()); } @Test public void findPageByQuery() { StudentQuery studentQuery = new StudentQuery(); studentQuery.setStudentNo("8"); Pageable pageable = new PageRequest(0, 10); Page<Student> page = studentService.findPageByQuery(studentQuery,pageable); System.out.println("查詢:" + page.getContent().size()); } }
1.8.2 AddressServiceTest.class
package com.springdatajpa.test; import com.springdatajpa.JpaApplication; import com.springdatajpa.dto.AddressQuery; import com.springdatajpa.dto.StudentQuery; import com.springdatajpa.model.Address; import com.springdatajpa.model.Student; import com.springdatajpa.service.AddressService; import com.springdatajpa.service.StudentService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List; /** * @author luoxianwei * @date 2018/6/26 */ @SpringBootTest(classes = JpaApplication.class) @RunWith(SpringRunner.class) public class AddressServiceTest { @Autowired AddressService addressService; @Test public void findAddress() { Address address = new Address(); address.setId("0024092e-771b-4f78-97ae-f810049a10b0"); Address address1 = addressService.findAddress(address); System.out.println(address1.getStudent().getStudentNo()); } @Test public void findAddressList() { List<Address> addressList = addressService.findAddressList(); System.out.println("查詢:" + addressList.size()); } @Test public void findByPage() { Pageable pageable = new PageRequest(0, 10); Page<Address> page = addressService.findByPage(pageable); System.out.println("查詢:" + page.getContent().size()); } @Test public void findPageByQuery() { AddressQuery addressQuery = new AddressQuery(); addressQuery.setStudentNo("8"); Pageable pageable = new PageRequest(0, 10); Page<Address> page = addressService.findPageByQuery(addressQuery,pageable); System.out.println("查詢:" + page.getContent().size()); } }
2. jdbcTemplate
2.1 oracleDatabase
2.1.1 pom.xml
<dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc14</artifactId> <version>10.2.0.4.0</version> </dependency>
2.1.2 application.properties
server.port=8090
server.servlet-path=/
spring.resources.static-locations=classpath:/static/,classpath:/templates/
spring.mvc.view.suffix=.html
#配置數據源
spring.datasource.driver-class-name:oracle.jdbc.driver.OracleDriver
spring.datasource.url: jdbc:oracle:thin:@localhost:1521:orcl
spring.datasource.username:scott
spring.datasource.password:scott
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
#在控制台輸出彩色日志
spring.output.ansi.enabled=always
2.1.3 model
2.1.3.1 BaseDomain.class
package com.springdataJpa.oracle.model.base; import com.alibaba.fastjson.annotation.JSONField; import lombok.Data; import javax.persistence.Column; import javax.persistence.MappedSuperclass; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import java.io.Serializable; import java.util.Date; /** * @date 2018/7/30 */ @MappedSuperclass @Data abstract public class BaseDomain implements Serializable { /** * 創建日期 */ private Date dateCreated = new Date(); /** * 最后更新日期 */ private Date lastUpdated; /** * 刪除日期 */ private Date deleteDate; /** * 刪除標記 */ private Boolean isDelete = false; }
2.1.3.1 Users.class
package com.springdataJpa.oracle.model; import com.springdataJpa.oracle.model.base.BaseDomain; import lombok.Data; import org.hibernate.annotations.GenericGenerator; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.io.Serializable; /** * @author luoxianwei * @date 2018/5/11 */ @Entity @Data public class Users extends BaseDomain implements Serializable { @Id @GenericGenerator(name = "PKUUID", strategy = "uuid2") @GeneratedValue(generator = "PKUUID") private String id; /** * 姓名 */ private String userName; /** * 年齡 */ private Integer age; /** * 性別 */ private String sex; /** * 用戶狀態:1.在線;2.隱身;3.離線;4.忙碌 */ private String status; }
2.1.4 dto
2.1.4.1 UsersQuery.class
package com.springdataJpa.oracle.dto; import lombok.Data; @Data public class UsersQuery { private String id; private String userName; private Integer age; private String sex; private String status; }
2.1.5 vo
2.1.5.1 PageVo.class
package com.springdataJpa.oracle.vo; import lombok.Data; import java.io.Serializable; import java.util.List; @Data public class PageVo<T> implements Serializable { //分頁查詢結果 List<T> Result; //頁總數 Integer pageNum; //一頁記錄數 Integer pageSize; //總記錄數 Integer totalCount; //當前頁 Integer currentPage; public PageVo() { } public PageVo(Integer pageNum, Integer pageSize) { this.pageNum = pageNum; this.pageSize = pageSize; } }
2.1.6 util
2.1.6.1 Lang.class
package com.springdataJpa.oracle.util; import lombok.extern.slf4j.Slf4j; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.*; /** * Java通用工具類 */ @Slf4j public class Lang { private static final String DATE_FORMAT_YYYYMMDDHHMMSS_SSS = "yyyyMMddHHmmssSSS"; private Lang() { } /** * 空對象 */ public final static Object EMPTY = new Object(); /** * 空數組 */ public final static Object[] EMPTY_ARRAY = new Object[]{}; /** * 獲取對象系統引用哈希值(不為負數) * * @param x * @return */ public static long identityHashCode(Object x) { return (long) System.identityHashCode(x) + (long) Integer.MAX_VALUE; } /** * 將CheckedException轉換為RuntimeException. */ public static RuntimeException unchecked(Throwable e) { if (e instanceof RuntimeException) { return (RuntimeException) e; } else { return new RuntimeException(e); } } /** * 將CheckedException轉換為RuntimeException. */ public static RuntimeException unchecked(Throwable e, String message, Object... args) { return new RuntimeException(String.format(message, args), e); } /** * 判斷一個對象是否是空對象 * * @param obj * @return */ @SuppressWarnings("rawtypes") public static boolean isEmpty(Object obj) { if (obj == null) { return true; } if (obj instanceof CharSequence) { return obj.toString().trim().length() == 0; } if (obj.getClass().equals(Object.class)) { return true; } if (isBaseType(obj.getClass())) { return false; } if (obj instanceof Map) { return ((Map) obj).isEmpty(); } if (obj instanceof Collection) { return ((Collection) obj).isEmpty(); } if (obj.getClass().isArray()) { return Array.getLength(obj) == 0; } return Object.class.equals(obj.getClass()); } /** * 判斷一個類型是否是基本類型 * * @param type * @return */ public static boolean isBaseType(Class<?> type) { if (type.isPrimitive()) { return true; } if (CharSequence.class.isAssignableFrom(type)) { return true; } if (Number.class.isAssignableFrom(type)) { return true; } if (Date.class.isAssignableFrom(type)) { return true; } if (Boolean.class.equals(type)) { return true; } if (Character.class.equals(type)) { return true; } if (Class.class.equals(type)) { return true; } if (StringBuilder.class.equals(type)) { return true; } if (StringBuffer.class.equals(type)) { return true; } if (Object.class.equals(type)) { return true; } if (Void.class.equals(type)) { return true; } return false; } /** * 判斷是否是數字類型 * * @param type * @return */ public static boolean isNumber(Class<?> type) { if (Number.class.isAssignableFrom(type)) { return true; } if (type.equals(int.class)) { return true; } if (type.equals(short.class)) { return true; } if (type.equals(long.class)) { return true; } if (type.equals(float.class)) { return true; } if (type.equals(double.class)) { return true; } if (type.equals(byte.class)) { return true; } return false; } /** * 獲得本源異常信息 * * @param e * @return */ public static Throwable getCause(Throwable e) { return e.getCause() == null ? e : getCause(e.getCause()); } /** * 輸出對象字符串格式 * * @param obj * @return */ public static String toString(Object obj) { return toString(obj, null); } /** * 輸出對象字符串格式 * * @param obj * @return */ public static String toString(Object obj, String format) { if (obj == null) { return "null"; } if (obj instanceof Throwable) { Throwable throwable = (Throwable) obj; StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); throwable.printStackTrace(pw); pw.flush(); pw.close(); sw.flush(); return sw.toString(); } if (obj instanceof Date) { return new SimpleDateFormat( format == null || format.trim().length() == 0 ? DATE_FORMAT_YYYYMMDDHHMMSS_SSS : format).format((Date) obj); } if (isNumber(obj.getClass())) { if (format != null && format.trim().length() != 0) { return new DecimalFormat(format).format(obj); } } return String.valueOf(obj); } /** * 新建一個Set * * @param args * @return */ @SuppressWarnings("unchecked") public static <T> Set<T> newSet(T... args) { int length = args == null ? 1 : args.length; Set<T> set = new HashSet<T>(length); if (args == null) { set.add(null); } else { for (int i = 0; i < args.length; i++) { set.add(args[i]); } } return set; } /** * 新建一個List * * @param args * @return */ @SuppressWarnings("unchecked") public static <T> List<T> newList(T... args) { int length = args == null ? 1 : args.length; List<T> list = new ArrayList<T>(length); if (args == null) { list.add(null); } else { for (int i = 0; i < args.length; i++) { list.add(args[i]); } } return list; } /** * 拋出一個帶消息的異常 * * @param type * @param message * @param args * @return */ public static <T extends Throwable> T newThrowable(Class<T> type, String message, Object... args) { try { return type.getConstructor(String.class).newInstance( String.format(message, args)); } catch (InstantiationException e) { throw Lang.unchecked(e, message, args); } catch (IllegalAccessException e) { throw Lang.unchecked(e, message, args); } catch (IllegalArgumentException e) { throw Lang.unchecked(e, message, args); } catch (InvocationTargetException e) { throw Lang.unchecked(e, message, args); } catch (NoSuchMethodException e) { throw Lang.unchecked(e, message, args); } catch (SecurityException e) { throw Lang.unchecked(e, message, args); } } /** * 拋出一個帶消息的運行時異常 * * @param message * @param args * @return */ public static IllegalStateException newThrowable(String message, Object... args) { return newThrowable(IllegalStateException.class, message, args); } /** * 新建一個Map,必須是偶數個參數 * * @param args * @return */ @SuppressWarnings("unchecked") public static <K, V> Map<K, V> newMap(Object... args) { Map<K, V> map = new HashMap<K, V>(); if (args != null) { if (args.length % 2 != 0) { throw new IllegalArgumentException( "The number of arguments must be an even number"); } for (int i = 0; i < args.length; i += 2) { map.put((K) args[i], (V) args[i + 1]); } } return map; } /** * 生成一個固定容量的LRU策略的Map * * @param capacity 容量 * @param args 參數列表,通newMap * @return */ public static <K, V> Map<K, V> newLRUMap(final int capacity, Object... args) { Map<K, V> map = newMap(args); return new LinkedHashMap<K, V>(map) { /** * */ private static final long serialVersionUID = -5820354698308020916L; /** * Returns <tt>true</tt> if this map should remove its eldest entry. * This method is invoked by <tt>put</tt> and <tt>putAll</tt> after * inserting a new entry into the map. It provides the implementor * with the opportunity to remove the eldest entry each time a new one * is added. This is useful if the map represents a cache: it allows * the map to reduce memory consumption by deleting stale entries. * * <p>Sample use: this override will allow the map to grow up to 100 * entries and then delete the eldest entry each time a new entry is * added, maintaining a steady state of 100 entries. * <pre> * private static final int MAX_ENTRIES = 100; * * protected boolean removeEldestEntry(Map.Entry eldest) { * return size() > MAX_ENTRIES; * } * </pre> * * <p>This method typically does not modify the map in any way, * instead allowing the map to modify itself as directed by its * return value. It <i>is</i> permitted for this method to modify * the map directly, but if it does so, it <i>must</i> return * <tt>false</tt> (indicating that the map should not attempt any * further modification). The effects of returning <tt>true</tt> * after modifying the map from within this method are unspecified. * * <p>This implementation merely returns <tt>false</tt> (so that this * map acts like a normal map - the eldest element is never removed). * * @param eldest The least recently inserted entry in the map, or if * this is an access-ordered map, the least recently accessed * entry. This is the entry that will be removed it this * method returns <tt>true</tt>. If the map was empty prior * to the <tt>put</tt> or <tt>putAll</tt> invocation resulting * in this invocation, this will be the entry that was just * inserted; in other words, if the map contains a single * entry, the eldest entry is also the newest. * @return <tt>true</tt> if the eldest entry should be removed * from the map; <tt>false</tt> if it should be retained. */ protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() > capacity; } }; } /** * 比較兩個對象是否相同,對於數字、日期等按照大小進行比較,自動兼容包裝器實例 * * @param a * @param b * @return */ public static boolean equals(Object a, Object b) { if (a == b) { return true; } if (a == null || b == null) { return false; } if (a.equals(b)) { return true; } // 比較大數字 if (isNumber(a.getClass()) && isNumber(b.getClass())) { return new BigDecimal(a.toString()).compareTo(new BigDecimal(b .toString())) == 0; } // 比較日期 if (a instanceof Date && b instanceof Date) { return ((Date) a).compareTo((Date) b) == 0; } return false; } /** * 計時執行 * * @return 返回runnable的執行時間 */ public static long timing(Runnable runnable) { long begin = System.currentTimeMillis(); try { runnable.run(); return System.currentTimeMillis() - begin; } catch (Throwable e) { throw unchecked(e); } } /** * 判斷是否為真,不為真則拋出異常 * * @param flag 真假標志位 * @param message 消息體,可帶格式,將使用String.format進行格式化 * @param args 格式化參數,可為空 */ public static void isTrue(boolean flag, String message, Object... args) { if (!flag) { throw new IllegalArgumentException(String.format(message, args)); } } /** * 判斷是否非null,為null則拋出異常 * * @param object 要判斷的對象 * @param message 消息體,可帶格式,將使用String.format進行格式化 * @param args 格式化參數,可為空 */ public static void notNull(Object object, String message, Object... args) { isTrue(object != null, message, args); } /** * 判斷是否非空,為空則拋出異常 * * @param object 要判斷的對象 * @param message 消息體,可帶格式,將使用String.format進行格式化 * @param args 格式化參數,可為空 */ public static void notEmpty(Object object, String message, Object... args) { isTrue(!Lang.isEmpty(object), message, args); } public static void main(String[] args) { System.out.println(BigDecimal.valueOf(0).equals(0)); } /** * 獲取最初的消息異常 * * @param e * @return */ public static Throwable getMessageCause(Throwable e) { while (e != null && e.getMessage() == null && e.getCause() != null) { e = e.getCause(); } return e; } public static String generateDynamic(int len) { boolean isDigit = false; boolean isLetter = false; final int maxNum = 36; int m = 0; StringBuffer pwd = null; while (!isDigit || !isLetter) { isDigit = false; isLetter = false; pwd = new StringBuffer(""); int i; // 生成的隨機數 int count = 0; char[] str = {'4', 'b', 'c', '8', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', '6', 'n', 'o', 'p', 'q', 'r', 's', '0', 'u', 'v', 'w', '1', 'y', 'z', 't', 'x', '2', '3', 'a', '5', 'm', '7', 'd', '9'}; Random r = new Random(); while (count < len) { // 生成隨機數,取絕對值,防止生成負數, // 生成的數最大為36-1 i = Math.abs(r.nextInt(maxNum)); if (i >= 0 && i < str.length) { pwd.append(str[i]); count++; } } for (int j = 0; j < pwd.toString().length(); j++) { //循環遍歷字符串 if (Character.isDigit(pwd.toString().charAt(j))) { //用char包裝類中的判斷數字的方法判斷每一個字符 isDigit = true; } if (Character.isLetter(pwd.toString().charAt(j))) { //用char包裝類中的判斷字母的方法判斷每一個字符 isLetter = true; } } m++; log.info("--------------" + "第" + m + "次生成密碼:" + pwd.toString() + "--------------------"); } return pwd.toString(); } public static BigDecimal fourCutFiveIn(double d, int decimalPlace) { BigDecimal bigDecimal = new BigDecimal(d); return bigDecimal.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP); } public static BigDecimal fourCutFiveIn(BigDecimal bigDecimal, int decimalPlace) { return bigDecimal.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP); } /** * 從列表中提取屬性集合,支持Map列表及JavaBean列表 * * @param list 支持Map列表(List<Map>)及JavaBean列表(List<Bean>) * @param key: String 查找屬性名 * @param value: T 返回集合中的類型 * @param <T> * @return */ public static <T> List<T> grepList(List list, String key, T value) { List<T> grepedList = null; Object v; if (!isEmpty(list)) { grepedList = new ArrayList<>(); Object obj = list.get(0); if (obj != null) { /** 判斷成員類型 */ if (obj instanceof Map) { for (Object o : list) { v = ((Map) o).get(key); if (v != null) { grepedList.add((T) v); } } } else { /** 處理Bean */ Class clz = obj.getClass(); try { BeanInfo beanInfo = Introspector.getBeanInfo(clz); PropertyDescriptor[] propDescs = beanInfo.getPropertyDescriptors(); for (Object o : list) { for (int i = 0; i < propDescs.length; i++) { if (propDescs[i].getName().equals(key)) { v = propDescs[i].getReadMethod().invoke(o); if (v != null) { grepedList.add((T) v); } } } } } catch (InvocationTargetException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } catch (IllegalAccessException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } catch (IntrospectionException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } } } } return grepedList; } /** * 從列表中查找,支持Map列表及JavaBean列表 * 使用: * 1. 從List<Map>查找 * List<Map> list = new ArrayList() {{ * add(new HashMap(){{ * put("key1", "key1_v1"); * put("key2", "key2_v1"); * }}); * <p> * add(new HashMap(){{ * put("key1", "key1_v2"); * put("key2", "key2_v2"); * }}); * }} * * <b>Lang.findInBeanList(list, "key1", "key2_v2");</b> * <p> * 2. 從List<JavaBean>查找 * List<TestBean> list = new ArrayList() {{ * add(new TestBean(){{ * setId("id1"); * setName("bean1"); * }}); * <p> * add(new TestBean(){{ * setId("id2"); * setName("bean2"); * }}); * }} * <b>Lang.findInBeanList(list, "id", "id2");</b> * * @param list 支持Map列表(List<Map>)及JavaBean列表(List<Bean>) * @param key: String 查找屬性名,即Map的key或JavaBean的屬性名 * @param value: Object 需匹配的屬性值 * @return */ public static <T> T findInBeanList(List<T> list, String key, Object value) { T result = null; Object v; if (!isEmpty(list)) { Object obj = list.get(0); /** 判斷成員類型 */ if (obj instanceof Map) { for (Object o : list) { v = ((Map) o).get(key); if (v != null) { if (v.equals(value)) { result = (T) o; break; } } } } else { /** 處理Bean */ try { BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] propDescs = beanInfo.getPropertyDescriptors(); for (Object o : list) { for (int i = 0; i < propDescs.length; i++) { if (propDescs[i].getName().equals(key)) { v = propDescs[i].getReadMethod().invoke(o); if (v != null && v.equals(value)) { result = (T) o; break; } } } } } catch (IntrospectionException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } catch (InvocationTargetException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } catch (IllegalAccessException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } catch (ClassCastException e) { throw new RuntimeException("ClassCastException !", e); } catch (Exception e) { throw new RuntimeException("findInBeanList !", e); } } } return result; } public static <T> T findInBeanList(T[] beans, String key, Object value) { if (beans == null) { return null; } return findInBeanList(Arrays.asList(beans), key, value); } /** * 從列表中查找,支持Map列表及JavaBean列表 * 使用: * 1. 從List<Map>查找 * List<Map> list = new ArrayList() {{ * add(new HashMap(){{ * put("key1", "key1_v1"); * put("key2", "key2_v1"); * }}); * <p> * add(new HashMap(){{ * put("key1", "key1_v2"); * put("key2", "key2_v2"); * }}); * }} * * <b>Lang.findInBeanList(list, "key1", "key2_v2");</b> * <p> * 2. 從List<JavaBean>查找 * List<TestBean> list = new ArrayList() {{ * add(new TestBean(){{ * setId("id1"); * setName("bean1"); * }}); * <p> * add(new TestBean(){{ * setId("id2"); * setName("bean2"); * }}); * }} * <b>Lang.findInBeanList(list, "id", "id2");</b> * * @param list 支持Map列表(List<Map>)及JavaBean列表(List<Bean>) * @param key: String 查找屬性名,即Map的key或JavaBean的屬性名 * @param value: Object 需匹配的屬性值 * @return */ public static <T> List<T> findAllInBeanList(List<T> list, String key, Object value) { List<T> result = new ArrayList<>(); Object v; if (!isEmpty(list)) { Object obj = list.get(0); /** 判斷成員類型 */ if (obj instanceof Map) { for (Object o : list) { v = ((Map) o).get(key); if (v != null) { if (v.equals(value)) { result.add((T) o); break; } } } } else { /** 處理Bean */ try { BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] propDescs = beanInfo.getPropertyDescriptors(); for (Object o : list) { for (int i = 0; i < propDescs.length; i++) { if (propDescs[i].getName().equals(key)) { v = propDescs[i].getReadMethod().invoke(o); if (v.equals(value)) { result.add((T) o); break; } } } } } catch (IntrospectionException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } catch (InvocationTargetException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } catch (IllegalAccessException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } } } return result; } public static <T> List<T> findAllInBeanList(T[] beans, String key, Object value) { if (beans == null) { return null; } return findAllInBeanList(Arrays.asList(beans), key, value); } /** * 在JavaBean集合中,提取指定key值相同的記錄,放到Map中,以key值作為索引 * * @param list * @param key * @param <T> * @return Map<String , List < T>> */ public static <T> Map<Object, List<T>> beanListGroupBy(List<T> list, Object key) { Map<Object, List<T>> result = null; Object v; List<T> groupedBeanList; if (!isEmpty(list)) { result = new HashMap<>(); Object obj = list.get(0); /** 判斷成員類型 */ if (obj instanceof Map) { for (Object o : list) { v = ((Map) o).get(key); if (v != null) { groupedBeanList = result.get(v); if (groupedBeanList == null) { groupedBeanList = new ArrayList<>(); } groupedBeanList.add((T) o); result.put(v, groupedBeanList); } } } else { /** 處理Bean */ try { BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] propDescs = beanInfo.getPropertyDescriptors(); for (Object o : list) { for (int i = 0; i < propDescs.length; i++) { if (propDescs[i].getName().equals(key)) { v = propDescs[i].getReadMethod().invoke(o); if (v != null) { groupedBeanList = result.get(v); if (groupedBeanList == null) { groupedBeanList = new ArrayList<>(); } groupedBeanList.add((T) o); result.put(v, groupedBeanList); } } } } } catch (IntrospectionException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } catch (InvocationTargetException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } catch (IllegalAccessException e) { throw new RuntimeException("Not getter for key [" + key + "] in bean list !", e); } } } return result; } /** * 在List中查找指定值 * * @param list * @param value * @param <T> * @return */ public static <T> T findInList(Iterable<T> list, T value) { Iterator<T> it = list.iterator(); T tmp; while (it.hasNext()) { tmp = it.next(); if (tmp.equals(value)) { return tmp; } } return null; } /** * 去除Map中的空值 * * @param source * @param casde 是否級聯 * @return */ public static <K, V> Map<K, V> filterNullMap(Map<K, V> source, Boolean casde) { Iterator<Map.Entry<K, V>> it = source.entrySet().iterator(); V val; while (it.hasNext()) { Map.Entry<K, V> entry = it.next(); val = entry.getValue(); if (val == null) { it.remove(); } else { if (casde) { if (val instanceof Iterable) { Iterator<Object> cit = ((Iterable) val).iterator(); Object tmp; while (cit.hasNext()) { tmp = cit.next(); if (tmp instanceof Map) { filterNullMap((Map<Object, Object>) tmp, casde); } } } else if (val instanceof Map) { filterNullMap((Map<Object, Object>) val, casde); } } } } return source; } /** * 將集合按指定數量分組 * * @param list * @param quantity * @return 返回分組后的List -> List<List<T>> */ public static List groupListByQuantity(List list, int quantity) { if (list == null || list.size() == 0) { return list; } if (quantity <= 0) { new IllegalArgumentException("Wrong quantity."); } List wrapList = new ArrayList(); int count = 0; while (count < list.size()) { wrapList.add(new ArrayList(list.subList(count, (count + quantity) > list.size() ? list.size() : count + quantity))); count += quantity; } return wrapList; } }
2.1.6.2 QueryByPage.class
package com.springdataJpa.oracle.util; import com.springdataJpa.oracle.vo.PageVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * 分頁查詢封裝類(不適合sql帶In的查詢) */ @Component @Slf4j public class QueryByPage { @Autowired JdbcTemplate jdbcTemplate; /** * @param sql * @param elementType 返回需要封裝的javaVo * @param page * @param pageSize * @param args sql參數 * @return PageVo */ public <T> PageVo<T> query(String sql, Class<T> elementType, Integer page, Integer pageSize, Object... args) throws Exception { sql = sql.toLowerCase(); log.info("query sql:" + sql); SqlReCreateFactory sqlReCreateFactory = new SqlReCreateFactory<Object>(sql, page, pageSize, args).invoke(); sql = sqlReCreateFactory.getSql(); List<Object> argsList = sqlReCreateFactory.getArgsList(); PageVo<T> pageVo = sqlReCreateFactory.getPageVo(); List<T> result = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(elementType), argsList.toArray()); pageVo.setResult(result); return pageVo; } /** * @param sql 默認封裝成List<Map<String,Object>> * @param page * @param pageSize * @param args sql參數 * @return PageVo */ public PageVo query(String sql, Integer page, Integer pageSize, Object... args) throws Exception { sql = sql.toLowerCase(); log.info("query sql:" + sql); SqlReCreateFactory sqlReCreateFactory = new SqlReCreateFactory<Object>(sql, page, pageSize, args).invoke(); sql = sqlReCreateFactory.getSql(); List<Object> argsList = sqlReCreateFactory.getArgsList(); PageVo<Map<String, Object>> pageVo = sqlReCreateFactory.getPageVo(); List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, argsList.toArray()); pageVo.setResult(result); return pageVo; } public PageVo querySqlCaseNoConvert(String sql, Integer page, Integer pageSize, Object... args) throws Exception { log.info("SQL IS {}", sql); SqlReCreateFactory sqlReCreateFactory = new SqlReCreateFactory<>(sql, page, pageSize, args).invoke(); sql = sqlReCreateFactory.getSql(); List<Object> argsList = sqlReCreateFactory.getArgsList(); PageVo<Map<String, Object>> pageVo = sqlReCreateFactory.getPageVo(); List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, argsList.toArray()); pageVo.setResult(result); return pageVo; } private class SqlReCreateFactory<T> { // private String sql; private Integer page; private Integer pageSize; private Object[] args; private PageVo<T> pageVo; private List<Object> argsList; public SqlReCreateFactory(String sql, Integer page, Integer pageSize, Object... args) { this.sql = sql; this.page = page; this.pageSize = pageSize; this.args = args; } public String getSql() { return sql; } public PageVo<T> getPageVo() { return pageVo; } public List<Object> getArgsList() { return argsList; } public SqlReCreateFactory invoke() { pageVo = new PageVo<>(0, pageSize); String sqlCount = "select count(*) from (" + sql + ") "; //oracle數據庫不需要別名 //String sqlCount = "select count(*) from (" + sql + ") cal "; //mysql數據庫需要別名,不然會報 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Every derived table must have its own alias這個錯誤 Integer count = jdbcTemplate.queryForObject(sqlCount, args, Integer.class); //查詢頁數 pageVo.setTotalCount(count); pageVo.setCurrentPage(page); int pageNum = 0; if (count != null && count > 0) { if (count % pageSize == 0) { pageNum = count / pageSize; } else { pageNum = count / pageSize + 1; } pageVo.setPageNum(pageNum); } /* String sqlPrefix = sql.substring(0, sql.indexOf("from")); String sqlSuffix = sql.substring(sql.indexOf("from"));*/ int pageMin = (page - 1) * pageSize; int pageMax = pageMin + pageSize; argsList = new ArrayList<>(); for (Object arg : args) { argsList.add(arg); } argsList.add(pageMin); argsList.add(pageMax); sql = "select p.* from (select t.* ,rownum rownumber from (" + sql + ") t) p where p.rownumber>? and p.rownumber<=? "; return this; } } }
2.1.6.3 JdbcTemplatePage.class
package com.springdataJpa.oracle.util; import com.springdataJpa.oracle.vo.PageVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; /** * parent * * @date 2018/7/25 * 分頁查詢(擁有QueryByPage的功能,並且適合sql語句帶In的查詢) */ @Component @Slf4j public class JdbcTemplatePage { @Autowired JdbcTemplate jdbcTemplate; /** * @param sql * @param elementType 返回需要封裝的pageVo * @param page * @param pageSize * @param args * @return PageVo */ public <T> PageVo<T> query(String sql, Class<T> elementType, Integer page, Integer pageSize, Map<String,Object> args) throws Exception { NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource()); sql = sql.toLowerCase(); log.info("query sql:"+sql); SqlReCreateFactory sqlReCreateFactory = new SqlReCreateFactory<Object>(sql, page, pageSize, args).invoke(); sql = sqlReCreateFactory.getSql(); PageVo<T> pageVo = sqlReCreateFactory.getPageVo(); List<T> result = namedParameterJdbcTemplate.query(sql, args, new BeanPropertyRowMapper<>(elementType)); pageVo.setResult(result); return pageVo; } private class SqlReCreateFactory<T> { // private String sql; private Integer page; private Integer pageSize; private Map<String,Object> args; private PageVo<T> pageVo; public SqlReCreateFactory(String sql, Integer page, Integer pageSize, Map<String, Object> args) { this.sql = sql; this.page = page; this.pageSize = pageSize; this.args = args; } public String getSql() { return sql; } public PageVo<T> getPageVo() { return pageVo; } public SqlReCreateFactory invoke() { NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource()); pageVo = new PageVo<>(0, pageSize); String sqlCount = "select count(*) from (" + sql + ") "; // oracle數據庫不需要別名 //String sqlCount = "select count(*) from (" + sql + ") c "; //mysql數據庫需要別名,不然會報 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Every derived table must have its own alias這個錯誤 //String sqlCount = getSQLCount(sql); 也可以用這種方式計算總數 Integer count = namedParameterJdbcTemplate.queryForObject(sqlCount, args, Integer.class); //查詢頁數 pageVo.setTotalCount(count); pageVo.setCurrentPage(page); int pageNum = 0; if (count != null && count > 0) { if (count % pageSize == 0) { pageNum = count / pageSize; } else { pageNum = count / pageSize + 1; } pageVo.setPageNum(pageNum); } //這種方法也可以 /*Integer pageNum = calTotalPages(pageSize, count); pageVo.setPageNum(pageNum);*/ int pageMin = (page - 1) * pageSize; int pageMax = pageMin + pageSize; //oracle是這樣的 //int pageMax = pageSize; //mysql分頁是:第一頁是select * from users limit 0,10;第二頁是select * from users limit 10,10; args.put("pagemin",pageMin); args.put("pagemax",pageMax); sql = "select p.* from (select t.* ,rownum rownumber from (" +sql+ ") t) p where p.rownumber>:pagemin and p.rownumber<=:pagemax "; return this; } } /** * 獲得計算總數的sql * @param sql * @return */ public String getSQLCount(String sql) { String sqlBak = sql.toLowerCase(); String searchValue = " from "; String sqlCount = "select count(*) from " + sql.substring(sqlBak.indexOf(searchValue) + searchValue.length(), sqlBak.length()); return sqlCount; } // 計算總頁數 public Integer calTotalPages(int numPerPage, int totalRows) { if (totalRows % numPerPage == 0) { return totalRows / numPerPage; } else { return (totalRows / numPerPage) + 1; } } // 計算總頁數 /* public void setTotalPages(int numPerPage, int totalRows) { if (totalRows % numPerPage == 0) { this.totalPages = totalRows / numPerPage; } else { this.totalPages = (totalRows / numPerPage) + 1; } }*/ }
2.1.7 service
2.1.7.1 JdbcTemplateService.class
package com.springdataJpa.oracle.service; import com.springdataJpa.oracle.model.Users; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; /** * @date 2018/6/26 */ @Service public class JdbcTemplateService { @Autowired JdbcTemplate jdbcTemplate; /** * 添加用戶 * * @param users * @return */ public Integer add(Users users) { String insertSql = "insert into users(id,user_name,age,sex,status,date_created) values (?,?,?,?,?,?)"; List<Object> list = new ArrayList<>(); list.add(users.getId()); list.add(users.getUserName()); list.add(users.getAge()); list.add(users.getSex()); list.add(users.getStatus()); list.add(users.getDateCreated()); //int count = jdbcTemplate.update(insertSql, new Object[]{users.getId(), users.getUserName(), users.getAge(), users.getSex(),users.getStatus(),users.getDateCreated()}); int count = jdbcTemplate.update(insertSql,list.toArray()); return count; } /** * 更新用戶 * * @param users * @return */ public Integer update(Users users) { String updateSql = "update users u set u.user_name = ? where u.id = ? "; int count = jdbcTemplate.update(updateSql, new Object[]{users.getUserName(), users.getId()}); return count; } /** * 刪除用戶 * * @param users * @return */ public Integer delete(Users users) { String deleteSql = "delete from users where id = ? "; int count = jdbcTemplate.update(deleteSql, new Object[]{users.getId()}); return count; } /** * 批量添加用戶 * * @param users * @return */ public int[] adds(List<Users> users) { final List<Users> tempUsers = users; String insertsSql = "insert into users(id,user_name,age,sex,status) values (?,?,?,?,?)"; int[] ints = jdbcTemplate.batchUpdate(insertsSql, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { String id = tempUsers.get(i).getId(); String userName = tempUsers.get(i).getUserName(); Integer age = tempUsers.get(i).getAge(); String sex = tempUsers.get(i).getSex(); String status = tempUsers.get(i).getStatus(); ps.setString(1, id); ps.setString(2, userName); ps.setInt(3, age); ps.setString(4, sex); ps.setString(5, status); } @Override public int getBatchSize() { return tempUsers.size(); } }); return ints; } /** * 查詢列表 * * @return */ public List<Users> usersQuery() { List<Users> users = null; String querySql = "select * from users"; try { users = jdbcTemplate.query(querySql, new BeanPropertyRowMapper<Users>(Users.class)); } catch (Exception e) { e.printStackTrace(); } return users; } }
2.1.7.2 QueryPageService.class
package com.springdataJpa.oracle.service; import com.springdataJpa.oracle.dto.UsersQuery; import com.springdataJpa.oracle.model.Users; import com.springdataJpa.oracle.util.Lang; import com.springdataJpa.oracle.util.QueryByPage; import com.springdataJpa.oracle.vo.PageVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author luoxianwei * @date 2018/6/26 */ @Service @Slf4j public class QueryPageService { @Autowired private QueryByPage queryByPage; /** * 分頁查詢(不帶條件) * * @param pageSize * @param pageNumber * @return */ public PageVo<Users> usersList(int pageSize, int pageNumber) { PageVo<Users> usersPageVo = null; Map<String, Object> sqlList = usersListSql(); try { usersPageVo = queryByPage.query(String.valueOf(sqlList.get("sql")), Users.class, pageNumber, pageSize, ((List) sqlList.get("list")).toArray()); } catch (Exception e) { e.printStackTrace(); } return usersPageVo; } /** * 列表查詢Sql * * @return */ public Map<String, Object> usersListSql() { StringBuffer sql = new StringBuffer(); sql.append(" select * from users u "); List<Object> list = new ArrayList<Object>(); log.info("列表查詢Sql===》:{}", sql.toString()); Map<String, Object> map = new HashMap<>(); map.put("sql", sql.toString()); map.put("list", list); return map; } /** * 分頁查詢(帶條件不帶In) * * @param pageSize * @param pageNumber * @return */ public PageVo<Users> usersQueryList(int pageSize, int pageNumber, UsersQuery usersQuery) { PageVo<Users> usersPageVo = null; Map<String, Object> sqlList = usersQueryListSql(usersQuery); try { usersPageVo = queryByPage.query(String.valueOf(sqlList.get("sql")), Users.class, pageNumber, pageSize, ((List) sqlList.get("list")).toArray()); } catch (Exception e) { e.printStackTrace(); } return usersPageVo; } /** * 列表查詢Sql * * @return */ public Map<String, Object> usersQueryListSql(UsersQuery usersQuery) { StringBuffer sql = new StringBuffer(); sql.append(" select * from users u where 1 = 1 "); List<Object> list = new ArrayList<>(); if (!Lang.isEmpty(usersQuery.getUserName())) { sql.append(" and u.user_name = ? "); list.add(usersQuery.getUserName()); } if (!Lang.isEmpty(usersQuery.getAge())) { sql.append(" and u.age = ? "); list.add(usersQuery.getAge()); } if (!Lang.isEmpty(usersQuery.getSex())) { sql.append(" and u.sex = ? "); list.add(usersQuery.getSex()); } log.info("列表查詢Sql===》:{}", sql.toString()); Map<String, Object> map = new HashMap<>(); map.put("sql", sql.toString()); map.put("list", list); return map; } }
2.1.7.3 JdbcTemplatePageService.class
package com.springdataJpa.oracle.service; import com.springdataJpa.oracle.dto.UsersQuery; import com.springdataJpa.oracle.model.Users; import com.springdataJpa.oracle.util.JdbcTemplatePage; import com.springdataJpa.oracle.util.Lang; import com.springdataJpa.oracle.vo.PageVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author luoxianwei * @date 2018/6/26 */ @Service @Slf4j public class JdbcTemplatePageService { @Autowired private JdbcTemplatePage jdbcTemplatePage; /** * 分頁查詢(帶條件帶In) * * @param pageSize * @param pageNumber * @return */ public PageVo<Users> usersQueryInList(int pageSize, int pageNumber, UsersQuery usersQuery) { PageVo<Users> usersPageVo = null; Map<String, Object> sqlList = usersQueryInListSql(usersQuery); try { usersPageVo = jdbcTemplatePage.query(String.valueOf(sqlList.get("sql")), Users.class, pageNumber, pageSize, (Map<String, Object>) sqlList.get("params")); } catch (Exception e) { e.printStackTrace(); } return usersPageVo; } /** * 列表查詢Sql * * @return */ public Map<String, Object> usersQueryInListSql(UsersQuery usersQuery) { StringBuffer sql = new StringBuffer(); sql.append(" select * from users u where 1 = 1 "); Map<String, Object> params = new HashMap<String, Object>(); if (!Lang.isEmpty(usersQuery.getUserName())) { sql.append(" and u.user_name = :username "); //別名要小些,因為后面sql都轉換為小寫 params.put("username", usersQuery.getUserName()); } if (!Lang.isEmpty(usersQuery.getAge())) { sql.append(" and u.age = :age "); params.put("age", usersQuery.getAge()); } if (!Lang.isEmpty(usersQuery.getSex())) { sql.append(" and u.sex = :sex "); params.put("sex", usersQuery.getSex()); } List<Object> list = new ArrayList<>(); if (!Lang.isEmpty(usersQuery.getStatus())) { String[] status = usersQuery.getStatus().split(","); for (String statu : status) { list.add(statu); } sql.append(" and u.status in (:status) "); params.put("status", list); } log.info("列表查詢Sql===》:{}", sql.toString()); Map<String, Object> map = new HashMap<>(); map.put("sql", sql.toString()); map.put("params", params); return map; } }
2.1.8 test
package com.springdataJpa.oracle.test; import com.springdataJpa.oracle.OracleJdbcTemplateApplication; import com.springdataJpa.oracle.dto.UsersQuery; import com.springdataJpa.oracle.model.Users; import com.springdataJpa.oracle.service.JdbcTemplatePageService; import com.springdataJpa.oracle.service.JdbcTemplateService; import com.springdataJpa.oracle.service.QueryPageService; import com.springdataJpa.oracle.vo.PageVo; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * @author luoxianwei * @date 2018/6/26 */ @SpringBootTest(classes = OracleJdbcTemplateApplication.class) @RunWith(SpringRunner.class) public class UsersTest { @Autowired JdbcTemplateService jdbcTemplateService; @Autowired QueryPageService queryPageService; @Autowired JdbcTemplatePageService jdbcTemplatePageService; /** * 添加用戶 */ @Test public void addUsers() { Users users = new Users(); String id = UUID.randomUUID().toString(); users.setId(id); users.setUserName("張三"); users.setAge(20); users.setSex("男"); users.setStatus("1"); Integer count = jdbcTemplateService.add(users); System.out.println("成功插入:" + count); } /** * 更新用戶 */ @Test public void updateUsers() { Users users = new Users(); users.setId("1ef1f637-87da-40e9-935e-328928a78884"); users.setUserName("李四"); Integer count = jdbcTemplateService.update(users); System.out.println("成功修改:" + count); } /** * 刪除用戶 */ @Test public void deleteUsers() { Users users = new Users(); users.setId("f5c05e22-6c5c-4f8c-97e0-2fe9fa919714"); Integer count = jdbcTemplateService.delete(users); System.out.println("成功刪除:" + count); } /** * 批量添加用戶 */ @Test public void addsUsers() { List<Users> users = new ArrayList<Users>(); for (int i = 0; i < 1000; i++) { Users users1 = new Users(); String uuid = UUID.randomUUID().toString(); users1.setId(uuid); users1.setUserName(uuid.substring(2, 5)); if (i < 200) { users1.setStatus("1"); users1.setSex("男"); users1.setAge(20); } else if (i < 500) { users1.setStatus("2"); users1.setSex("男"); users1.setAge(20); } else if (i < 700) { users1.setStatus("3"); users1.setSex("女"); users1.setAge(18); } else { users1.setStatus("4"); users1.setSex("女"); users1.setAge(18); } users.add(users1); } int[] adds = jdbcTemplateService.adds(users); System.out.println("批量添加:" + adds.length); } /** * 查詢列表 */ @Test public void usersQuery() { List<Users> users = jdbcTemplateService.usersQuery(); System.out.println("成功查詢:" + users.size() + "條"); } /** * 分頁查詢(不帶條件) */ @Test public void usersList() { PageVo<Users> usersPageVo = queryPageService.usersList(10, 1); System.out.println("成功分頁查詢:" + usersPageVo.getResult().size() + "條"); } /** * 分頁查詢(帶條件不帶In) */ @Test public void usersQueryList() { UsersQuery usersQuery = new UsersQuery(); usersQuery.setSex("男"); usersQuery.setAge(20); PageVo<Users> pageVo = queryPageService.usersQueryList(10, 1, usersQuery); System.out.println("成功分頁查詢:" + pageVo.getResult().size() + "條"); } /** * 分頁查詢(帶條件帶In) */ @Test public void usersQueryInList() { UsersQuery usersQuery = new UsersQuery(); usersQuery.setSex("男"); usersQuery.setAge(20); usersQuery.setStatus("1,2"); PageVo<Users> pageVo = jdbcTemplatePageService.usersQueryInList(10, 1, usersQuery); System.out.println("成功分頁查詢:" + pageVo.getTotalCount() + "條"); } }
2.2 mysqlDatabase
2.2.1 pom.xml
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
2.2.2 application.properties
server.port=8089
server.servlet-path=/
spring.resources.static-locations=classpath:/static/,classpath:/templates/
spring.mvc.view.suffix=.html
#配置數據源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jdbcTemplate
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
#在控制台輸出彩色日志
spring.output.ansi.enabled=always
2.2.3 model
2.2.3.1 BaseDomain.class
package com.springdataJpa.mysql.model.base; import lombok.Data; import javax.persistence.Column; import javax.persistence.MappedSuperclass; import java.io.Serializable; import java.util.Date; /** * @author luoxianwei * @date 2018/5/14 */ @MappedSuperclass @Data public class BaseDomain implements Serializable { /** * 創建日期 */ @Column(columnDefinition ="timestamp comment '創建日期'") private Date dateCreated; /** * 最后更新日期 */ @Column(columnDefinition ="timestamp comment '最后更新日期'") private Date lastUpdated; /** * 刪除日期 */ @Column(columnDefinition ="timestamp comment '刪除日期'") private Date deleteDate; /** * 刪除標記 */ @Column(columnDefinition ="int(1) default 0 comment '刪除標記'") private int isDelete ; public void setLastUpdated(Date lastUpdated) { this.lastUpdated = lastUpdated == null? null : lastUpdated; } public void setDeleteDate(Date deleteDate) { this.deleteDate = deleteDate == null? null : deleteDate; } }
2.2.3.2 Users.class
package com.springdataJpa.mysql.model; import com.springdataJpa.mysql.model.base.BaseDomain; import lombok.Data; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.io.Serializable; /** * @author luoxianwei * @date 2018/5/11 */ @Entity @Table @Data public class Users extends BaseDomain implements Serializable { //用戶狀態:1.在線;2.隱身;3.離線;4.忙碌 private static final String USER_STATUS_ONLINE = "1"; //用戶狀態:2.隱身; private static final String USER_STATUS_INVISIBLE = "2"; //用戶狀態:3.離線; private static final String USER_STATUS_OFFLINE = "3"; //用戶狀態:4.忙碌 private static final String USER_STATUS_BEBUSY = "4"; @Id @GenericGenerator(name = "PKUUID", strategy = "uuid2") @GeneratedValue(generator = "PKUUID") @Column(columnDefinition = "varchar(255) comment '用戶Id'") private String id; @Column(columnDefinition = "varchar(255) comment '姓名'") private String userName; @Column(columnDefinition = "int comment '年齡'") private Integer age; @Column(columnDefinition = "varchar(255) comment '性別'") private String sex; /** * 用戶狀態:1.在線;2.隱身;3.離線;4.忙碌 */ @Column(columnDefinition = "varchar(255) comment '狀態'") private String status; }
2.2.4 dto
2.2.4.1 UsersQuery.class
package com.springdataJpa.mysql.dto; import lombok.Data; @Data public class UsersQuery { private String id; private String userName; private Integer age; private String sex; private String status; }
2.2.5 vo
2.2.5.1 PageVo.class
package com.springdataJpa.mysql.vo; import lombok.Data; import java.io.Serializable; import java.util.List; @Data public class PageVo<T> implements Serializable { //分頁查詢結果 List<T> Result; //頁總數 Integer pageNum; //一頁記錄數 Integer pageSize; //總記錄數 Integer totalCount; //當前頁 Integer currentPage; public PageVo() { } public PageVo(Integer pageNum, Integer pageSize) { this.pageNum = pageNum; this.pageSize = pageSize; } }
2.2.6 util
2.2.6.1 Lang.class
同上面的一樣
2.2.6.2 Pagination.class
package com.springdataJpa.mysql.util; import com.springdataJpa.mysql.vo.PageVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * 分頁查詢封裝類(類似於使用oracle數據庫util中的QueryByPage,不適合sql帶In的查詢) */ @Component @Slf4j public class Pagination { @Autowired JdbcTemplate jdbcTemplate; /** * @param sql * @param elementType 返回需要封裝的javaVo * @param page * @param pageSize * @param args sql參數 * @return PageVo */ public <T> PageVo<T> query(String sql, Class<T> elementType, Integer page, Integer pageSize, Object... args) throws Exception { sql = sql.toLowerCase(); log.info("query sql:" + sql); SqlReCreateFactory sqlReCreateFactory = new SqlReCreateFactory<Object>(sql, page, pageSize, args).invoke(); sql = sqlReCreateFactory.getSql(); List<Object> argsList = sqlReCreateFactory.getArgsList(); PageVo<T> pageVo = sqlReCreateFactory.getPageVo(); List<T> result = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(elementType), argsList.toArray()); pageVo.setResult(result); return pageVo; } /** * @param sql 默認封裝成List<Map<String,Object>> * @param page * @param pageSize * @param args sql參數 * @return PageVo */ public PageVo query(String sql, Integer page, Integer pageSize, Object... args) throws Exception { sql = sql.toLowerCase(); log.info("query sql:" + sql); SqlReCreateFactory sqlReCreateFactory = new SqlReCreateFactory<Object>(sql, page, pageSize, args).invoke(); sql = sqlReCreateFactory.getSql(); List<Object> argsList = sqlReCreateFactory.getArgsList(); PageVo<Map<String, Object>> pageVo = sqlReCreateFactory.getPageVo(); List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, argsList.toArray()); pageVo.setResult(result); return pageVo; } public PageVo querySqlCaseNoConvert(String sql, Integer page, Integer pageSize, Object... args) throws Exception { log.info("SQL IS {}", sql); SqlReCreateFactory sqlReCreateFactory = new SqlReCreateFactory<>(sql, page, pageSize, args).invoke(); sql = sqlReCreateFactory.getSql(); List<Object> argsList = sqlReCreateFactory.getArgsList(); PageVo<Map<String, Object>> pageVo = sqlReCreateFactory.getPageVo(); List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, argsList.toArray()); pageVo.setResult(result); return pageVo; } private class SqlReCreateFactory<T> { // private String sql; private Integer page; private Integer pageSize; private Object[] args; private PageVo<T> pageVo; private List<Object> argsList; public SqlReCreateFactory(String sql, Integer page, Integer pageSize, Object... args) { this.sql = sql; this.page = page; this.pageSize = pageSize; this.args = args; } public String getSql() { return sql; } public PageVo<T> getPageVo() { return pageVo; } public List<Object> getArgsList() { return argsList; } public SqlReCreateFactory invoke() { pageVo = new PageVo<>(0, pageSize); //String sqlCount = "select count(*) from (" + sql + ") "; oracle數據庫不需要別名 String sqlCount = "select count(*) from (" + sql + ") c "; //mysql數據庫需要別名,不然會報 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Every derived table must have its own alias這個錯誤 //String sqlCount = getSQLCount(sql); 也可以用這種方式計算總數 Integer count = jdbcTemplate.queryForObject(sqlCount, args, Integer.class); //查詢頁數 pageVo.setTotalCount(count); pageVo.setCurrentPage(page); int pageNum = 0; if (count != null && count > 0) { if (count % pageSize == 0) { pageNum = count / pageSize; } else { pageNum = count / pageSize + 1; } pageVo.setPageNum(pageNum); } //這種方法也可以 /*Integer pageNum = calTotalPages(pageSize, count); pageVo.setPageNum(pageNum);*/ int pageMin = (page - 1) * pageSize; //int pageMax = pageMin + pageSize; oracle是這樣的 int pageMax = pageSize; //mysql分頁是:第一頁是select * from users limit 0,10;第二頁是select * from users limit 10,10; argsList = new ArrayList<>(); for (Object arg : args) { argsList.add(arg); } argsList.add(pageMin); argsList.add(pageMax); //sql = "select p.* from (select t.* ,rownum rownumber from (" + sql + ") t) p where p.rownumber>? and p.rownumber<=? "; oracle數據庫是這樣的 sql = sql + "limit ?,? " ; //mysql數據庫是這樣的 return this; } } /** * 獲得計算總數的sql * @param sql * @return */ public String getSQLCount(String sql) { String sqlBak = sql.toLowerCase(); String searchValue = " from "; String sqlCount = "select count(*) from " + sql.substring(sqlBak.indexOf(searchValue) + searchValue.length(), sqlBak.length()); return sqlCount; } // 計算總頁數 public Integer calTotalPages(int numPerPage, int totalRows) { if (totalRows % numPerPage == 0) { return totalRows / numPerPage; } else { return (totalRows / numPerPage) + 1; } } // 計算總頁數 /* public void setTotalPages(int numPerPage, int totalRows) { if (totalRows % numPerPage == 0) { this.totalPages = totalRows / numPerPage; } else { this.totalPages = (totalRows / numPerPage) + 1; } }*/ }
2.2.6.3 JdbcTemplatePage.class
package com.springdataJpa.mysql.util; import com.springdataJpa.mysql.vo.PageVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; /** * parent * * @date 2018/7/25 * 分頁查詢(擁有Pagination的功能,並且適合sql語句帶In的查詢) */ @Component @Slf4j public class JdbcTemplatePage { @Autowired JdbcTemplate jdbcTemplate; /** * @param sql * @param elementType 返回需要封裝的pageVo * @param page * @param pageSize * @param args * @return PageVo */ public <T> PageVo<T> query(String sql, Class<T> elementType, Integer page, Integer pageSize, Map<String,Object> args) throws Exception { NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource()); sql = sql.toLowerCase(); log.info("query sql:"+sql); SqlReCreateFactory sqlReCreateFactory = new SqlReCreateFactory<Object>(sql, page, pageSize, args).invoke(); sql = sqlReCreateFactory.getSql(); PageVo<T> pageVo = sqlReCreateFactory.getPageVo(); List<T> result = namedParameterJdbcTemplate.query(sql, args, new BeanPropertyRowMapper<>(elementType)); pageVo.setResult(result); return pageVo; } private class SqlReCreateFactory<T> { // private String sql; private Integer page; private Integer pageSize; private Map<String,Object> args; private PageVo<T> pageVo; public SqlReCreateFactory(String sql, Integer page, Integer pageSize, Map<String, Object> args) { this.sql = sql; this.page = page; this.pageSize = pageSize; this.args = args; } public String getSql() { return sql; } public PageVo<T> getPageVo() { return pageVo; } public SqlReCreateFactory invoke() { NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource()); pageVo = new PageVo<>(0, pageSize); //String sqlCount = "select count(*) from (" + sql + ") "; oracle數據庫不需要別名 String sqlCount = "select count(*) from (" + sql + ") c "; //mysql數據庫需要別名,不然會報 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Every derived table must have its own alias這個錯誤 //String sqlCount = getSQLCount(sql); 也可以用這種方式計算總數 Integer count = namedParameterJdbcTemplate.queryForObject(sqlCount, args, Integer.class); //查詢頁數 pageVo.setTotalCount(count); pageVo.setCurrentPage(page); int pageNum = 0; if (count != null && count > 0) { if (count % pageSize == 0) { pageNum = count / pageSize; } else { pageNum = count / pageSize + 1; } pageVo.setPageNum(pageNum); } //這種方法也可以 /*Integer pageNum = calTotalPages(pageSize, count); pageVo.setPageNum(pageNum);*/ int pageMin = (page - 1) * pageSize; //int pageMax = pageMin + pageSize; oracle是這樣的 int pageMax = pageSize; //mysql分頁是:第一頁是select * from users limit 0,10;第二頁是select * from users limit 10,10; args.put("pagemin",pageMin); args.put("pagemax",pageMax); //sql = "select p.* from (select t.* ,rownum rownumber from (" +sql+ ") t) p where p.rownumber>:pagemin and p.rownumber<=:pagemax ";oracle數據庫是這樣的 sql = sql + "limit :pagemin,:pagemax " ; //mysql數據庫是這樣的 return this; } } /** * 獲得計算總數的sql * @param sql * @return */ public String getSQLCount(String sql) { String sqlBak = sql.toLowerCase(); String searchValue = " from "; String sqlCount = "select count(*) from " + sql.substring(sqlBak.indexOf(searchValue) + searchValue.length(), sqlBak.length()); return sqlCount; } // 計算總頁數 public Integer calTotalPages(int numPerPage, int totalRows) { if (totalRows % numPerPage == 0) { return totalRows / numPerPage; } else { return (totalRows / numPerPage) + 1; } } // 計算總頁數 /* public void setTotalPages(int numPerPage, int totalRows) { if (totalRows % numPerPage == 0) { this.totalPages = totalRows / numPerPage; } else { this.totalPages = (totalRows / numPerPage) + 1; } }*/ }
2.2.7 service
2.2.7.1 JdbcTemplateService.class
package com.springdataJpa.mysql.service; import com.springdataJpa.mysql.model.Users; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; /** * @date 2018/6/26 */ @Service public class JdbcTemplateService { @Autowired JdbcTemplate jdbcTemplate; /** * 添加用戶 * * @param users * @return */ public Integer add(Users users) { String insertSql = "insert into users(id,user_name,age,sex) values (?,?,?,?)"; int count = jdbcTemplate.update(insertSql, new Object[]{users.getId(), users.getUserName(), users.getAge(), users.getSex()}); return count; } /** * 更新用戶 * * @param users * @return */ public Integer update(Users users) { String updateSql = "update users u set u.user_name = ? where u.id = ? "; int count = jdbcTemplate.update(updateSql, new Object[]{users.getUserName(), users.getId()}); return count; } /** * 刪除用戶 * * @param users * @return */ public Integer delete(Users users) { String deleteSql = "delete from users where id = ? "; int count = jdbcTemplate.update(deleteSql, new Object[]{users.getId()}); return count; } /** * 批量添加用戶 * * @param users * @return */ public int[] adds(List<Users> users) { final List<Users> tempUsers = users; String insertsSql = "insert into users(id,user_name,age,sex,status) values (?,?,?,?,?)"; int[] ints = jdbcTemplate.batchUpdate(insertsSql, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { String id = tempUsers.get(i).getId(); String userName = tempUsers.get(i).getUserName(); Integer age = tempUsers.get(i).getAge(); String sex = tempUsers.get(i).getSex(); String status = tempUsers.get(i).getStatus(); ps.setString(1, id); ps.setString(2, userName); ps.setInt(3, age); ps.setString(4, sex); ps.setString(5, status); } @Override public int getBatchSize() { return tempUsers.size(); } }); return ints; } /** * 查詢列表 * * @return */ public List<Users> usersQuery() { List<Users> users = null; String querySql = "select * from users"; try { users = jdbcTemplate.query(querySql, new BeanPropertyRowMapper<Users>(Users.class)); } catch (Exception e) { e.printStackTrace(); } return users; } }
2.2.7.2 PaginationService.class
package com.springdataJpa.mysql.service; import com.springdataJpa.mysql.dto.UsersQuery; import com.springdataJpa.mysql.model.Users; import com.springdataJpa.mysql.util.Lang; import com.springdataJpa.mysql.util.Pagination; import com.springdataJpa.mysql.vo.PageVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author luoxianwei * @date 2018/6/26 */ @Service @Slf4j public class PaginationService { @Autowired private Pagination pagination; /** * 分頁查詢(不帶條件) * * @param pageSize * @param pageNumber * @return */ public PageVo<Users> usersList(int pageSize, int pageNumber) { PageVo<Users> usersPageVo = null; Map<String, Object> sqlList = usersListSql(); try { usersPageVo = pagination.query(String.valueOf(sqlList.get("sql")), Users.class, pageNumber, pageSize, ((List) sqlList.get("list")).toArray()); } catch (Exception e) { e.printStackTrace(); } return usersPageVo; } /** * 列表查詢Sql * * @return */ public Map<String, Object> usersListSql() { StringBuffer sql = new StringBuffer(); sql.append(" select * from users u "); List<Object> list = new ArrayList<Object>(); log.info("列表查詢Sql===》:{}", sql.toString()); Map<String, Object> map = new HashMap<>(); map.put("sql", sql.toString()); map.put("list", list); return map; } /** * 分頁查詢(帶條件不帶In) * * @param pageSize * @param pageNumber * @return */ public PageVo<Users> usersQueryList(int pageSize, int pageNumber, UsersQuery usersQuery) { PageVo<Users> usersPageVo = null; Map<String, Object> sqlList = usersQueryListSql(usersQuery); try { usersPageVo = pagination.query(String.valueOf(sqlList.get("sql")), Users.class, pageNumber, pageSize, ((List) sqlList.get("list")).toArray()); } catch (Exception e) { e.printStackTrace(); } return usersPageVo; } /** * 列表查詢Sql * * @return */ public Map<String, Object> usersQueryListSql(UsersQuery usersQuery) { StringBuffer sql = new StringBuffer(); sql.append(" select * from users u where u.is_delete = 0 "); List<Object> list = new ArrayList<>(); if (!Lang.isEmpty(usersQuery.getUserName())) { sql.append(" and u.user_name = ? "); list.add(usersQuery.getUserName()); } if (!Lang.isEmpty(usersQuery.getAge())) { sql.append(" and u.age = ? "); list.add(usersQuery.getAge()); } if (!Lang.isEmpty(usersQuery.getSex())) { sql.append(" and u.sex = ? "); list.add(usersQuery.getSex()); } log.info("列表查詢Sql===》:{}", sql.toString()); Map<String, Object> map = new HashMap<>(); map.put("sql", sql.toString()); map.put("list", list); return map; } }
2.2.7.3 JdbcTemplatePageService.class
package com.springdataJpa.mysql.service; import com.springdataJpa.mysql.dto.UsersQuery; import com.springdataJpa.mysql.model.Users; import com.springdataJpa.mysql.util.JdbcTemplatePage; import com.springdataJpa.mysql.util.Lang; import com.springdataJpa.mysql.vo.PageVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author luoxianwei * @date 2018/6/26 */ @Service @Slf4j public class JdbcTemplatePageService { @Autowired private JdbcTemplatePage jdbcTemplatePage; /** * 分頁查詢(帶條件帶In) * * @param pageSize * @param pageNumber * @return */ public PageVo<Users> usersQueryInList(int pageSize, int pageNumber, UsersQuery usersQuery) { PageVo<Users> usersPageVo = null; Map<String, Object> sqlList = usersQueryInListSql(usersQuery); try { usersPageVo = jdbcTemplatePage.query(String.valueOf(sqlList.get("sql")), Users.class, pageNumber, pageSize, (Map<String, Object>) sqlList.get("params")); } catch (Exception e) { e.printStackTrace(); } return usersPageVo; } /** * 列表查詢Sql * * @return */ public Map<String, Object> usersQueryInListSql(UsersQuery usersQuery) { StringBuffer sql = new StringBuffer(); sql.append(" select * from users u where u.is_delete = 0 "); Map<String, Object> params = new HashMap<String, Object>(); if (!Lang.isEmpty(usersQuery.getUserName())) { sql.append(" and u.user_name = :username "); //別名要小些,因為后面sql都轉換為小寫 params.put("username", usersQuery.getUserName()); } if (!Lang.isEmpty(usersQuery.getAge())) { sql.append(" and u.age = :age "); params.put("age", usersQuery.getAge()); } if (!Lang.isEmpty(usersQuery.getSex())) { sql.append(" and u.sex = :sex "); params.put("sex", usersQuery.getSex()); } List<Object> list = new ArrayList<>(); if (!Lang.isEmpty(usersQuery.getStatus())) { String[] status = usersQuery.getStatus().split(","); for (String statu : status) { list.add(statu); } sql.append(" and u.status in (:status) "); params.put("status", list); } log.info("列表查詢Sql===》:{}", sql.toString()); Map<String, Object> map = new HashMap<>(); map.put("sql", sql.toString()); map.put("params", params); return map; } }
2.2.8 test
package com.springdataJpa.mysql.test; import com.springdataJpa.mysql.MysqlJdbcTemplateApplication; import com.springdataJpa.mysql.dto.UsersQuery; import com.springdataJpa.mysql.model.Users; import com.springdataJpa.mysql.service.JdbcTemplatePageService; import com.springdataJpa.mysql.service.JdbcTemplateService; import com.springdataJpa.mysql.service.PaginationService; import com.springdataJpa.mysql.vo.PageVo; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * @author luoxianwei * @date 2018/6/26 */ @SpringBootTest(classes = MysqlJdbcTemplateApplication.class) @RunWith(SpringRunner.class) public class UsersTest { @Autowired JdbcTemplateService jdbcTemplateService; @Autowired PaginationService paginationService; @Autowired JdbcTemplatePageService jdbcTemplatePageService; /** * 添加用戶 */ @Test public void addUsers() { Users users = new Users(); String id = UUID.randomUUID().toString(); users.setId(id); users.setUserName("張三"); users.setAge(20); users.setSex("男"); Integer count = jdbcTemplateService.add(users); System.out.println("成功插入:" + count); } /** * 更新用戶 */ @Test public void updateUsers() { Users users = new Users(); users.setId("0458ec1d-789a-4725-b5f6-8a381446fbf0"); users.setUserName("李四"); Integer count = jdbcTemplateService.update(users); System.out.println("成功修改:" + count); } /** * 刪除用戶 */ @Test public void deleteUsers() { Users users = new Users(); users.setId("0458ec1d-789a-4725-b5f6-8a381446fbf0"); Integer count = jdbcTemplateService.delete(users); System.out.println("成功刪除:" + count); } /** * 批量添加用戶 */ @Test public void addsUsers() { List<Users> users = new ArrayList<Users>(); for (int i = 0; i < 1000; i++) { Users users1 = new Users(); String uuid = UUID.randomUUID().toString(); users1.setId(uuid); users1.setUserName(uuid.substring(2, 5)); users1.setAge(20); users1.setSex("男"); if (i < 200) { users1.setStatus("1"); users1.setSex("男"); users1.setAge(20); } else if (i < 500) { users1.setStatus("2"); users1.setSex("男"); users1.setAge(20); } else if (i < 700) { users1.setStatus("3"); users1.setSex("女"); users1.setAge(18); } else { users1.setStatus("4"); users1.setSex("女"); users1.setAge(18); } users.add(users1); } int[] adds = jdbcTemplateService.adds(users); System.out.println("批量添加:" + adds.length); } /** * 查詢列表 */ @Test public void usersQuery() { List<Users> users = jdbcTemplateService.usersQuery(); System.out.println("成功查詢:" + users.size() + "條"); } /** * 分頁查詢(不帶條件) */ @Test public void usersList() { PageVo<Users> usersPageVo = paginationService.usersList(10, 2); System.out.println("成功分頁查詢:" + usersPageVo.getResult().size() + "條"); } /** * 分頁查詢(帶條件不帶In) */ @Test public void usersQueryList() { UsersQuery usersQuery = new UsersQuery(); usersQuery.setSex("男"); usersQuery.setAge(20); PageVo<Users> pageVo = paginationService.usersQueryList(10, 1, usersQuery); System.out.println("成功分頁查詢:" + pageVo.getTotalCount() + "條"); } /** * 分頁查詢(帶條件帶In) */ @Test public void usersQueryInList() { UsersQuery usersQuery = new UsersQuery(); usersQuery.setSex("男"); usersQuery.setAge(20); usersQuery.setStatus("1,2"); PageVo<Users> pageVo = jdbcTemplatePageService.usersQueryInList(10, 1, usersQuery); System.out.println("成功分頁查詢:" + pageVo.getTotalCount() + "條"); } }