content
The relationship between SpringDataJpa, jpa, hibernate
1. Create a Maven project and import coordinates
2. Write the configuration file of Spring Data JPA (applicationContext.xml)
3. Create entity classes, database tables
JpaRepository encapsulated methods
JpaSpecificationExecutor encapsulated method
1. Spring Data JPa
Introducing springDataJPa
Spring Data JPA is a set of JPA application framework encapsulated by Spring based on ORM framework and JPA specification, which enables developers to access and operate the database with minimal code. It provides common functions including CRUD, etc., and is easy to expand! Learning and using Spring Data JPA can greatly improve development efficiency!
Spring Data JPA is part of the larger Spring Data family of easily implementing JPA-based repositories. This module handles enhanced support for the JPA-based data access layer. It makes it easier to build Spring-driven applications that use data access technologies.
SpringDataJPA is actually an encapsulation abstraction of the JPA specification. The bottom layer is still implemented using Hibernate's JPA technology . It refers to the JPQL (Java Persistence Query Language) query language, which is part of the entire Spring ecosystem. With the popularity of Spring Boot and Spring Cloud in the market, Spring Data JPA has gradually entered everyone's field of vision. They form an organic whole, which is more convenient to use, and speeds up the development efficiency, so that developers do not need to care about and configure more It can be fully immersed in Spring's complete ecological standard implementation. JPA is easy to use, has high development efficiency, better support for objects, and has great flexibility, and the market's recognition is getting higher and higher.
Official website address : Spring Data JPA
The relationship between SpringDataJpa, jpa, hibernate
The underlying work is still Hibernate. I heard that the founders of JPA and Hibernate are the same person.
2. Build the environment
1. Create a Maven project and import coordinates
<?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">
<parent>
<artifactId>JPA</artifactId>
<groupId>com.dynamic</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>JPA-Day2</artifactId>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<hibernate.version>5.0.7.Final</hibernate.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<c3p0.version>0.9.1.2</c3p0.version>
<mysql.version>5.1.6</mysql.version>
</properties>
<dependencies>
<!-- junit单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- spring beg -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring对orm框架的支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring end -->
<!-- hibernate beg -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.1.Final</version>
</dependency>
<!-- hibernate end -->
<!-- c3p0 beg -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<!-- c3p0 end -->
<!-- log end -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- spring data jpa 的坐标-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- el beg 使用spring data jpa 必须引入 -->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<!-- el end -->
</dependencies>
</project>
2. Write the configuration file of Spring Data JPA (applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!-- 1.dataSource 配置数据库连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jpa" />
<property name="user" value="root" />
<property name="password" value="root" />
</bean>
<!-- 2.配置entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.dynamic.domain" />
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<!--jpa的供应商适配器 -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!--配置是否自动创建数据库表 -->
<property name="generateDdl" value="false" />
<!--指定数据库类型 -->
<property name="database" value="MYSQL" />
<!--数据库方言:支持的特有语法 -->
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
<!--是否显示sql -->
<property name="showSql" value="true" />
</bean>
</property>
<!--jpa的方言 :高级的特性 -->
<property name="jpaDialect" >
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<!-- 3.事务管理器-->
<!-- JPA事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 整合spring data jpa-->
<jpa:repositories base-package="com.dynamic.dao"
transaction-manager-ref="transactionManager"
entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
<!-- 4.txAdvice-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 5.aop-->
<!-- <aop:config>-->
<!-- <aop:pointcut id="pointcut" expression="execution(* com.dynamic.service.*.*(..))" />-->
<!-- <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />-->
<!-- </aop:config>-->
<context:component-scan base-package="com.dynamic"></context:component-scan>
<!--组装其它 配置文件-->
</beans>
3. Create entity classes, database tables
package com.dynamic.domain;
import javax.persistence.*;
/**
* @Author: Promsing(张有博)
* @Date: 2021/10/13 - 17:29
* @Description: 客户的实体类
* 配置映射关系
* 1.实体类和表的映射关系
* @Entity 声明是实体类
* @Table(name = "cst_customer") 实体类与表的映射关系,name配置表的名称
*
* 2.实体类中属性和表字段的映射关系
* @version: 1.0
*/
@Entity
@Table(name = "cst_customer")
public class Customer {
/**
* @Id:声明主键的配置
* @GeneratedValue:配置主键的生成策略
* strategy
* GenerationType.IDENTITY :自增,mysql
* * 底层数据库必须支持自动增长(底层数据库支持的自动增长方式,对id自增)
* GenerationType.SEQUENCE : 序列,oracle
* * 底层数据库必须支持序列
* GenerationType.TABLE : jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
* GenerationType.AUTO : 由程序自动的帮助我们选择主键生成策略
* @Column:配置属性和字段的映射关系
* name:数据库表中字段的名称
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "cust_id")
private Long id;//主键
@Column(name="cust_name")
private String custName;
@Column(name="cust_source")
private String custSource;
@Column(name = "cust_industry")
private String custIndustry;//所属行业
@Column(name="cust_level")
private String custLevel;
@Column(name = "cust_address")
private String custAddress;
@Column(name = "cost_phone")
private String custPhone;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", custName='" + custName + '\'' +
", custSource='" + custSource + '\'' +
", custIndustry='" + custIndustry + '\'' +
", custLevel='" + custLevel + '\'' +
", custAddress='" + custAddress + '\'' +
", custPhone='" + custPhone + '\'' +
'}';
}
}
4. SQL for database tables
CREATE TABLE `cst_customer` (
`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
`cust_address` varchar(128) DEFAULT NULL COMMENT '客户联系地址',
`cust_phone` varchar(64) DEFAULT NULL COMMENT '客户联系电话',
`cost_phone` varchar(255) DEFAULT NULL,
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
5. DAO interface
package com.dynamic.dao;
import com.dynamic.domain.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* @Author: Promsing(张有博)
* @Date: 2021/10/17 - 17:36
* @Description: 需要符合springDataJPA的dao层接口规范
* JpaRepository<操作的实体类型,实体类中主键属性的类型>
* *封装了基本的CRUD操作
* JpaSpecificationExecutor<操作的实体类型>
* *封装了复杂查询(分页)
* @version: 1.0
*/
public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {
}
Three, four query methods:
1. Basic CRUD
Inherit JpaRepository, JpaSpecificationExecutor interface, and use JPA-encapsulated methods.
JpaRepository encapsulated methods
JpaSpecificationExecutor encapsulated method
test class
/**
* findOne(id) :根据id查询
*
* save(customer):保存或更新 实体的id属性
*
* delete(id) :根据id删除
*
* findAll() :查询全部
*
* count() :计数
*
* exists() :判断是否存在
*
*/
@Test
public void testFindOne(){
System.out.println("dfa");
Customer one = dao.findOne(1L);
System.out.println(one);
}
@Test
public void testSave(){
System.out.println("dfa");
Customer c=new Customer();
c.setCustAddress("廊坊");
c.setCustName("小小张");
c.setCustPhone("9999");
c.setCustLevel("vipp");
Customer save = dao.save(c);
System.out.println(save);
}
@Test
@Transactional
public void testUpdate(){
System.out.println("dfa");
Customer c=new Customer();
c.setCustAddress("廊坊");
c.setCustName("小小张");
c.setCustPhone("2800");
Customer save = dao.save(c);
System.out.println(save);
}
@Test
public void testDelete(){
dao.delete(2L);
System.out.println();
}
@Test
@Transactional
public void testFindAll(){
List<Customer> all = dao.findAll();
for (Customer customer : all) {
System.out.println(customer);
}
System.out.println();
}
@Test
@Transactional
public void testCount(){
long count = dao.count();
System.out.println(count);
}
@Test
public void testExists(){
boolean exists = dao.exists(2L);
System.out.println(exists);
}
@Test
@Transactional
public void testGetOne(){
// getOone方法是懒加载
Customer one = dao.getOne(2L);
System.out.println(one);
}
2. JPQL query
jpa query language (jpq query language), similar to native SQL statements, and completely object-oriented, accessed through class names and attributes, querying classes and attributes in classes
The previous blog introduced JPQL:
The JPQL statement needs to be configured on the interface method
1. Unique query: method needs to be configured on the dao interface
2. On the newly added method, configure the jpql query statement in the form of annotations
3. Annotation: @Query
DAO interface:
/**
* @Author: Promsing(张有博)
* @Date: 2021/10/17 - 17:36
* @Description: 需要符合springDataJPA的dao层接口规范
* JpaRepository<操作的实体类型,实体类中主键属性的类型>
* *封装了基本的CRUD操作
* JpaSpecificationExecutor<操作的实体类型>
* *封装了复杂查询(分页)
* @version: 1.0
*/
public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {
/**
* @Query:表示查询
*
* @Modifying 表示更新的操作
*/
@Query(value = "from Customer where custName = ? ")
public List<Customer> findJpql(String custName);
/**
* 对于多个占位符参数
* 赋值的时候,默认情况下,占位符的位置需要和方法参数中的位置保持一致
*
* 可以指定占位符参数的位置
* ? 索引的方式,指定此占位符的取值来源
*/
@Query(value = "from Customer where custName = ? and id = ?")
// @Query(value = "from Customer where custName = ?2 and id = ?1")
public Object findCustNameAndId(String name,Long id);
@Query(value = "update Customer set custName = ? where id = ? ")
@Modifying //表示是,更新的操作
public Integer updateName(String name,Long id);
}
Test class:
@Test
public void testJpql(){
List<Customer> list = dao.findJpql("小小张");
System.out.println(list);
}
@Test
public void testFindCustNameAndId(){
Object one = dao.findCustNameAndId("小小张",1L);
System.out.println(one);
}
@Test
@Transactional //添加事务的支持
@Rollback(value = false)
/**
* springDataJpa中使用jpql完成更新/删除操作
* 需要手动添加事务的支持
* 默认会执行结束之后,回滚事务
* @Rollback: 设置是否自动回滚
* false(不) | true
*/
public void testUpdateName(){
Object one = dao.updateName("张自由",3L);
System.out.println(one);
}
3. SQL query
1. Unique query: method needs to be configured on the dao interface
2. On the newly added method, configure the sql query statement in the form of annotations
3. Annotation: @Query
value : jpql statement | sql statement
nativeQuery : false (use jpql query) | true (use native query: sql query)
DAO interface
package com.dynamic.dao;
import com.dynamic.domain.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* @Author: Promsing(张有博)
* @Date: 2021/10/17 - 17:36
* @Description: 需要符合springDataJPA的dao层接口规范
* JpaRepository<操作的实体类型,实体类中主键属性的类型>
* *封装了基本的CRUD操作
* JpaSpecificationExecutor<操作的实体类型>
* *封装了复杂查询(分页)
* @version: 1.0
*/
public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {
/**
* 使用sql的形式查询 查询全部用户
* SQL:select * from cst_customer
* @Query: 配置sql查询
* value:sqly语句
* nativeQuery:查询方式
* true:sql查询
* false:jpql查询
* @return
*/
@Query(value = "select * from cst_customer", nativeQuery = true)
public List<Customer> findSql();
@Query(value = "select * from cst_customer where cust_name like ?", nativeQuery = true)
public List<Customer> findLikeSql(String name );
}
Test class:
@Test
public void testSQL(){
List<Customer> list = dao.findSql();
List<Customer> sql = dao.findLikeSql("小%");
for (Customer customer : sql) {
System.out.println(customer);
}
}
4. Method named query
It is a more in-depth encapsulation of jpql query
We only need to define methods according to the method name rules provided by SpringDataJpa, no need to configure jpql statements to complete the query
According to the rules defined by Spring Data JPA, the query method starts with findBy. When a conditional query is involved, the attributes of the condition are connected with the condition keyword. It should be noted that the first letter of the condition attribute should be capitalized. When the framework parses the method name, it first intercepts the redundant prefix of the method name, and then parses the remaining part.
Part of the comparison table
Keyword |
Sample |
JPQL |
||
And |
findByLastnameAndFirstname |
… where x.lastname = ?1 and x.firstname = ?2 |
||
Or |
findByLastnameOrFirstname |
… where x.lastname = ?1 or x.firstname = ?2 |
||
Is,Equals |
findByFirstnameIs, findByFirstnameEquals |
… where x.firstname = ?1 |
||
Between |
findByStartDateBetween |
… where x.startDate between ?1 and ?2 |
||
LessThan |
findByAgeLessThan |
… where x.age < ?1 |
||
LessThanEqual |
findByAgeLessThanEqual |
… where x.age ⇐ ?1 |
||
GreaterThan |
findByAgeGreaterThan |
… where x.age > ?1 |
||
GreaterThanEqual |
findByAgeGreaterThanEqual |
… where x.age >= ?1 |
||
After |
findByStartDateAfter |
… where x.startDate > ?1 |
||
Before |
findByStartDateBefore |
… where x.startDate < ?1 |
||
IsNull |
findByAgeIsNull |
… where x.age is null |
||
IsNotNull,NotNull |
findByAge(Is)NotNull |
… where x.age not null |
||
Like |
findByFirstnameLike |
… where x.firstname like ?1 |
||
NotLike |
findByFirstnameNotLike |
… where x.firstname not like ?1 |
||
StartingWith |
findByFirstnameStartingWith |
… where x.firstname like ?1 (parameter bound with appended %) |
||
EndingWith |
findByFirstnameEndingWith |
… where x.firstname like ?1 (parameter bound with prepended %) |
||
Containing |
findByFirstnameContaining |
… where x.firstname like ?1 (parameter bound wrapped in %) |
||
OrderBy |
findByAgeOrderByLastnameDesc |
… where x.age = ?1 order by x.lastname desc |
||
Not |
findByLastnameNot |
… where x.lastname <> ?1 |
||
In |
findByAgeIn(Collection ages) |
… where x.age in ?1 |
||
swimming |
findByAgeNotIn(Collection age) |
… where x.age not in ?1 |
||
TRUE |
findByActiveTrue() |
… where x.active = true |
||
FALSE |
findByActiveFalse () |
… where x.active = false |
||
IgnoreCase |
findByFirstnameIgnoreCase |
… where UPPER(x.firstame) = UPPER(?1) |
DAO interface:
package com.dynamic.dao;
import com.dynamic.domain.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* @Author: Promsing(张有博)
* @Date: 2021/10/17 - 17:36
* @Description: 需要符合springDataJPA的dao层接口规范
* JpaRepository<操作的实体类型,实体类中主键属性的类型>
* *封装了基本的CRUD操作
* JpaSpecificationExecutor<操作的实体类型>
* *封装了复杂查询(分页)
* @version: 1.0
*/
public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {
/**
* 方法名的约定
*
* findBy:查询
* 对象中的属性名(首字母大写),查询条件
*
* findByCustName 根据客户名称查询
*
* 会根据方法名称进行解析 findBy from XXX where custName
* @param name
* @return
*/
//1.findBy +属性名称(根据属性名称进行完成匹配的查询=)
public Customer findByCustName(String name );
//2.findBy +属性名称 +“查询方式”(Like | isNull)
public List<Customer> findByCustNameLike(String name );
//3.findBy +属性名称 +“查询方式” +“多条件的连接符(and|or)” +属性名 +“查询方式”
public Customer findByCustNameLikeAndCustIndustry(String name,String industry);
}
Test class:
@Test
public void testFindNaming(){
Customer custName = dao.findByCustName("张自由");
System.out.println(custName);
System.out.println("______________");
List<Customer> byCustNameLike = dao.findByCustNameLike("小%");
for (Customer customer : byCustNameLike) {
System.out.println(customer);
}
System.out.println("______________");
Customer it = dao.findByCustNameLikeAndCustIndustry("小%", "IT教育");
System.out.println(it);
}