diff --git "a/JPA-Demo/doc/SpringDataJPA345円255円246円344円271円240円350円256円260円345円275円225円(344円272円224円)--344円275円277円347円224円250円QueryDSL.md" "b/JPA-Demo/doc/SpringDataJPA345円255円246円344円271円240円350円256円260円345円275円225円(344円272円224円)--344円275円277円347円224円250円QueryDSL.md" new file mode 100644 index 0000000..c2e4300 --- /dev/null +++ "b/JPA-Demo/doc/SpringDataJPA345円255円246円344円271円240円350円256円260円345円275円225円(344円272円224円)--344円275円277円347円224円250円QueryDSL.md" @@ -0,0 +1,504 @@ +# SpringDataJPA学习记录(五)--使用QueryDSL + +--- +标签: QueryDSL SpringData JPA + +在上章节基础上增加了三个实体 +User: 用于演示单表查询,自连接查询 +Preson, IDCard: 用于演示一对一关系查询 +Order, OrderItem 用于演示多对多关系查询 + +User用户实体类 + +```` +/** + * User类 主要用于单表操作。 + */ +@Entity +@Table(name="t_user") +public class User implements Serializable{ + + private static final long serialVersionUID = 1L; + + @Id() + @GeneratedValue(strategy = GenerationType.AUTO) + private Integer id; + private String name; + private int age; + private String address; + //............省略getter,setter方法............ + /** + * attention: + * Details:方便查看测试结果 + * @author chhliu + */ + @Override + public String toString() { + return "User [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]"; + } + } +```` +IDCard实体类 +```` +/** + * 描述:身份ID + * @author chhliu + */ +@Entity +@Table(name="T_IDCARD") +public class IDCard { + @Id + @GeneratedValue + private Integer id; + private String idNo; + @OneToOne(cascade={CascadeType.MERGE, CascadeType.REMOVE, CascadeType.PERSIST}, fetch=FetchType.EAGER) + private Person person; + //---省略get set方法--- + @Override + public String toString() { + return "IDCard [id=" + id + ", idNo=" + idNo + ", person=" + person + "]"; + } +} +```` +Person个人实体类 +```` +/** + * 描述:个人表 + * 用于演示一对一关系查询 + * @author chhliu + */ +@Entity +@Table(name="T_PERSON") +public class Person { + @Id + @GeneratedValue + private Integer id; + private String name; + private String address; + + @OneToOne(mappedBy="person", cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}) + private IDCard idCard; + //---省略get set方法--- + @Override + public String toString() { + return "Person [id=" + id + ", name=" + name + ", address=" + address + ", idCard=" + idCard + "]"; + } +} +```` +Order订单表实体 + +```` +/** + * 描述:Order 订单实体类 + * 用于演示订单表与订单项表的多对多关系查询 + * @author chhliu + */ +@Entity +@Table(name="T_ORDER") +public class Order { + @Id + @GeneratedValue + @Column(name="ID") + private Integer id; + + @Column(length=20, name="ORDER_NAME") + private String orderName; + + @Column(name="COUNT") + private Integer count; + + @OneToMany(mappedBy = "order",cascade={CascadeType.PERSIST,CascadeType.REMOVE},fetch = FetchType.EAGER) + private List orderItems; + //---省略get set 方法--- + @Override + public String toString() { + return "Order{" + + "id=" + id + + ", orderName='" + orderName + '\'' + + ", count=" + count + + '}'; + } +} +```` +订单项实体 +```` +/** + * 描述:OrderItem 订单项实体类 + * @author chhliu + */ +@Entity +@Table(name="ORDER_ITEM") +public class OrderItem { + @Id + @GeneratedValue + @Column(name="ID", nullable=false) + private Integer id; + + @Column(name="ITEM_NAME", length=20) + private String itemName; + + @Column(name="PRICE") + private Integer price; + + @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE, CascadeType.MERGE}, fetch=FetchType.EAGER) + @JoinColumn(name = "ORDER_ID") + private Order order; + //---省略get set 方法--- + @Override + public String toString() { + return "OrderItem{" + + "id=" + id + + ", itemName='" + itemName + '\'' + + ", price=" + price + + ", orderId=" + order.getId() + + '}'; + } +} +```` +单表查询实现类 +```` + +/** + * @author 向亚林 + * 2018年3月5日 11:25 + */ +@Component +@Transactional +public class UserRepositoryImpl extends BaseRepository implements UserRepositoryCustom { + @Autowired + UserRepository userRepository; + /** + * 按用户名查询用户 + * 使用spring data QueryDSL实现 + * + * @param userName + * @return + */ + @Override + public User findUserByUserName(String userName) { + QUser qUser = QUser.user; + Predicate predicate = qUser.name.eq(userName); + return userRepository.findOne(predicate); + } + + /** + * 单条件查询用户 + * + * @param userName + * @return + */ + @Override + public User findOneByUserName(String userName) { + QUser qUser = QUser.user; + User user = queryFactory.selectFrom(qUser) + .where(qUser.name.eq(userName)) + .fetchOne(); + return user; + } + + /** + * 查询user表中的所有记录 + * + * @return + */ + @Override + public List findAll() { + System.out.println("重写findAll方法"); + QUser qUser = QUser.user; + return queryFactory.selectFrom(qUser).fetch(); + } + + /** + * 单表多条件查询 + * + * @param userName + * @param address + * @return + */ + @Override + public User findOneByUserNameAndAddress(String userName, String address) { + QUser qUser = QUser.user; + User user = queryFactory.select(qUser) + .from(qUser) + .where(qUser.name.eq(userName).and(qUser.address.eq(address))) + .fetchOne(); + return user; + } + + /** + * 使用join查询 + * @param user + * @return + */ + @Override + public List findUsersByJoin(QUser user) { + QUser qUser = QUser.user; + List users = queryFactory.selectFrom(qUser) + .innerJoin(qUser) + .on(qUser.id.intValue().eq(user.id.intValue())) + .fetch(); + return users; + } + + /** + * 将查询结果排序 + * + * @return + */ + @Override + public List findUsersByOrder() { + QUser qUser = QUser.user; + List users = queryFactory.selectFrom(qUser) + .orderBy(qUser.age.desc()) + .fetch(); + return users; + } + + /** + * Group By使用 + * + * @return + */ + @Override + public List findUserByGroup() { + QUser qUser = QUser.user; + return queryFactory.select(qUser.name) + .from(qUser) + .groupBy(qUser.name) + .fetch(); + } + + /** + * 删除用户 + * + * @param userName + * @return + */ + @Override + public long deleteUser(String userName) { + QUser qUser = QUser.user; + return queryFactory.delete(qUser).where(qUser.name.eq(userName)).execute(); + } + + /** + * 更新记录 + * + * @param user + * @param userName + * @return + */ + @Override + public long updateUser(User user, String userName) { + QUser qUser = QUser.user; + return queryFactory.update(qUser).where(qUser.name.eq(userName)) + .set(qUser.name,user.getName()) + .set(qUser.age,user.getAge()) + .set(qUser.address,user.getAddress()) + .execute(); + } + + /** + * 使用原生Query + * + * @param userName + * @return + */ + @Override + public User findOneUserByOriginalSql(String userName) { + QUser qUser = QUser.user; + Query query = queryFactory.selectFrom(qUser) + .where(qUser.name.eq(userName)).createQuery(); + User singleResult = (User) query.getSingleResult(); + return singleResult; + } + + /** + * 分页查询单表 + * + * @param offset + * @param pageSize + * @return + */ + @Override + public Page findAllByPage(int offset, int pageSize) { + Predicate predicate = QUser.user.age.lt(30); + Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "id")); + PageRequest pageRequest = new PageRequest(offset, pageSize, sort); + return userRepository.findAll(predicate, pageRequest); + } + + /** + * 自连接查询 + * 查询来自同一个地方,年龄>age的用户信息 + * + * @param age + * @return + */ + @Override + public List findUserByJoinUser(Integer age) { + BooleanExpression expression = QUser.user.age.intValue().gt(age); + return queryFactory.selectFrom(QUser.user) + .leftJoin(QUser.user) + .on((QUser.user.address).eq(QUser.user.address)) + .where(expression) + .fetch(); + } + +} +```` +一对一关系查询实现类 +```` + +/** + * @author 向亚林 + * 2018年3月5日 17:24 + */ +@Component +@Transactional +public class PersonAndIdCardRepositoryImpl extends BaseRepository implements PersonAndIdCardRepositoryCustom { + /** + * 多表动态查询 + * Person与IDCard是一对一的关系 + * + * @return + */ + @Override + public List findAllPersonAndIdCard() { + Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.id.intValue()); + return queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address) + .from(QIDCard.iDCard, QPerson.person) + .where(predicate) + .fetch(); + } + + /** + * 将查询结果以DTO的方式输出 + * + * @return + */ + @Override + public List findByDto() { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + JPAQuery jpaQuery = queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address) + .from(QIDCard.iDCard, QPerson.person) + .where(expression); + List tuples = jpaQuery.fetch(); + List personIdCardDtoList = new ArrayList(); + if (null != tuples && !tuples.isEmpty()) { + for (Tuple tuple : tuples) { + String idCard = tuple.get(QIDCard.iDCard.idNo); + String name = tuple.get(QPerson.person.name); + String address = tuple.get(QPerson.person.address); + PersonIdCardDto personIdCardDto = new PersonIdCardDto(idCard, name, address); + personIdCardDtoList.add(personIdCardDto); + } + } + return personIdCardDtoList; + } + + /** + * 多表动态查询,并分页 + * + * @param offset + * @param pageSize + * @return + */ + @Override + public QueryResults findByDtoAndPager(int offset, int pageSize) { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + return queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address) + .from(QIDCard.iDCard, QPerson.person) + .where(expression) + .offset(offset) + .limit(pageSize) + .fetchResults(); + } + + /** + * QueryDSL使用Bean进行投影查询 + * + * @return + */ + @Override + public List findByDtoUseBean() { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + List fetch = queryFactory.select(Projections.bean(PersonIdCardDto.class, QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address)) + .from(QIDCard.iDCard, QPerson.person) + .where(expression) + .fetch(); + return fetch; + } + + /** + * QueryDSL使用fields来代替setter + * + * @return + */ + @Override + public List findByDtoUseFields() { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + return queryFactory.select(Projections.fields(PersonIdCardDto.class, QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address)) + .from(QIDCard.iDCard, QPerson.person) + .where(expression) + .fetch(); + } + + /** + * QueryDSL使用构造方法,注意构造方法中属性的顺序必须和构造器中的顺序一致 + * + * @return + */ + @Override + public List findByDtoUseConstructor() { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + return queryFactory.select(Projections.constructor(PersonIdCardDto.class, QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address)) + .from(QIDCard.iDCard, QPerson.person) + .where(expression) + .fetch(); + } +} + +```` +多对多关系查询实现类 +```` + +/** + * @author 向亚林 + * 2018年3月6日 14:19 + */ +public class OrderAndOrderItemRepositoryImpl extends BaseRepository implements OrderAndOrderItemRepositoryCustom { + /** + * 一对多,条件查询 + * + * @param orderName + * @return + */ + @Override + public List findOrderAndOrderItemByOrderName(String orderName) { + BooleanExpression expression = QOrder.order.orderName.eq(orderName); + return queryFactory.select(QOrder.order, QOrderItem.orderItem) + .from(QOrder.order, QOrderItem.orderItem) + .where(QOrder.order.id.intValue().eq(QOrderItem.orderItem.order.id.intValue()), expression) + .fetch(); + } + + /** + * 多表连接查询 + * + * @param orderName + * @return + */ + @Override + public List findAllByOrderName(String orderName) { + BooleanExpression expression = QOrder.order.orderName.eq(orderName); + JPAQuery jpaQuery = queryFactory.select(QOrder.order, QOrderItem.orderItem) + .from(QOrder.order) + .leftJoin(QOrderItem.orderItem) + .on((QOrder.order.id.intValue()).eq(QOrderItem.orderItem.order.id.intValue())) + .where(expression); + return jpaQuery.fetch(); + + } +} + +```` \ No newline at end of file diff --git a/JPA-Demo/doc/sql.sql b/JPA-Demo/doc/sql.sql index 0a431b6..3c5ec95 100644 --- a/JPA-Demo/doc/sql.sql +++ b/JPA-Demo/doc/sql.sql @@ -54,6 +54,107 @@ insert into `t_hotel`(`id`,`name`,`address`,`city`) values (1,'ShangHai.HutaiLu UNLOCK TABLES; +-- ---------------------------- +-- Table structure for t_user +-- ---------------------------- +DROP TABLE IF EXISTS `t_user`; +CREATE TABLE `t_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `age` int(11) NOT NULL, + `address` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Records of t_user +-- ---------------------------- +INSERT INTO `t_user` VALUES ('1', 'zhangsan', '18', '1111'); +INSERT INTO `t_user` VALUES ('2', 'lisi', '20', '2222'); +INSERT INTO `t_user` VALUES ('3', 'wangwu', '19', '2222'); +INSERT INTO `t_user` VALUES ('4', 'bao1', '16', '1111'); +INSERT INTO `t_user` VALUES ('5', 'bao2', '19', '1111'); +INSERT INTO `t_user` VALUES ('7', 'bao4', '88', '1111'); + +-- ---------------------------- +-- Table structure for t_idcard +-- ---------------------------- +DROP TABLE IF EXISTS `t_idcard`; +CREATE TABLE `t_idcard` ( + `id` int(11) NOT NULL, + `idNo` varchar(255) DEFAULT NULL, + `person_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FKfl8133nq66cp2fjnc7u7vullo` (`person_id`), + CONSTRAINT `FKfl8133nq66cp2fjnc7u7vullo` FOREIGN KEY (`person_id`) REFERENCES `t_person` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Records of t_idcard +-- ---------------------------- +INSERT INTO `t_idcard` VALUES ('1', '111', '1'); +INSERT INTO `t_idcard` VALUES ('2', '222', '2'); +INSERT INTO `t_idcard` VALUES ('3', '333', '3'); + + +-- ---------------------------- +-- Table structure for t_person +-- ---------------------------- +DROP TABLE IF EXISTS `t_person`; +CREATE TABLE `t_person` ( + `id` int(11) NOT NULL, + `name` varchar(255) DEFAULT NULL, + `address` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Records of t_person +-- ---------------------------- +INSERT INTO `t_person` VALUES ('1', 'bao1', 'aaa'); +INSERT INTO `t_person` VALUES ('2', 'bao2', 'bbb'); +INSERT INTO `t_person` VALUES ('3', 'bao3', 'ccc'); + +-- ---------------------------- +-- Table structure for t_order +-- ---------------------------- +DROP TABLE IF EXISTS `t_order`; +CREATE TABLE `t_order` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `ORDER_NAME` varchar(20) DEFAULT NULL, + `COUNT` int(11) DEFAULT NULL, + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Records of t_order +-- ---------------------------- +INSERT INTO `t_order` VALUES ('1', 'CN111', '111'); +INSERT INTO `t_order` VALUES ('2', 'CN222', '222'); +INSERT INTO `t_order` VALUES ('3', 'CN333', '333'); + +-- ---------------------------- +-- Table structure for order_item +-- ---------------------------- +DROP TABLE IF EXISTS `order_item`; +CREATE TABLE `order_item` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `ITEM_NAME` varchar(20) DEFAULT NULL, + `PRICE` int(11) DEFAULT NULL, + `ORDER_ID` int(11) DEFAULT NULL, + PRIMARY KEY (`ID`), + KEY `FKtq1wmoawe8voyf02thxxcnwgo` (`ORDER_ID`), + CONSTRAINT `FKtq1wmoawe8voyf02thxxcnwgo` FOREIGN KEY (`ORDER_ID`) REFERENCES `t_order` (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Records of order_item +-- ---------------------------- +INSERT INTO `order_item` VALUES ('1', 'OI111', '111', '1'); +INSERT INTO `order_item` VALUES ('2', 'OI222', '222', '2'); +INSERT INTO `order_item` VALUES ('3', 'OI333', '333', '3'); +INSERT INTO `order_item` VALUES ('4', 'OI444', '444', '1'); + /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; diff --git a/JPA-Demo/src/main/java/cn/mrdear/entity/IDCard.java b/JPA-Demo/src/main/java/cn/mrdear/entity/IDCard.java new file mode 100644 index 0000000..3af809f --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/entity/IDCard.java @@ -0,0 +1,53 @@ +package cn.mrdear.entity; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * 描述:身份ID + * @author chhliu + */ +@Entity +@Table(name="T_IDCARD") +public class IDCard { + @Id + @GeneratedValue + private Integer id; + private String idNo; + @OneToOne(cascade={CascadeType.MERGE, CascadeType.REMOVE, CascadeType.PERSIST}, fetch=FetchType.EAGER) + private Person person; + + @Override + public String toString() { + return "IDCard [id=" + id + ", idNo=" + idNo + ", person=" + person + "]"; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getIdNo() { + return idNo; + } + + public void setIdNo(String idNo) { + this.idNo = idNo; + } + + public Person getPerson() { + return person; + } + + public void setPerson(Person person) { + this.person = person; + } +} \ No newline at end of file diff --git a/JPA-Demo/src/main/java/cn/mrdear/entity/Order.java b/JPA-Demo/src/main/java/cn/mrdear/entity/Order.java new file mode 100644 index 0000000..6f9ecc5 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/entity/Order.java @@ -0,0 +1,77 @@ +package cn.mrdear.entity; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * 描述:Order 订单实体类 + * 用于演示订单表与订单项表的多对多关系查询 + * @author chhliu + */ +@Entity +@Table(name="T_ORDER") +public class Order { + @Id + @GeneratedValue + @Column(name="ID") + private Integer id; + + @Column(length=20, name="ORDER_NAME") + private String orderName; + + @Column(name="COUNT") + private Integer count; + + @OneToMany(mappedBy = "order",cascade={CascadeType.PERSIST,CascadeType.REMOVE},fetch = FetchType.EAGER) + private List orderItems; + + @Override + public String toString() { + return "Order{" + + "id=" + id + + ", orderName='" + orderName + '\'' + + ", count=" + count + + '}'; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getOrderName() { + return orderName; + } + + public void setOrderName(String orderName) { + this.orderName = orderName; + } + + public Integer getCount() { + return count; + } + + public void setCount(Integer count) { + this.count = count; + } + + public List getOrderItems() { + return orderItems; + } + + public void setOrderItems(List orderItems) { + this.orderItems = orderItems; + } + +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/entity/OrderItem.java b/JPA-Demo/src/main/java/cn/mrdear/entity/OrderItem.java new file mode 100644 index 0000000..69fad47 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/entity/OrderItem.java @@ -0,0 +1,77 @@ +package cn.mrdear.entity; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * 描述:OrderItem 订单项实体类 + * @author chhliu + */ +@Entity +@Table(name="ORDER_ITEM") +public class OrderItem { + @Id + @GeneratedValue + @Column(name="ID", nullable=false) + private Integer id; + + @Column(name="ITEM_NAME", length=20) + private String itemName; + + @Column(name="PRICE") + private Integer price; + + @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE, CascadeType.MERGE}, fetch=FetchType.EAGER) + @JoinColumn(name = "ORDER_ID") + private Order order; + + @Override + public String toString() { + return "OrderItem{" + + "id=" + id + + ", itemName='" + itemName + '\'' + + ", price=" + price + + ", orderId=" + order.getId() + + '}'; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getItemName() { + return itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + public Integer getPrice() { + return price; + } + + public void setPrice(Integer price) { + this.price = price; + } + + public Order getOrder() { + return order; + } + + public void setOrder(Order order) { + this.order = order; + } + +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/entity/Person.java b/JPA-Demo/src/main/java/cn/mrdear/entity/Person.java new file mode 100644 index 0000000..a4eecc2 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/entity/Person.java @@ -0,0 +1,63 @@ +package cn.mrdear.entity; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * 描述:个人表 + * 用于演示一对一关系查询 + * @author chhliu + */ +@Entity +@Table(name="T_PERSON") +public class Person { + @Id + @GeneratedValue + private Integer id; + private String name; + private String address; + + @OneToOne(mappedBy="person", cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}) + private IDCard idCard; + + @Override + public String toString() { + return "Person [id=" + id + ", name=" + name + ", address=" + address + ", idCard=" + idCard + "]"; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public IDCard getIdCard() { + return idCard; + } + + public void setIdCard(IDCard idCard) { + this.idCard = idCard; + } +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/entity/TCity.java b/JPA-Demo/src/main/java/cn/mrdear/entity/TCity.java index b8d5a47..d6deae6 100644 --- a/JPA-Demo/src/main/java/cn/mrdear/entity/TCity.java +++ b/JPA-Demo/src/main/java/cn/mrdear/entity/TCity.java @@ -97,4 +97,15 @@ public int hashCode() { result = 31 * result + (map != null ? map.hashCode() : 0); return result; } + + @Override + public String toString() { + return "TCity{" + + "id=" + id + + ", name='" + name + '\'' + + ", state='" + state + '\'' + + ", country='" + country + '\'' + + ", map='" + map + '\'' + + '}'; + } } diff --git a/JPA-Demo/src/main/java/cn/mrdear/entity/THotel.java b/JPA-Demo/src/main/java/cn/mrdear/entity/THotel.java index 68f2d06..f32d9fc 100644 --- a/JPA-Demo/src/main/java/cn/mrdear/entity/THotel.java +++ b/JPA-Demo/src/main/java/cn/mrdear/entity/THotel.java @@ -83,4 +83,14 @@ public int hashCode() { result = 31 * result + (city != null ? city.hashCode() : 0); return result; } + + @Override + public String toString() { + return "THotel{" + + "id=" + id + + ", name='" + name + '\'' + + ", address='" + address + '\'' + + ", city=" + city + + '}'; + } } diff --git a/JPA-Demo/src/main/java/cn/mrdear/entity/User.java b/JPA-Demo/src/main/java/cn/mrdear/entity/User.java new file mode 100644 index 0000000..4ef1836 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/entity/User.java @@ -0,0 +1,78 @@ +package cn.mrdear.entity; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * User类 主要用于单表操作。 + */ +@Entity +@Table(name="t_user") +public class User implements Serializable{ + + private static final long serialVersionUID = 1L; + + @Id() + @GeneratedValue(strategy = GenerationType.AUTO) + private Integer id; + private String name; + private int age; + private String address; + + /** + * attention: + * Details:方便查看测试结果 + * @author chhliu + */ + @Override + public String toString() { + return "User [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]"; + } + + public User(String name, int age, String address) { + this.name = name; + this.age = age; + this.address = address; + } + + public User() { + + } + + public int getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/jpa/dto/PersonIdCardDto.java b/JPA-Demo/src/main/java/cn/mrdear/jpa/dto/PersonIdCardDto.java new file mode 100644 index 0000000..d88e071 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/jpa/dto/PersonIdCardDto.java @@ -0,0 +1,54 @@ +package cn.mrdear.jpa.dto; + +/** + * 查询结果DTO + * @author 向亚林 + * 2018年3月5日 17:15 + */ +public class PersonIdCardDto { + private String idNo; + private String name; + private String address; + + public PersonIdCardDto() { + } + + public PersonIdCardDto(String idNo, String name, String address) { + this.idNo = idNo; + this.name = name; + this.address = address; + } + + public String getIdNo() { + return idNo; + } + + public void setIdNo(String idNo) { + this.idNo = idNo; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + @Override + public String toString() { + return "PersonIdCardDto{" + + "idNo='" + idNo + '\'' + + ", name='" + name + '\'' + + ", address='" + address + '\'' + + '}'; + } +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/BaseRepository.java b/JPA-Demo/src/main/java/cn/mrdear/repository/BaseRepository.java index 7c12317..5e8f5cf 100644 --- a/JPA-Demo/src/main/java/cn/mrdear/repository/BaseRepository.java +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/BaseRepository.java @@ -1,7 +1,10 @@ package cn.mrdear.repository; +import com.querydsl.jpa.impl.JPAQueryFactory; import org.springframework.data.repository.NoRepositoryBean; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @@ -15,5 +18,17 @@ public class BaseRepository { @PersistenceContext(unitName = "TestJPA") protected EntityManager em; + protected JPAQueryFactory queryFactory; + + @PostConstruct + public void init(){ + System.out.println("\n init()方法调用"); + queryFactory = new JPAQueryFactory(em); + } + + @PreDestroy + public void destroy(){ + System.out.println("\n destroy()方法调用"); + } } diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/OrderAndOrderItemRepository.java b/JPA-Demo/src/main/java/cn/mrdear/repository/OrderAndOrderItemRepository.java new file mode 100644 index 0000000..618c78a --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/OrderAndOrderItemRepository.java @@ -0,0 +1,13 @@ +package cn.mrdear.repository; + +import cn.mrdear.entity.Order; +import cn.mrdear.repository.custom.OrderAndOrderItemRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QueryDslPredicateExecutor; + +/** + * @author 向亚林 + * 2018年3月6日 14:08 + */ +public interface OrderAndOrderItemRepository extends JpaRepository, QueryDslPredicateExecutor, OrderAndOrderItemRepositoryCustom { +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/PersonAndIdCardRepository.java b/JPA-Demo/src/main/java/cn/mrdear/repository/PersonAndIdCardRepository.java new file mode 100644 index 0000000..41a146a --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/PersonAndIdCardRepository.java @@ -0,0 +1,13 @@ +package cn.mrdear.repository; + +import cn.mrdear.entity.Person; +import cn.mrdear.repository.custom.PersonAndIdCardRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QueryDslPredicateExecutor; + +/** + * @author 向亚林 + * 2018年3月5日 16:52 + */ +public interface PersonAndIdCardRepository extends JpaRepository, QueryDslPredicateExecutor, PersonAndIdCardRepositoryCustom { +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/UserRepository.java b/JPA-Demo/src/main/java/cn/mrdear/repository/UserRepository.java new file mode 100644 index 0000000..d147c39 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/UserRepository.java @@ -0,0 +1,13 @@ +package cn.mrdear.repository; + +import cn.mrdear.entity.User; +import cn.mrdear.repository.custom.UserRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QueryDslPredicateExecutor; + +/** + * @author 向亚林 + * 2018年3月5日 11:14 + */ +public interface UserRepository extends JpaRepository, QueryDslPredicateExecutor, UserRepositoryCustom { +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/custom/OrderAndOrderItemRepositoryCustom.java b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/OrderAndOrderItemRepositoryCustom.java new file mode 100644 index 0000000..c941dbb --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/OrderAndOrderItemRepositoryCustom.java @@ -0,0 +1,25 @@ +package cn.mrdear.repository.custom; + +import com.querydsl.core.Tuple; + +import java.util.List; + +/** + * @author 向亚林 + * 2018年3月6日 14:09 + */ +public interface OrderAndOrderItemRepositoryCustom { + /** + * 一对多,条件查询 + * @return + */ + List findOrderAndOrderItemByOrderName(String orderName); + + /** + * 多表连接查询 + * @param orderName + * @return + */ + List findAllByOrderName(String orderName); + +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/custom/OrderAndOrderItemRepositoryImpl.java b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/OrderAndOrderItemRepositoryImpl.java new file mode 100644 index 0000000..28fbac9 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/OrderAndOrderItemRepositoryImpl.java @@ -0,0 +1,49 @@ +package cn.mrdear.repository.custom; + +import cn.mrdear.entity.QOrder; +import cn.mrdear.entity.QOrderItem; +import cn.mrdear.repository.BaseRepository; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQuery; + +import java.util.List; + +/** + * @author 向亚林 + * 2018年3月6日 14:19 + */ +public class OrderAndOrderItemRepositoryImpl extends BaseRepository implements OrderAndOrderItemRepositoryCustom { + /** + * 一对多,条件查询 + * + * @param orderName + * @return + */ + @Override + public List findOrderAndOrderItemByOrderName(String orderName) { + BooleanExpression expression = QOrder.order.orderName.eq(orderName); + return queryFactory.select(QOrder.order, QOrderItem.orderItem) + .from(QOrder.order, QOrderItem.orderItem) + .where(QOrder.order.id.intValue().eq(QOrderItem.orderItem.order.id.intValue()), expression) + .fetch(); + } + + /** + * 多表连接查询 + * + * @param orderName + * @return + */ + @Override + public List findAllByOrderName(String orderName) { + BooleanExpression expression = QOrder.order.orderName.eq(orderName); + JPAQuery jpaQuery = queryFactory.select(QOrder.order, QOrderItem.orderItem) + .from(QOrder.order) + .leftJoin(QOrderItem.orderItem) + .on((QOrder.order.id.intValue()).eq(QOrderItem.orderItem.order.id.intValue())) + .where(expression); + return jpaQuery.fetch(); + + } +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/custom/PersonAndIdCardRepositoryCustom.java b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/PersonAndIdCardRepositoryCustom.java new file mode 100644 index 0000000..56ac974 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/PersonAndIdCardRepositoryCustom.java @@ -0,0 +1,51 @@ +package cn.mrdear.repository.custom; + +import cn.mrdear.jpa.dto.PersonIdCardDto; +import com.querydsl.core.QueryResults; +import com.querydsl.core.Tuple; + +import java.util.List; + +/** + * @author 向亚林 + * 2018年3月5日 16:53 + */ +public interface PersonAndIdCardRepositoryCustom { + /** + * 多表动态查询 + * @return + */ + List findAllPersonAndIdCard(); + + /** + * 将查询结果以DTO的方式输出 + * @return + */ + List findByDto(); + + /** + * 多表动态查询,并分页 + * @param offset + * @param pageSize + * @return + */ + QueryResults findByDtoAndPager(final int offset, final int pageSize); + + /** + * QueryDSL使用Bean进行投影查询 + * @return + */ + List findByDtoUseBean(); + + /** + * QueryDSL使用fields来代替setter + * @return + */ + List findByDtoUseFields(); + + /** + * QueryDSL使用构造方法,注意构造方法中属性的顺序必须和构造器中的顺序一致 + * @return + */ + List findByDtoUseConstructor(); +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/custom/PersonAndIdCardRepositoryImpl.java b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/PersonAndIdCardRepositoryImpl.java new file mode 100644 index 0000000..ccf17a0 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/PersonAndIdCardRepositoryImpl.java @@ -0,0 +1,127 @@ +package cn.mrdear.repository.custom; + +import cn.mrdear.entity.IDCard; +import cn.mrdear.entity.QIDCard; +import cn.mrdear.entity.QPerson; +import cn.mrdear.jpa.dto.PersonIdCardDto; +import cn.mrdear.repository.BaseRepository; +import com.querydsl.core.QueryResults; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQuery; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author 向亚林 + * 2018年3月5日 17:24 + */ +@Component +@Transactional +public class PersonAndIdCardRepositoryImpl extends BaseRepository implements PersonAndIdCardRepositoryCustom { + /** + * 多表动态查询 + * Person与IDCard是一对一的关系 + * + * @return + */ + @Override + public List findAllPersonAndIdCard() { + Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.id.intValue()); + return queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address) + .from(QIDCard.iDCard, QPerson.person) + .where(predicate) + .fetch(); + } + + /** + * 将查询结果以DTO的方式输出 + * + * @return + */ + @Override + public List findByDto() { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + JPAQuery jpaQuery = queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address) + .from(QIDCard.iDCard, QPerson.person) + .where(expression); + List tuples = jpaQuery.fetch(); + List personIdCardDtoList = new ArrayList(); + if (null != tuples && !tuples.isEmpty()) { + for (Tuple tuple : tuples) { + String idCard = tuple.get(QIDCard.iDCard.idNo); + String name = tuple.get(QPerson.person.name); + String address = tuple.get(QPerson.person.address); + PersonIdCardDto personIdCardDto = new PersonIdCardDto(idCard, name, address); + personIdCardDtoList.add(personIdCardDto); + } + } + return personIdCardDtoList; + } + + /** + * 多表动态查询,并分页 + * + * @param offset + * @param pageSize + * @return + */ + @Override + public QueryResults findByDtoAndPager(int offset, int pageSize) { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + return queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address) + .from(QIDCard.iDCard, QPerson.person) + .where(expression) + .offset(offset) + .limit(pageSize) + .fetchResults(); + } + + /** + * QueryDSL使用Bean进行投影查询 + * + * @return + */ + @Override + public List findByDtoUseBean() { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + List fetch = queryFactory.select(Projections.bean(PersonIdCardDto.class, QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address)) + .from(QIDCard.iDCard, QPerson.person) + .where(expression) + .fetch(); + return fetch; + } + + /** + * QueryDSL使用fields来代替setter + * + * @return + */ + @Override + public List findByDtoUseFields() { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + return queryFactory.select(Projections.fields(PersonIdCardDto.class, QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address)) + .from(QIDCard.iDCard, QPerson.person) + .where(expression) + .fetch(); + } + + /** + * QueryDSL使用构造方法,注意构造方法中属性的顺序必须和构造器中的顺序一致 + * + * @return + */ + @Override + public List findByDtoUseConstructor() { + BooleanExpression expression = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); + return queryFactory.select(Projections.constructor(PersonIdCardDto.class, QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address)) + .from(QIDCard.iDCard, QPerson.person) + .where(expression) + .fetch(); + } +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/custom/TCityRepositoryImpl.java b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/TCityRepositoryImpl.java index 4ddde14..6a5319a 100644 --- a/JPA-Demo/src/main/java/cn/mrdear/repository/custom/TCityRepositoryImpl.java +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/TCityRepositoryImpl.java @@ -34,7 +34,7 @@ public List findCityAndHotel(Predicate predicate) { @Override public QueryResults findCityAndHotelPage(Predicate predicate,Pageable pageable) { JPAQueryFactory queryFactory = new JPAQueryFactory(em); - JPAQuery jpaQuery = queryFactory.select(QTCity.tCity.id,QTHotel.tHotel) + JPAQuery jpaQuery = queryFactory.select(QTCity.tCity.id,QTCity.tCity.name,QTHotel.tHotel) .from(QTCity.tCity) .leftJoin(QTHotel.tHotel) .on(QTHotel.tHotel.city.longValue().eq(QTCity.tCity.id.longValue())) diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/custom/UserRepositoryCustom.java b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/UserRepositoryCustom.java new file mode 100644 index 0000000..581b70d --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/UserRepositoryCustom.java @@ -0,0 +1,98 @@ +package cn.mrdear.repository.custom; + +import cn.mrdear.entity.QUser; +import cn.mrdear.entity.User; +import org.springframework.data.domain.Page; + +import java.util.List; + +/** + * @author 向亚林 + * 2018年3月5日 11:17 + */ +public interface UserRepositoryCustom { + /** + * 按用户名查询用户 + * 使用spring data QueryDSL实现 + * @param userName + * @return + */ + User findUserByUserName(final String userName); + + /** + * 单条件查询用户 + * @param userName + * @return + */ + User findOneByUserName(final String userName); + /** + * 查询user表中的所有记录 + * @return + */ + List findAll(); + + /** + * 单表多条件查询 + * @param userName + * @param address + * @return + */ + User findOneByUserNameAndAddress(final String userName, final String address); + + /** + * 使用join查询 + * @param user + * @return + */ + List findUsersByJoin(final QUser user); + + /** + * 将查询结果排序 + * @return + */ + List findUsersByOrder(); + + /** + * Group By使用 + * @return + */ + List findUserByGroup(); + + /** + * 删除用户 + * @param userName + * @return + */ + long deleteUser(String userName); + + /** + * 更新记录 + * @param user + * @param userName + * @return + */ + long updateUser(final User user, final String userName); + + /** + * 使用原生Query + * @param userName + * @return + */ + User findOneUserByOriginalSql(final String userName); + + /** + * 分页查询单表 + * @param offset + * @param pageSize + * @return + */ + Page findAllByPage(final int offset, final int pageSize); + + /** + * 自连接查询 + * 查询来自同一个地方,年龄>age的用户信息 + * @param age + * @return + */ + List findUserByJoinUser(final Integer age); +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/repository/custom/UserRepositoryImpl.java b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/UserRepositoryImpl.java new file mode 100644 index 0000000..257807b --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/repository/custom/UserRepositoryImpl.java @@ -0,0 +1,205 @@ +package cn.mrdear.repository.custom; + +import cn.mrdear.entity.QUser; +import cn.mrdear.entity.User; +import cn.mrdear.repository.BaseRepository; +import cn.mrdear.repository.UserRepository; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.BooleanExpression; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.Query; +import java.util.List; + +/** + * @author 向亚林 + * 2018年3月5日 11:25 + */ +@Component +@Transactional +public class UserRepositoryImpl extends BaseRepository implements UserRepositoryCustom { + @Autowired + UserRepository userRepository; + /** + * 按用户名查询用户 + * 使用spring data QueryDSL实现 + * + * @param userName + * @return + */ + @Override + public User findUserByUserName(String userName) { + QUser qUser = QUser.user; + Predicate predicate = qUser.name.eq(userName); + return userRepository.findOne(predicate); + } + + /** + * 单条件查询用户 + * + * @param userName + * @return + */ + @Override + public User findOneByUserName(String userName) { + QUser qUser = QUser.user; + User user = queryFactory.selectFrom(qUser) + .where(qUser.name.eq(userName)) + .fetchOne(); + return user; + } + + /** + * 查询user表中的所有记录 + * + * @return + */ + @Override + public List findAll() { + System.out.println("重写findAll方法"); + QUser qUser = QUser.user; + return queryFactory.selectFrom(qUser).fetch(); + } + + /** + * 单表多条件查询 + * + * @param userName + * @param address + * @return + */ + @Override + public User findOneByUserNameAndAddress(String userName, String address) { + QUser qUser = QUser.user; + User user = queryFactory.select(qUser) + .from(qUser) + .where(qUser.name.eq(userName).and(qUser.address.eq(address))) + .fetchOne(); + return user; + } + + /** + * 使用join查询 + * @param user + * @return + */ + @Override + public List findUsersByJoin(QUser user) { + QUser qUser = QUser.user; + List users = queryFactory.selectFrom(qUser) + .innerJoin(qUser) + .on(qUser.id.intValue().eq(user.id.intValue())) + .fetch(); + return users; + } + + /** + * 将查询结果排序 + * + * @return + */ + @Override + public List findUsersByOrder() { + QUser qUser = QUser.user; + List users = queryFactory.selectFrom(qUser) + .orderBy(qUser.age.desc()) + .fetch(); + return users; + } + + /** + * Group By使用 + * + * @return + */ + @Override + public List findUserByGroup() { + QUser qUser = QUser.user; + return queryFactory.select(qUser.name) + .from(qUser) + .groupBy(qUser.name) + .fetch(); + } + + /** + * 删除用户 + * + * @param userName + * @return + */ + @Override + public long deleteUser(String userName) { + QUser qUser = QUser.user; + return queryFactory.delete(qUser).where(qUser.name.eq(userName)).execute(); + } + + /** + * 更新记录 + * + * @param user + * @param userName + * @return + */ + @Override + public long updateUser(User user, String userName) { + QUser qUser = QUser.user; + return queryFactory.update(qUser).where(qUser.name.eq(userName)) + .set(qUser.name,user.getName()) + .set(qUser.age,user.getAge()) + .set(qUser.address,user.getAddress()) + .execute(); + } + + /** + * 使用原生Query + * + * @param userName + * @return + */ + @Override + public User findOneUserByOriginalSql(String userName) { + QUser qUser = QUser.user; + Query query = queryFactory.selectFrom(qUser) + .where(qUser.name.eq(userName)).createQuery(); + User singleResult = (User) query.getSingleResult(); + return singleResult; + } + + /** + * 分页查询单表 + * + * @param offset + * @param pageSize + * @return + */ + @Override + public Page findAllByPage(int offset, int pageSize) { + Predicate predicate = QUser.user.age.lt(30); + Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "id")); + PageRequest pageRequest = new PageRequest(offset, pageSize, sort); + return userRepository.findAll(predicate, pageRequest); + } + + /** + * 自连接查询 + * 查询来自同一个地方,年龄>age的用户信息 + * + * @param age + * @return + */ + @Override + public List findUserByJoinUser(Integer age) { + BooleanExpression expression = QUser.user.age.intValue().gt(age); + return queryFactory.selectFrom(QUser.user) + .leftJoin(QUser.user) + .on((QUser.user.address).eq(QUser.user.address)) + .where(expression) + .fetch(); + } + +} diff --git a/JPA-Demo/src/main/java/cn/mrdear/service/UserService.java b/JPA-Demo/src/main/java/cn/mrdear/service/UserService.java new file mode 100644 index 0000000..8d803a2 --- /dev/null +++ b/JPA-Demo/src/main/java/cn/mrdear/service/UserService.java @@ -0,0 +1,15 @@ +package cn.mrdear.service; + +import cn.mrdear.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * @author 向亚林 + * 2018年3月5日 13:41 + */ +@Service +@Transactional +public class UserService { +} diff --git a/JPA-Demo/src/main/resources/config.properties b/JPA-Demo/src/main/resources/config.properties index 9e6ae62..ed05a0d 100644 --- a/JPA-Demo/src/main/resources/config.properties +++ b/JPA-Demo/src/main/resources/config.properties @@ -2,7 +2,7 @@ jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8 jdbc.username=root -jdbc.password=7946521 +jdbc.password=root #druid start filters=stat diff --git a/JPA-Demo/src/main/resources/spring/applicationContext.xml b/JPA-Demo/src/main/resources/spring/applicationContext.xml index 97cf7c7..41620fa 100644 --- a/JPA-Demo/src/main/resources/spring/applicationContext.xml +++ b/JPA-Demo/src/main/resources/spring/applicationContext.xml @@ -74,7 +74,7 @@ false - none + update diff --git a/JPA-Demo/src/test/java/OrderAndOrderItemRepositoryTest.java b/JPA-Demo/src/test/java/OrderAndOrderItemRepositoryTest.java new file mode 100644 index 0000000..8523a6e --- /dev/null +++ b/JPA-Demo/src/test/java/OrderAndOrderItemRepositoryTest.java @@ -0,0 +1,60 @@ +import cn.mrdear.entity.QOrder; +import cn.mrdear.entity.QOrderItem; +import cn.mrdear.repository.OrderAndOrderItemRepository; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +/** + * @author 向亚林 + * 2018年3月6日 14:26 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:spring/applicationContext.xml") +public class OrderAndOrderItemRepositoryTest { + @Autowired + OrderAndOrderItemRepository orderAndOrderItemRepository; + + @Test + public void queryTest1(){ + List cn111 = orderAndOrderItemRepository.findOrderAndOrderItemByOrderName("CN111"); + printInfo(cn111, QOrder.order, QOrderItem.orderItem); + } + @Test + public void queryTest2(){ + List cn111 = orderAndOrderItemRepository.findAllByOrderName("CN222"); + printInfo(cn111,QOrder.order, QOrderItem.orderItem); + } + + /** + * 打印查询结果 + * @param results + * @param + */ + public void printInfo(List results) { + System.out.println("\n\n\n 打印查询结果: "); + if (null == results ) return; + for (T result : results) { + System.out.print(result); + } + System.out.println(); + } + + public void printInfo(List results, Expression... infos) { + System.out.println("\n\n\n 打印查询结果: "); + if (null == results) return; + for (Tuple result : results) { + for (Expression info : infos) { + System.out.print(" "+info.toString()+" "+result.get(info).toString()); + } + System.out.println(); + } + System.out.println(); + } +} diff --git a/JPA-Demo/src/test/java/PersonAndIdCardRepositoryTest.java b/JPA-Demo/src/test/java/PersonAndIdCardRepositoryTest.java new file mode 100644 index 0000000..5f740b4 --- /dev/null +++ b/JPA-Demo/src/test/java/PersonAndIdCardRepositoryTest.java @@ -0,0 +1,93 @@ +import cn.mrdear.entity.QIDCard; +import cn.mrdear.entity.QPerson; +import cn.mrdear.jpa.dto.PersonIdCardDto; +import cn.mrdear.repository.PersonAndIdCardRepository; +import com.querydsl.core.QueryResults; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.StringPath; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.lang.reflect.Field; +import java.lang.reflect.TypeVariable; +import java.util.List; + +/** + * @author 向亚林 + * 2018年3月5日 17:38 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:spring/applicationContext.xml") +public class PersonAndIdCardRepositoryTest { + @Autowired + private PersonAndIdCardRepository personAndIdCardRepository; + + @Test + public void queryTest1() { + List allPersonAndIdCard = personAndIdCardRepository.findAllPersonAndIdCard(); +// for (Tuple info : allPersonAndIdCard) { +// System.out.println(info.get(QIDCard.iDCard.idNo)+" "+info.get(QPerson.person.name)+" "+info.get(QPerson.person.address)); +// } + printInfo(allPersonAndIdCard, QIDCard.iDCard.idNo, QPerson.person.name, QPerson.person.address); + } + + @Test + public void queryTest2() { + List byDto = personAndIdCardRepository.findByDto(); + printInfo(byDto); + } + @Test + public void queryTest3(){ + QueryResults byDtoAndPager = personAndIdCardRepository.findByDtoAndPager(2, 2); + System.out.println("记录数: "+byDtoAndPager.getTotal()); + printInfo(byDtoAndPager.getResults()); + } + @Test + public void queryTest4() { + printInfo(personAndIdCardRepository.findByDtoUseBean()); + } + @Test + public void queryTest5(){ + printInfo(personAndIdCardRepository.findByDtoUseFields()); + } + @Test + public void queryTest6() { + printInfo(personAndIdCardRepository.findByDtoUseConstructor()); + } + + /** + * 打印查询结果 + * @param info + * @param + */ + public void printInfo(List info) { + System.out.println("\n\n\n 打印查询查询: "); + for (T t : info) { + System.out.println(t); + } + System.out.println(); + } + + /** + * 打印查询结果 + * @param results + * @param infos com.querydsl.core.types.Expression 数组 + */ + public void printInfo(List results, Expression ... infos) { + System.out.println("\n\n\n 打印查询结果: "); + for (Tuple result : results) { + for (Expression info : infos) { + //info.toString() 为属性名,result.get(info).toString() 为获取属性的值 + System.out.print(" "+info.toString()+" "+result.get(info).toString()); + } + System.out.println(); + } + System.out.println(); + } +} diff --git a/JPA-Demo/src/test/java/TCityTest.java b/JPA-Demo/src/test/java/TCityTest.java index 4b0af31..b4e8513 100644 --- a/JPA-Demo/src/test/java/TCityTest.java +++ b/JPA-Demo/src/test/java/TCityTest.java @@ -57,8 +57,10 @@ public void findByLeftJoin(){ Predicate predicate = qtCity.name.like("shanghai"); List result = tCityRepository.findCityAndHotel(predicate); for (Tuple row : result) { - System.out.println("qtCity:"+row.get(qtCity)); - System.out.println("qtHotel:"+row.get(qtHotel)); + System.out.println("qtCity: "+qtCity.name.getMetadata().getName() +" "+row.get(qtCity).getId()+" "+row.get(qtCity).getName()+" "+row.get(qtCity).getCountry()); + System.out.println("qtCity:"+row.get(qtCity).toString()); + System.out.println("qtHotel:"+row.get(qtHotel).getId()+" "+row.get(qtHotel).getName()+" "+row.get(qtHotel).getCity()); + System.out.println("qtHotel:"+row.get(qtHotel).toString()); System.out.println("--------------------"); } System.out.println(result); @@ -71,8 +73,8 @@ public void findByLeftJoinPage(){ PageRequest pageRequest = new PageRequest(0,10); QueryResults result = tCityRepository.findCityAndHotelPage(predicate,pageRequest); for (Tuple row : result.getResults()) { - System.out.println("qtCity:"+row.get(qtCity)); - System.out.println("qtHotel:"+row.get(qtHotel)); + System.out.println("qtCity:"+row.get(qtCity.id)+" \t"+row.get(qtCity.name)); + System.out.println("qtHotel:"+row.get(qtHotel)+" \t"+row.get(qtHotel).getId()+" \t"+row.get(qtHotel).getName()+" \t"+row.get(qtHotel).getCity()); System.out.println("--------------------"); } System.out.println(result.getTotal()); diff --git a/JPA-Demo/src/test/java/UserRepositoryTest.java b/JPA-Demo/src/test/java/UserRepositoryTest.java new file mode 100644 index 0000000..97e8f44 --- /dev/null +++ b/JPA-Demo/src/test/java/UserRepositoryTest.java @@ -0,0 +1,95 @@ +import cn.mrdear.entity.QUser; +import cn.mrdear.entity.User; +import cn.mrdear.repository.UserRepository; +import com.querydsl.core.types.dsl.BooleanExpression; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +/** + * @author 向亚林 + * 2018年3月5日 11:26 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:spring/applicationContext.xml") +public class UserRepositoryTest { + @Autowired + private UserRepository userRepository; + //动态条件 + QUser qUser = QUser.user; + + @Test + public void queryTest1(){ + BooleanExpression zhangsan = qUser.name.eq("zhangsan"); + User user = userRepository.findOne(zhangsan); + System.out.println("\n\n\n user: "+user); + } + @Test + public void queryTest2(){ + User user = userRepository.findOneByUserName("zhangsan"); + System.out.println("\n\n\n user: "+user); + } + @Test + public void queryTest3(){ + List all = userRepository.findAll(); + pringInfo(all); + } + @Test + public void queryTest4(){ + User wangwu = userRepository.findOneByUserNameAndAddress("wangwu", "3333"); + System.out.println("wangwu: "+wangwu); + } + @Test + public void queryTest5(){ + QUser user = new QUser("name"); + List usersByJoin = userRepository.findUsersByJoin(user); + pringInfo(usersByJoin); + } + @Test + public void queryTest6(){ + pringInfo(userRepository.findUsersByOrder()); + } + @Test + public void queryTest7() { + pringInfo(userRepository.findUserByGroup()); + } + @Test + public void queryTest8() { + long bao3 = userRepository.deleteUser("bao3"); + System.out.println("删除影响行数: "+bao3); + } + @Test + public void queryTest9() { + User user = new User("bao4", 88, "8888"); + long bao3 = userRepository.updateUser(user, "bao3"); + System.out.println("修改影响行数: "+bao3); + } + @Test + public void queryTest10() { + User bao4 = userRepository.findOneUserByOriginalSql("bao4"); + System.out.println("bao4: "+bao4); + } + @Test + public void queryTest11() { + Page allByPage = userRepository.findAllByPage(0, 3); + pringInfo(allByPage.getContent()); + } + @Test + public void queryTest12() { + List userByJoinUser = userRepository.findUserByJoinUser(18); + pringInfo(userByJoinUser); + } + + public void pringInfo(List info) { + System.out.println("\n\n\n 显示查询结果:"); + for (T t : info) { + System.out.println(t); + } + System.out.println(); + } +} AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル