質問編集履歴
4
添付の修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -424,4 +424,13 @@
|
|
424
424
|
### 補足情報(FW/ツールのバージョンなど)
|
425
425
|
stsのプロジェクトは:spring web/ thymeleaf/My SQL Driver/MyBatis Framework を選択しております。
|
426
426
|
|
427
|
-
ここにより詳細な情報を記載してください。
|
427
|
+
ここにより詳細な情報を記載してください。
|
428
|
+
|
429
|
+
※ブラウザエラー
|
430
|
+

|
431
|
+
|
432
|
+
※stsエラー①
|
433
|
+

|
434
|
+
|
435
|
+
※stsエラー②
|
436
|
+

|
3
ご指摘いただいたものを修正いたしました。
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,7 +1,4 @@
|
|
1
1
|
### 前提・実現したいこと
|
2
|
-
最終的には、localhostに反映した商品名等の表示・購入btnのクリック・ 履歴表示のクリックで開発者ツールに表示されるようにしたいです。
|
3
|
-
|
4
|
-
お世話になります。
|
5
2
|
現在、簡易的なショッピングサイトを作成しております。
|
6
3
|
そこで発生したエラーについてですが、どのように修正をすればよいのか分からず、お力をいただければと思い投稿いたしました。
|
7
4
|
よろしくお願いいたします。
|
@@ -9,9 +6,7 @@
|
|
9
6
|
### 発生している問題・エラーメッセージ
|
10
7
|
|
11
8
|
```
|
12
|
-
|
9
|
+
添付参照
|
13
|
-
spring tool :: [THYMELEAF][http-nio-8080-exec-1] Exception processing template "index": An error happened during template parsing (template: "class path resource [templates/index.html]")
|
14
|
-
|
15
10
|
```
|
16
11
|
|
17
12
|
### 該当のソースコード
|
@@ -21,7 +16,7 @@
|
|
21
16
|
|
22
17
|
package xxxxx.practice.controlle;
|
23
18
|
|
24
|
-
import java.util.List;
|
19
|
+
import java.util.List;略
|
25
20
|
|
26
21
|
@Controller
|
27
22
|
@RequestMapping("/practice")
|
@@ -88,7 +83,7 @@
|
|
88
83
|
|
89
84
|
```
|
90
85
|
【Goods.java】
|
91
|
-
package
|
86
|
+
package xxxxx.model.domain;
|
92
87
|
|
93
88
|
import java.sql.Timestamp;
|
94
89
|
import java.util.List;
|
@@ -100,56 +95,328 @@
|
|
100
95
|
private long price;
|
101
96
|
private Timestamp updatedAt;
|
102
97
|
private List<Purchase> purchaseList;
|
98
|
+
|
99
|
+
以下文字数オーバーのため略(getter/setter)
|
103
100
|
|
104
|
-
public long getId() {
|
105
|
-
return id;
|
106
|
-
|
101
|
+
```
|
107
|
-
public void setId(long id) {
|
108
|
-
this.id = id;
|
109
|
-
|
102
|
+
```
|
110
|
-
public String getGoodsName() {
|
111
|
-
return goodsName;
|
112
|
-
}
|
113
|
-
public void setGoodsName(String goodsName) {
|
114
|
-
this.goodsName = goodsName;
|
115
|
-
}
|
116
|
-
public long getPrice() {
|
117
|
-
return price;
|
118
|
-
}
|
119
|
-
public void setPrice(long price) {
|
120
|
-
this.price = price;
|
121
|
-
}
|
122
|
-
public Timestamp getUpdatedAt() {
|
123
|
-
return updatedAt;
|
124
|
-
}
|
125
|
-
public void setUpdatedAt(Timestamp updatedAt) {
|
126
|
-
this.updatedAt = updatedAt;
|
127
|
-
}
|
128
|
-
public List<Purchase> getPurchaseList() {
|
129
|
-
|
103
|
+
【Purchase.java】
|
130
|
-
}
|
131
|
-
public void setPurchaseList(List<Purchase> purchaseList) {
|
132
|
-
|
104
|
+
package xxxxx.practice.model.domain;
|
133
|
-
}
|
134
105
|
|
106
|
+
import java.sql.Timestamp;
|
107
|
+
|
108
|
+
public class Purchase {
|
109
|
+
|
110
|
+
private long id;
|
111
|
+
private long userId;
|
112
|
+
private long goodsId;
|
113
|
+
private long itemCount;
|
114
|
+
private long total;
|
115
|
+
private Timestamp createdAt;
|
116
|
+
|
117
|
+
以下文字数オーバーのため略(getter/setter)
|
118
|
+
|
119
|
+
|
120
|
+
```
|
121
|
+
```
|
122
|
+
【User.java】
|
123
|
+
package xxxxx.practice.model.domain;
|
124
|
+
|
125
|
+
public class User {
|
126
|
+
|
127
|
+
private long id;
|
128
|
+
private String userName;
|
129
|
+
private String password;
|
130
|
+
private String fullName;
|
131
|
+
private int isAdmin;
|
132
|
+
|
133
|
+
以下文字数オーバーのため略(getter/setter)
|
134
|
+
|
135
|
+
```
|
136
|
+
```
|
137
|
+
【HistoryDto.java】
|
138
|
+
package xxxxx.practice.model.domain.dto;
|
139
|
+
|
140
|
+
import java.sql.Timestamp;略
|
141
|
+
|
142
|
+
public class HistoryDto {
|
143
|
+
|
144
|
+
private long id;
|
145
|
+
private long userId;
|
146
|
+
private long goodsId;
|
147
|
+
private String goodsName;
|
148
|
+
private long itemCount;
|
149
|
+
private long total;
|
150
|
+
private Timestamp createdAt;
|
151
|
+
|
152
|
+
public HistoryDto() {}
|
153
|
+
|
154
|
+
public HistoryDto(Goods goods) {
|
155
|
+
Purchase p = goods.getPurchaseList().get(0);
|
156
|
+
this.setId(p.getId());
|
157
|
+
this.setUserId(p.geUsertId());
|
158
|
+
this.setGoodsId(p.getGoodsId());
|
159
|
+
this.setGoodsName(goods.getGoodsName());
|
160
|
+
this.setItemCount(p.getItemCount());
|
161
|
+
this.setTotal(p.getTotal());
|
162
|
+
this.setCreatedAt(p.getCreatedAt());
|
163
|
+
|
164
|
+
|
135
165
|
}
|
136
166
|
|
167
|
+
以下文字数オーバーのため略(getter/setter)
|
137
168
|
```
|
169
|
+
|
138
170
|
```
|
139
|
-
【
|
171
|
+
【HistoryForm.java】
|
172
|
+
|
173
|
+
package xxxxx.practice.model.form;
|
174
|
+
|
175
|
+
import java.io.Serializable;
|
176
|
+
|
177
|
+
public class HistoryForm implements Serializable {
|
178
|
+
private static final long serialVersionUID = 1L;
|
179
|
+
|
180
|
+
private String userId;
|
181
|
+
|
182
|
+
以下文字数オーバーのため略(getter/setter)
|
183
|
+
|
140
184
|
```
|
185
|
+
|
141
186
|
```
|
142
|
-
【
|
187
|
+
【PurchaseForm.java】
|
188
|
+
|
189
|
+
package xxxxx.practice.model.form;
|
190
|
+
|
191
|
+
import java.io.Serializable;
|
192
|
+
|
193
|
+
public class PurchaseForm implements Serializable {
|
194
|
+
private static final long serialVersionUID = 1L;
|
195
|
+
|
196
|
+
private long userId;
|
197
|
+
private long goodsId;
|
198
|
+
private long itemCount;
|
199
|
+
private long total;
|
200
|
+
|
201
|
+
以下文字数オーバーのため略(getter/setter)
|
202
|
+
|
143
203
|
```
|
204
|
+
|
144
205
|
```
|
145
|
-
【
|
206
|
+
【GoodsMapper.java】
|
207
|
+
package 〃.practice.model.mapper;
|
208
|
+
|
209
|
+
import java.util.List;
|
210
|
+
|
211
|
+
import org.apache.ibatis.annotations.Delete;略
|
212
|
+
|
213
|
+
@Mapper
|
214
|
+
public interface GoodsMapper {
|
215
|
+
|
216
|
+
@Select("SELECT * FROM goods")
|
217
|
+
List<Goods> findAll();
|
218
|
+
|
219
|
+
@Delete("DELETE FROM goods WHERE Id = #{id}")
|
220
|
+
boolean deleteById(long id);
|
221
|
+
|
222
|
+
}
|
223
|
+
|
224
|
+
|
146
225
|
```
|
226
|
+
```
|
227
|
+
【PurchaseMapper.java】
|
147
228
|
|
229
|
+
package 〃.practice.model.mapper;
|
148
230
|
|
231
|
+
import java.util.List;
|
149
232
|
|
233
|
+
import org.apache.ibatis.annotations.Insert;略
|
234
|
+
@Mapper
|
235
|
+
public interface PurchaseMapper {
|
236
|
+
|
237
|
+
List<HistoryDto> findHistory(@Param("userId") String userId);
|
238
|
+
|
239
|
+
@Insert("INSERT INTO purchase (user_id, goods_id, item_count, total)" +
|
240
|
+
"VALUES (#{userId}, #{goodsId}, #{itemCount}, #{total})")
|
241
|
+
@Options(useGeneratedKeys=true, keyProperty="id")
|
242
|
+
void insert(Purchase purchase);
|
243
|
+
}
|
150
244
|
|
245
|
+
```
|
246
|
+
```
|
247
|
+
【UserMapper.java】
|
151
248
|
|
249
|
+
package 〃.practice.model.mapper;
|
152
250
|
|
251
|
+
import java.util.List;略
|
252
|
+
|
253
|
+
@Mapper
|
254
|
+
public interface UserMapper {
|
255
|
+
|
256
|
+
List<User> findByUserNameAndPassword (
|
257
|
+
@Param("userName") String userName,
|
258
|
+
@Param("password") String password);
|
259
|
+
}
|
260
|
+
|
261
|
+
```
|
262
|
+
```
|
263
|
+
【PurchaseMapper.xml】
|
264
|
+
|
265
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
266
|
+
<!DOCTYPE html
|
267
|
+
PUBLIC "-//mybatis.org//DTO Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
268
|
+
<mapper
|
269
|
+
namespace="〃.practice.model.mapper.PurchaseMapper">
|
270
|
+
|
271
|
+
<select id="findHistory" resultType="〃.practice.model.domain.dto.HistoryDto">
|
272
|
+
SELECT p.id, p.user_id, p.goods_id, p.goods_name, p.item_count, p.total, p.created_at
|
273
|
+
FROM purchase p
|
274
|
+
INNER JOIN goods g
|
275
|
+
ON p.goods_id = g.id
|
276
|
+
WHERE created_at = (
|
277
|
+
SELECT MAX(created_at) FROM purchase p WHERE p.user_id = #{userId})
|
278
|
+
</select>
|
279
|
+
|
280
|
+
</mapper>
|
281
|
+
```
|
282
|
+
```
|
283
|
+
【UserMapper.xml】
|
284
|
+
|
285
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
286
|
+
<!DOCTYPE html
|
287
|
+
PUBLIC "-//mybatis.org//DTO Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
288
|
+
<mapper
|
289
|
+
namespace="〃.practice.model.mapper.UserMapper">
|
290
|
+
|
291
|
+
<select id="findByUserNameAndPassword"
|
292
|
+
resultType="〃.practice.model.domain.User">
|
293
|
+
SELECT * FROM user WHERE user_name = #{userName} AND password = #{password}
|
294
|
+
</select>
|
295
|
+
|
296
|
+
</mapper>
|
297
|
+
```
|
298
|
+
```
|
299
|
+
【index.html】
|
300
|
+
|
301
|
+
<!DOCTYPE html>
|
302
|
+
<html xmlns:th="http://www.thymeleaf.org">
|
303
|
+
<head>
|
304
|
+
<meta charset="UTF-8" />
|
305
|
+
<title>ショッピングサイト(仮)</title>
|
306
|
+
|
307
|
+
<style>
|
308
|
+
td:nth-child(1).td:nth-child(3) {
|
309
|
+
text-align: right;
|
310
|
+
}
|
311
|
+
input[type=number] {
|
312
|
+
width: 50px;
|
313
|
+
text-align: right;
|
314
|
+
}
|
315
|
+
</style>
|
316
|
+
|
317
|
+
<script src="http://code.jquery.com/jquery-3.4.1.min.js"></script>
|
318
|
+
<script>
|
319
|
+
$(() => {
|
320
|
+
$('button.purchase').on('click', buy);
|
321
|
+
$('button#history').on('click', showHistory);
|
322
|
+
});
|
323
|
+
|
324
|
+
let buy = (event) => {
|
325
|
+
let targetTr = $(event.target).parent().parent();
|
326
|
+
let tdList = $(targetTr).find('td');
|
327
|
+
|
328
|
+
let total = Number($(tdList[3]).find('input').val()) * Number($(tdList[2]).text());
|
329
|
+
|
330
|
+
let data = {
|
331
|
+
"userId": $('#hiddenUserId').val(),
|
332
|
+
"goodsId": $(tdList[0]).text(),
|
333
|
+
"itemCount": $(tdList[3]).find('input').val(),
|
334
|
+
"total": total,
|
335
|
+
};
|
336
|
+
|
337
|
+
$.ajax ({
|
338
|
+
type: 'POST',
|
339
|
+
url: '/practice/api/purchase',
|
340
|
+
data: JSON.stringify(data),
|
341
|
+
contentType: 'application/json',
|
342
|
+
datatype: 'json',
|
343
|
+
scriptCharset: 'utf-8'
|
344
|
+
})
|
345
|
+
|
346
|
+
.then(
|
347
|
+
(result) => {
|
348
|
+
alert('購入');
|
349
|
+
}, () => {
|
350
|
+
console.error('Error: ajax connection failed.');
|
351
|
+
}
|
352
|
+
);
|
353
|
+
};
|
354
|
+
|
355
|
+
|
356
|
+
let showHistory = (event) => {
|
357
|
+
$.ajax({
|
358
|
+
type: 'POST',
|
359
|
+
url: '/practice/api/history',
|
360
|
+
data: JSON.stringify({
|
361
|
+
"userId": $('#hiddenUserId').val(),
|
362
|
+
}),
|
363
|
+
contentType: 'application/json',
|
364
|
+
datatype: 'json',
|
365
|
+
scriptCharset: 'utf-8'
|
366
|
+
})
|
367
|
+
}
|
368
|
+
|
369
|
+
.then(
|
370
|
+
(result) => {
|
371
|
+
let purchaseList = JSON.parse(result);
|
372
|
+
purchaseList.map((v) => {
|
373
|
+
console.log(v.userId);
|
374
|
+
console.log(v.goodsId);
|
375
|
+
console.log(v.goodsName);
|
376
|
+
console.log(v.createdAt);
|
377
|
+
})
|
378
|
+
},
|
379
|
+
() => {
|
380
|
+
console.error('Error: ajax connection failed.');
|
381
|
+
}
|
382
|
+
);
|
383
|
+
};
|
384
|
+
</script>
|
385
|
+
</head>
|
386
|
+
<body>
|
387
|
+
|
388
|
+
<table id="goodsListTable">
|
389
|
+
<thead>
|
390
|
+
<tr>
|
391
|
+
<th>xxx</th><th>xxx</th><th>xxx</th><th>xxx</th><th>xxx</th>
|
392
|
+
</tr>
|
393
|
+
</thead>
|
394
|
+
|
395
|
+
<tbody>
|
396
|
+
<tr th:each="item: ${goodsList}">
|
397
|
+
<td th:text="${item.id}"/>
|
398
|
+
<td th:text="${item.goodsName}"/>
|
399
|
+
<td th:text="${item.price}"/>
|
400
|
+
<td><input type="number" class="count" value="0" /></td>
|
401
|
+
<td><button class="purchase">購入</button></td>
|
402
|
+
</tr>
|
403
|
+
</tbody>
|
404
|
+
|
405
|
+
</table>
|
406
|
+
|
407
|
+
<button id="history">履歴</button>
|
408
|
+
|
409
|
+
<input type="hidden" id="hiddenUserId" th:value="${user.id}" />
|
410
|
+
|
411
|
+
</body>
|
412
|
+
</html>
|
413
|
+
```
|
414
|
+
|
415
|
+
|
416
|
+
|
417
|
+
|
418
|
+
|
419
|
+
|
153
420
|
### 試したこと
|
154
421
|
|
155
422
|
誤字脱字の確認。エラーについて調べるものの、いまいちわかりませんでした。
|
2
ご指摘いただいたものを、全て修正いたしました。
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
簡易的なショッピングサイト
|
1
|
+
簡易的なショッピングサイト【初心者質問】
|
body
CHANGED
@@ -1,48 +1,28 @@
|
|
1
1
|
### 前提・実現したいこと
|
2
|
-
|
2
|
+
最終的には、localhostに反映した商品名等の表示・購入btnのクリック・ 履歴表示のクリックで開発者ツールに表示されるようにしたいです。
|
3
|
-
掲題の件につきましてご質問です。
|
4
3
|
|
4
|
+
お世話になります。
|
5
|
-
現在
|
5
|
+
現在、簡易的なショッピングサイトを作成しております。
|
6
|
-
|
6
|
+
そこで発生したエラーについてですが、どのように修正をすればよいのか分からず、お力をいただければと思い投稿いたしました。
|
7
|
+
よろしくお願いいたします。
|
7
8
|
|
8
|
-
ブラウザのコンソールでは『GET http://localhost:8080/practice 404 practice:1 』と表示されました。
|
9
|
-
404 => 該当アドレスのページがない、またはそのサーバーが落ちている状態
|
10
9
|
### 発生している問題・エラーメッセージ
|
11
10
|
|
12
11
|
```
|
13
|
-
ブラウザのコンソール
|
14
|
-
|
12
|
+
ブラウザ: GET http://localhost:8080/practice/ 404
|
15
|
-
|
13
|
+
spring tool :: [THYMELEAF][http-nio-8080-exec-1] Exception processing template "index": An error happened during template parsing (template: "class path resource [templates/index.html]")
|
14
|
+
|
16
15
|
```
|
17
16
|
|
18
17
|
### 該当のソースコード
|
19
18
|
|
19
|
+
```ここに言語名を入力
|
20
|
-
|
20
|
+
【IndexController】
|
21
|
-
package co.jp.internous.practice.controlle;
|
22
21
|
|
23
|
-
|
22
|
+
package xxxxx.practice.controlle;
|
24
23
|
|
25
|
-
import org.springframework.beans.factory.annotation.Autowired;
|
26
|
-
import org.springframework.stereotype.Controller;
|
27
|
-
import
|
24
|
+
import java.util.List;以下略
|
28
|
-
import org.springframework.web.bind.annotation.PostMapping;
|
29
|
-
import org.springframework.web.bind.annotation.RequestBody;
|
30
|
-
import org.springframework.web.bind.annotation.RequestMapping;
|
31
|
-
import org.springframework.web.bind.annotation.ResponseBody;
|
32
25
|
|
33
|
-
import com.google.gson.Gson;
|
34
|
-
|
35
|
-
import co.jp.internous.practice.model.domain.Goods;
|
36
|
-
import co.jp.internous.practice.model.domain.Purchase;
|
37
|
-
import co.jp.internous.practice.model.domain.User;
|
38
|
-
import co.jp.internous.practice.model.domain.dto.HistoryDto;
|
39
|
-
import co.jp.internous.practice.model.form.HistoryForm;
|
40
|
-
import co.jp.internous.practice.model.form.PurchaseForm;
|
41
|
-
import co.jp.internous.practice.model.mapper.GoodsMapper;
|
42
|
-
import co.jp.internous.practice.model.mapper.PurchaseMapper;
|
43
|
-
import co.jp.internous.practice.model.mapper.UserMapper;
|
44
|
-
|
45
|
-
|
46
26
|
@Controller
|
47
27
|
@RequestMapping("/practice")
|
48
28
|
public class IndexController {
|
@@ -58,7 +38,7 @@
|
|
58
38
|
|
59
39
|
Gson gson = new Gson();
|
60
40
|
|
61
|
-
@RequestMapping("
|
41
|
+
@RequestMapping("practice")
|
62
42
|
public String index(Model m) {
|
63
43
|
String userName = "taro";
|
64
44
|
String password = "taropw";
|
@@ -103,151 +83,13 @@
|
|
103
83
|
}
|
104
84
|
}
|
105
85
|
|
106
|
-
```
|
107
86
|
|
108
|
-
```dto
|
109
|
-
package co.jp.internous.practice.model.domain.dto;
|
110
|
-
|
111
|
-
import java.sql.Timestamp;
|
112
|
-
|
113
|
-
import co.jp.internous.practice.model.domain.Goods;
|
114
|
-
import co.jp.internous.practice.model.domain.Purchase;
|
115
|
-
|
116
|
-
public class HistoryDto {
|
117
|
-
|
118
|
-
private long id;
|
119
|
-
private long userId;
|
120
|
-
private long goodsId;
|
121
|
-
private String goodsName;
|
122
|
-
private long itemCount;
|
123
|
-
private long total;
|
124
|
-
private Timestamp createdAt;
|
125
|
-
|
126
|
-
public HistoryDto() {}
|
127
|
-
|
128
|
-
public HistoryDto(Goods goods) {
|
129
|
-
Purchase p = goods.getPurchaseList().get(0);
|
130
|
-
this.setId(p.getId());
|
131
|
-
this.setUserId(p.geUsertId());
|
132
|
-
this.setGoodsId(p.getGoodsId());
|
133
|
-
this.setGoodsName(goods.getGoodsName());
|
134
|
-
this.setItemCount(p.getItemCount());
|
135
|
-
this.setTotal(p.getTotal());
|
136
|
-
this.setCreatedAt(p.getCreatedAt());
|
137
|
-
|
138
|
-
|
139
|
-
}
|
140
|
-
|
141
|
-
※Setter / Getterは略
|
142
|
-
|
143
|
-
}
|
144
|
-
|
145
87
|
```
|
146
88
|
|
147
|
-
```form
|
148
|
-
【HistoryForm】
|
149
|
-
package co.jp.internous.practice.model.form;
|
150
|
-
|
151
|
-
import java.io.Serializable;
|
152
|
-
|
153
|
-
public class HistoryForm implements Serializable {
|
154
|
-
private static final long serialVersionUID = 1L;
|
155
|
-
|
156
|
-
private String userId;
|
157
|
-
|
158
|
-
※Setter / Getterは略
|
159
|
-
|
160
|
-
}
|
161
|
-
|
162
|
-
|
163
|
-
【PUrchaseForm】
|
164
|
-
import java.io.Serializable;
|
165
|
-
|
166
|
-
public class PurchaseForm implements Serializable {
|
167
|
-
private static final long serialVersionUID = 1L;
|
168
|
-
|
169
|
-
private long userId;
|
170
|
-
private long goodsId;
|
171
|
-
private long itemCount;
|
172
|
-
private long total;
|
173
|
-
|
174
|
-
※Setter / Getterは略
|
175
|
-
}
|
176
|
-
|
177
89
|
```
|
90
|
+
【Goods.java】
|
91
|
+
package xxxx.model.domain;
|
178
92
|
|
179
|
-
```mapper
|
180
|
-
【Goods】
|
181
|
-
package co.jp.internous.practice.model.mapper;
|
182
|
-
|
183
|
-
import java.util.List;
|
184
|
-
|
185
|
-
import org.apache.ibatis.annotations.Delete;
|
186
|
-
import org.apache.ibatis.annotations.Mapper;
|
187
|
-
import org.apache.ibatis.annotations.Select;
|
188
|
-
|
189
|
-
import co.jp.internous.practice.model.domain.Goods;
|
190
|
-
|
191
|
-
@Mapper
|
192
|
-
public interface GoodsMapper {
|
193
|
-
|
194
|
-
@Select("SELECT * FROM goods")
|
195
|
-
List<Goods> findAll();
|
196
|
-
|
197
|
-
@Delete("DELETE FROM goods WHERE Id = #{id}")
|
198
|
-
boolean deleteById(long id);
|
199
|
-
|
200
|
-
}
|
201
|
-
|
202
|
-
【User】
|
203
|
-
|
204
|
-
package co.jp.internous.practice.model.mapper;
|
205
|
-
|
206
|
-
import java.util.List;
|
207
|
-
|
208
|
-
import org.apache.ibatis.annotations.Mapper;
|
209
|
-
import org.apache.ibatis.annotations.Param;
|
210
|
-
|
211
|
-
import co.jp.internous.practice.model.domain.User;
|
212
|
-
|
213
|
-
@Mapper
|
214
|
-
public interface UserMapper {
|
215
|
-
|
216
|
-
List<User> findByUserNameAndPassword (
|
217
|
-
@Param("userName") String userName,
|
218
|
-
@Param("password") String password );
|
219
|
-
}
|
220
|
-
|
221
|
-
|
222
|
-
【Purchase】
|
223
|
-
package co.jp.internous.practice.model.mapper;
|
224
|
-
|
225
|
-
import java.util.List;
|
226
|
-
|
227
|
-
import org.apache.ibatis.annotations.Insert;
|
228
|
-
import org.apache.ibatis.annotations.Mapper;
|
229
|
-
import org.apache.ibatis.annotations.Options;
|
230
|
-
import org.apache.ibatis.annotations.Param;
|
231
|
-
|
232
|
-
import co.jp.internous.practice.model.domain.Purchase;
|
233
|
-
import co.jp.internous.practice.model.domain.dto.HistoryDto;
|
234
|
-
|
235
|
-
@Mapper
|
236
|
-
public interface PurchaseMapper {
|
237
|
-
|
238
|
-
List<HistoryDto> findHistory(@Param("userId") String userId);
|
239
|
-
|
240
|
-
@Insert("INSERT INTO purchase (user_id, goods_id, item_count, total)" +
|
241
|
-
"VALUES (#{userId}, #{goodsId}, #{itemCount}, #{total})")
|
242
|
-
@Options(useGeneratedKeys=true, keyProperty="id")
|
243
|
-
void insert(Purchase purchase);
|
244
|
-
}
|
245
|
-
|
246
|
-
```
|
247
|
-
|
248
|
-
```domain
|
249
|
-
package co.jp.internous.practice.model.domain;
|
250
|
-
|
251
93
|
import java.sql.Timestamp;
|
252
94
|
import java.util.List;
|
253
95
|
|
@@ -258,164 +100,61 @@
|
|
258
100
|
private long price;
|
259
101
|
private Timestamp updatedAt;
|
260
102
|
private List<Purchase> purchaseList;
|
261
|
-
|
262
|
-
※Setter / Getterは略
|
263
|
-
|
264
|
-
```
|
265
|
-
|
266
|
-
|
267
|
-
```xml
|
268
|
-
【Purchase】
|
269
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
270
|
-
<!DOCTYPE html
|
271
|
-
PUBLIC "-//mybatis.org//DTO Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
272
|
-
<mapper
|
273
|
-
namespace="jp.co.internous.practice.model.mapper.PurchaseMapper">
|
274
|
-
|
275
|
-
<select id="findHistory" resultType="jp.co.internous.practice.model.domain.dto.HistoryDto">
|
276
|
-
SELECT p.id, p.user_id, p.goods_id, p.goods_name, p.item_count, p.total, p.created_at
|
277
|
-
FROM purchase p
|
278
|
-
INNER JOIN goods g
|
279
|
-
ON p.goods_id = g.id
|
280
|
-
WHERE created_at = (
|
281
|
-
SELECT MAX(created_at) FROM purchase p WHERE p.user_id = #{userId})
|
282
|
-
</select>
|
283
103
|
|
104
|
+
public long getId() {
|
105
|
+
return id;
|
106
|
+
}
|
107
|
+
public void setId(long id) {
|
108
|
+
this.id = id;
|
109
|
+
}
|
110
|
+
public String getGoodsName() {
|
111
|
+
return goodsName;
|
112
|
+
}
|
113
|
+
public void setGoodsName(String goodsName) {
|
114
|
+
this.goodsName = goodsName;
|
115
|
+
}
|
116
|
+
public long getPrice() {
|
117
|
+
return price;
|
118
|
+
}
|
119
|
+
public void setPrice(long price) {
|
120
|
+
this.price = price;
|
121
|
+
}
|
122
|
+
public Timestamp getUpdatedAt() {
|
123
|
+
return updatedAt;
|
124
|
+
}
|
125
|
+
public void setUpdatedAt(Timestamp updatedAt) {
|
126
|
+
this.updatedAt = updatedAt;
|
127
|
+
}
|
128
|
+
public List<Purchase> getPurchaseList() {
|
284
|
-
|
129
|
+
return purchaseList;
|
130
|
+
}
|
131
|
+
public void setPurchaseList(List<Purchase> purchaseList) {
|
132
|
+
this.purchaseList = purchaseList;
|
133
|
+
}
|
285
134
|
|
286
|
-
【UserMapper】
|
287
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
288
|
-
<!DOCTYPE html
|
289
|
-
PUBLIC "-//mybatis.org//DTO Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
290
|
-
|
135
|
+
}
|
291
|
-
namespace="jp.co.internous.practice.model.mapper.UserMapper">
|
292
136
|
|
293
|
-
<select id="findByUserNameAndPassword"
|
294
|
-
resultType="jp.co.internous.practice.model.domain.User">
|
295
|
-
SELECT * FROM user WHERE user_name = #{userName} AND password = #{password}
|
296
|
-
</select>
|
297
|
-
|
298
|
-
</mapper>
|
299
137
|
```
|
138
|
+
```
|
139
|
+
【Purchase.java】
|
140
|
+
```
|
141
|
+
```
|
142
|
+
【User.java】
|
143
|
+
```
|
144
|
+
```
|
145
|
+
【User.java】
|
146
|
+
```
|
300
147
|
|
301
|
-
```html
|
302
|
-
<!DOCTYPE html>
|
303
|
-
<html xmlns:th="http://www.thymeleaf.org">
|
304
|
-
<head>
|
305
|
-
<meta charset="UTF-8" />
|
306
|
-
<title>Study Spring boot and Mybatis</title>
|
307
148
|
|
308
|
-
<style>
|
309
|
-
td:nth-child(1).td:nth-child(3) {
|
310
|
-
text-align: right;
|
311
|
-
}
|
312
|
-
input[type=number] {
|
313
|
-
width: 50px;
|
314
|
-
text-align: right;
|
315
|
-
}
|
316
|
-
</style>
|
317
149
|
|
318
|
-
<script src="http://code.jquery.com/jquery-3.4.1.min.js"></script>
|
319
|
-
<script>
|
320
|
-
$(() => {
|
321
|
-
$('button.purchase').on('click', buy);
|
322
|
-
$('button#history').on('click', showHistory);
|
323
|
-
});
|
324
150
|
|
325
|
-
let buy = (event) => {
|
326
|
-
let targetTr = $(event.target).parent().parent();
|
327
|
-
let tdList = $(targetTr).find('td');
|
328
|
-
let total = Number($(tdList[3]).find('input').val()) * Number($(tdList[2]).text());
|
329
151
|
|
330
|
-
let data = {
|
331
|
-
"userId": $('#hiddenUserId').val(),
|
332
|
-
"goodsId": $(tdList[0]).text(),
|
333
|
-
"itemCount": $(tdList[3]).find('input').val(),
|
334
|
-
"total": total,
|
335
|
-
};
|
336
152
|
|
337
|
-
$.ajax ({
|
338
|
-
type: 'POST',
|
339
|
-
url: '/practice/api/purchase',
|
340
|
-
data: JSON.stringify(data),
|
341
|
-
contentType: 'application/json',
|
342
|
-
datatype: 'json',
|
343
|
-
scriptCharset: 'utf-8
|
344
|
-
})
|
345
|
-
|
346
|
-
.then(
|
347
|
-
(result) => {
|
348
|
-
alert('購入しました。');
|
349
|
-
}, () => {
|
350
|
-
console.error('Error: ajax connection failed.');
|
351
|
-
}
|
352
|
-
);
|
353
|
-
};
|
354
|
-
|
355
|
-
|
356
|
-
let showHistory = (event) => {
|
357
|
-
$.ajax({
|
358
|
-
type: 'POST',
|
359
|
-
url: '/practice/api/history',
|
360
|
-
data: JSON.stringify({
|
361
|
-
"userId": $('#hiddenUserId').val(),
|
362
|
-
}),
|
363
|
-
contentType: 'application/json',
|
364
|
-
datatype: 'json',
|
365
|
-
scriptCharset: 'utf-8'
|
366
|
-
})
|
367
|
-
}
|
368
|
-
|
369
|
-
.then(
|
370
|
-
(result) => {
|
371
|
-
let purchaseList = JSON.parse(result);
|
372
|
-
purchaseList.map((v) => {
|
373
|
-
console.log(v.userId);
|
374
|
-
console.log(v.goodsId);
|
375
|
-
console.log(v.goodsName);
|
376
|
-
console.log(v.createdAt);
|
377
|
-
})
|
378
|
-
},
|
379
|
-
() => {
|
380
|
-
console.error('Error: ajax connection failed.');
|
381
|
-
}
|
382
|
-
);
|
383
|
-
};
|
384
|
-
</script>
|
385
|
-
</head>
|
386
|
-
<body>
|
387
|
-
|
388
|
-
<table id="goodsListTable">
|
389
|
-
<thead>
|
390
|
-
<tr>
|
391
|
-
<th>ID</th><th>商品名</th><th>価格</th><th>注文数</th><th>カート</th>
|
392
|
-
</tr>
|
393
|
-
</thead>
|
394
|
-
|
395
|
-
<tbody>
|
396
|
-
<tr th:each="item: ${goodsList}">
|
397
|
-
<td th:text="${item.id}"/>
|
398
|
-
<td th:text="${item.goodsName}"/>
|
399
|
-
<td th:text="${item.price}"/>
|
400
|
-
<td><input type="number" class="count" value="0" /></td>
|
401
|
-
<td><button class="purchase">購入</button></td>
|
402
|
-
</tr>
|
403
|
-
</tbody>
|
404
|
-
|
405
|
-
</table>
|
406
|
-
|
407
|
-
<button id="history">履歴</button>
|
408
|
-
|
409
|
-
<input type="hidden" id="hiddenUserId" th:value="${user.id}" />
|
410
|
-
|
411
|
-
</body>
|
412
|
-
</html>
|
413
|
-
```
|
414
153
|
### 試したこと
|
415
154
|
|
416
|
-
|
155
|
+
誤字脱字の確認。エラーについて調べるものの、いまいちわかりませんでした。
|
417
|
-
何卒宜しくお願い致します。
|
418
156
|
|
419
157
|
### 補足情報(FW/ツールのバージョンなど)
|
158
|
+
stsのプロジェクトは:spring web/ thymeleaf/My SQL Driver/MyBatis Framework を選択しております。
|
420
159
|
|
421
160
|
ここにより詳細な情報を記載してください。
|
1
題名の変更
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
|
1
|
+
簡易的なショッピングサイト
|
body
CHANGED
File without changes
|