1 /* 2 * Entity - Entity is an object-relational mapping tool for the D programming language. Referring to the design idea of JPA. 3 * 4 * Copyright (C) 2015-2018 Shanghai Putao Technology Co., Ltd 5 * 6 * Developer: HuntLabs.cn 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.entity.repository.EntityRepository; 13 14 import hunt.entity.criteria; 15 import hunt.entity.EntityManager; 16 import hunt.entity.TypedQuery; 17 import hunt.entity.Model; 18 import hunt.entity.repository.CrudRepository; 19 import hunt.entity.DefaultEntityManagerFactory; 20 import hunt.Long; 21 22 import hunt.database.query; 23 24 public import hunt.entity.domain; 25 26 class EntityRepository(T, ID) : CrudRepository!(T, ID) if (is(T : Model)) { 27 this(EntityManager manager = null) { 28 super(manager); 29 _member = new Member!T(entityManager.getPrefix()); 30 } 31 32 static string initObjects() { 33 // dfmt off 34 return ` 35 auto em = _manager ? _manager : createEntityManager(); 36 scope(exit) {if (!_manager) em.close();} 37 CriteriaBuilder builder = em.getCriteriaBuilder(); 38 auto criteriaQuery = builder.createQuery!T; 39 Root!T root = criteriaQuery.from();`; 40 41 // dfmt on 42 } 43 44 alias count = CrudRepository!(T, ID).count; 45 alias findAll = CrudRepository!(T, ID).findAll; 46 47 long count(Condition condition) { 48 mixin(initObjects); 49 50 criteriaQuery.select(builder.count(root)).where(condition.toPredicate()); 51 52 Long result = cast(Long)(em.createQuery(criteriaQuery).getSingleResult()); 53 return result.longValue(); 54 } 55 56 long count(Specification specification) { 57 mixin(initObjects); 58 59 criteriaQuery.select(builder.count(root)) 60 .where(specification.toPredicate(root, criteriaQuery, builder)); 61 62 Long result = cast(Long)(em.createQuery(criteriaQuery).getSingleResult()); 63 return result.longValue(); 64 // return 0; 65 } 66 67 T find(Condition condition) { 68 // auto list = findAll(condition); 69 // if(list.length > 0) 70 // return list[0]; 71 // return null; 72 mixin(initObjects); 73 74 //condition 75 criteriaQuery.select(root).where(condition.toPredicate()); 76 77 // page 78 TypedQuery!T typedQuery = em.createQuery(criteriaQuery).setFirstResult(0).setMaxResults(1); 79 80 // result 81 auto res = typedQuery.getResultList(); 82 if (res.length > 0) { 83 return res[0]; 84 } 85 return null; 86 } 87 88 T find(ID id) { 89 return this.findById(id); 90 } 91 92 T[] findAll(Sort sort) { 93 mixin(initObjects); 94 95 //sort 96 foreach (o; sort.list) { 97 criteriaQuery.getQueryBuilder().orderBy(o.getColumn() ~ " " ~ o.getOrderType()); 98 } 99 100 //all 101 criteriaQuery.select(root); 102 103 TypedQuery!T typedQuery = em.createQuery(criteriaQuery); 104 auto res = typedQuery.getResultList(); 105 106 return res; 107 } 108 109 T[] findAll(Condition condition) { 110 mixin(initObjects); 111 112 //specification 113 criteriaQuery.select(root).where(condition.toPredicate()); 114 115 TypedQuery!T typedQuery = em.createQuery(criteriaQuery); 116 auto res = typedQuery.getResultList(); 117 118 return res; 119 } 120 121 T[] findAll(R)(Comparison!R condition) { 122 mixin(initObjects); 123 124 //specification 125 criteriaQuery.select(root).where(condition); 126 127 TypedQuery!T typedQuery = em.createQuery(criteriaQuery); 128 auto res = typedQuery.getResultList(); 129 130 return res; 131 } 132 133 T[] findAll(Specification specification) { 134 mixin(initObjects); 135 136 //specification 137 criteriaQuery.select(root).where(specification.toPredicate(root, criteriaQuery, builder)); 138 139 TypedQuery!T typedQuery = em.createQuery(criteriaQuery); 140 auto res = typedQuery.getResultList(); 141 142 return res; 143 } 144 145 T[] findAll(Condition condition, Sort sort) { 146 mixin(initObjects); 147 148 //sort 149 foreach (o; sort.list) 150 criteriaQuery.getQueryBuilder().orderBy(o.getColumn() ~ " " ~ o.getOrderType()); 151 152 //specification 153 criteriaQuery.select(root).where(condition.toPredicate()); 154 155 TypedQuery!T typedQuery = em.createQuery(criteriaQuery); 156 auto res = typedQuery.getResultList(); 157 158 return res; 159 } 160 161 T[] findAll(Specification specification, Sort sort) { 162 mixin(initObjects); 163 164 //sort 165 foreach (o; sort.list) 166 criteriaQuery.getQueryBuilder().orderBy(o.getColumn() ~ " " ~ o.getOrderType()); 167 168 //specification 169 criteriaQuery.select(root).where(specification.toPredicate(root, criteriaQuery, builder)); 170 171 TypedQuery!T typedQuery = em.createQuery(criteriaQuery); 172 auto res = typedQuery.getResultList(); 173 174 return res; 175 } 176 177 Page!T findAll(Pageable pageable) { 178 mixin(initObjects); 179 180 //sort 181 foreach (o; pageable.getSort.list) 182 criteriaQuery.getQueryBuilder().orderBy(o.getColumn() ~ " " ~ o.getOrderType()); 183 184 //all 185 criteriaQuery.select(root); 186 187 //page 188 TypedQuery!T typedQuery = em.createQuery(criteriaQuery) 189 .setFirstResult(pageable.getOffset()).setMaxResults(pageable.getPageSize()); 190 191 auto res = typedQuery.getResultList(); 192 auto page = new Page!T(res, pageable, super.count()); 193 194 return page; 195 } 196 197 /// 198 Page!T findAll(Condition condition, Pageable pageable) { 199 mixin(initObjects); 200 201 //sort 202 foreach (o; pageable.getSort.list) 203 criteriaQuery.getQueryBuilder().orderBy(o.getColumn() ~ " " ~ o.getOrderType()); 204 205 //condition 206 criteriaQuery.select(root).where(condition.toPredicate()); 207 208 //page 209 TypedQuery!T typedQuery = em.createQuery(criteriaQuery) 210 .setFirstResult(pageable.getOffset()).setMaxResults(pageable.getPageSize()); 211 auto res = typedQuery.getResultList(); 212 auto page = new Page!T(res, pageable, count(condition)); 213 214 return page; 215 } 216 217 Page!T findAll(Specification specification, Pageable pageable) { 218 mixin(initObjects); 219 220 //sort 221 foreach (o; pageable.getSort.list) 222 criteriaQuery.getQueryBuilder().orderBy(o.getColumn() ~ " " ~ o.getOrderType()); 223 224 //specification 225 criteriaQuery.select(root).where(specification.toPredicate(root, criteriaQuery, builder)); 226 227 //page 228 TypedQuery!T typedQuery = em.createQuery(criteriaQuery) 229 .setFirstResult(pageable.getOffset()).setMaxResults(pageable.getPageSize()); 230 auto res = typedQuery.getResultList(); 231 auto page = new Page!T(res, pageable, count(specification)); 232 233 return page; 234 } 235 236 @property Member!T field() { 237 return _member; 238 } 239 240 deprecated("Using field instead.") 241 @property Member!T Field() { 242 return _member; 243 } 244 245 private: 246 247 Member!T _member; 248 } 249 250 /* 251 version(unittest) 252 { 253 @Table("p_menu") 254 class Menu 255 { 256 mixin MakeModel; 257 258 @PrimaryKey 259 @AutoIncrement 260 int ID; 261 262 @Column("name") 263 string name; 264 @JoinColumn("up_menu_id") 265 int up_menu_id; 266 string perident; 267 int index; 268 string icon; 269 bool status; 270 } 271 } 272 273 unittest{ 274 275 void test_entity_repository() 276 { 277 278 //data 279 280 // (1, 'User', 0, 'user.edit', 0, 'fe-box', 0), 281 // (2, 'Role', 0, 'role.edit', 0, 'fe-box', 0), 282 // (3, 'Module', 0, 'module.edit', 0, 'fe-box', 0), 283 // (4, 'Permission', 0, 'permission.edit', 0, 'fe-box', 0), 284 // (5, 'Menu', 0, 'menu.edit', 0, 'fe-box', 0), 285 // (6, 'Manage User', 1, 'user.edit', 0, '0', 0), 286 // (7, 'Add User', 1, 'user.add', 0, '0', 0), 287 // (8, 'Manage Role', 2, 'role.edit', 0, '0', 0), 288 // (9, 'Add Role', 2, 'role.add', 0, '0', 0), 289 // (10, 'Manage Module', 3, 'module.edit', 0, '0', 0), 290 // (11, 'Add Module', 3, 'module.add', 0, '0', 0), 291 // (12, 'Manage Permission', 4, 'permission.edit', 0, '0', 0), 292 // (13, 'Add Permission', 4, 'permission.add', 0, '0', 0), 293 // (14, 'Manage Menu', 5, 'menu.edit', 0, '0', 0), 294 // (15, 'Add Menu', 5, 'menu.add', 0, '0', 0); 295 296 297 auto option = new EntityOption; 298 299 option.database.driver = "mysql"; 300 option.database.host = "127.0.0.1"; 301 option.database.port = 3306; 302 option.database.database = "hunt_test"; 303 option.database.username = "root"; 304 option.database.password = "123456"; 305 option.database.charset = "utf8mb4"; 306 option.database.prefix = ""; 307 308 EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("default", option); 309 EntityManager em = entityManagerFactory.createEntityManager(); 310 311 auto rep = new EntityRepository!(Menu , int)(em); 312 313 //sort 314 auto menus1 = rep.findAll(new Sort(rep.field.ID , OrderBy.DESC)); 315 assert(menus1.length == 15); 316 assert(menus1[0].ID == 15 && menus1[$ - 1].ID == 1); 317 318 //specification 319 class MySpecification: Specification!Menu 320 { 321 Predicate toPredicate(Root!Menu root, CriteriaQuery!Menu criteriaQuery , 322 CriteriaBuilder criteriaBuilder) 323 { 324 Predicate _name = criteriaBuilder.gt(root.Menu.ID, 5); 325 return criteriaBuilder.and(_name); 326 } 327 } 328 auto menus2 = rep.findAll(new MySpecification()); 329 assert(menus2.length == 10); 330 assert(menus2[0].ID == 6); 331 332 //sort specification 333 auto menus3 = rep.findAll(new MySpecification , new Sort(rep.field.ID ,OrderBy.DESC)); 334 assert(menus3[0].ID == 15 && menus3[$ - 1].ID == 6); 335 336 //page 337 auto pages1 = rep.findAll(new Pageable(0 , 10 , rep.field.ID , OrderBy.DESC)); 338 assert(pages1.getTotalPages() == 2); 339 assert(pages1.getContent.length == 10); 340 assert(pages1.getContent[0].ID == 15 && pages1.getContent[$-1].ID == 6); 341 assert(pages1.getTotalElements() == 15); 342 343 //page specification 344 auto pages2 = rep.findAll(new MySpecification , new Pageable(1 , 5 , rep.field.ID , OrderBy.DESC)); 345 assert(pages2.getTotalPages() == 2); 346 assert(pages2.getContent.length == 5); 347 assert(pages2.getContent[0].ID == 10 && pages1.getContent[$-1].ID == 6); 348 assert(pages2.getTotalElements() == 10); 349 350 ///where name == "User" 351 auto condition = new Condition(`%s = '%s'` , rep.field.name , "User"); 352 auto menu4 = rep.find(condition); 353 assert(menu4.ID == 1); 354 355 ///count 356 assert(rep.count(new Condition(`%s > %d` , rep.field.ID , 0)) == 15); 357 358 359 } 360 361 362 test_entity_repository(); 363 }*/