SpringData系列一@Query注解及@Modifying注解â

很遗憾,这篇文章产生的初衷只是由于三个原因,第一,公司不忙,我太闲了,第二我是真的用到了,感觉这篇博文讲的不错,所以我想copy一遍@Query注解及@Modifying注解,第三,复习一遍。

@Query注解查询适用于所查询的数据无法通过关键字查询得到结果的查询。这种查询可以摆脱像关键字查询那样的约束,将查询直接在相应的接口方法中声明,结构更为清晰,这是Spring Data的特有实现。

  • 索引参数与命名参数

1. 索引参数如下所示,索引值从1开始,查询中”?X”个数需要与方法定义的参数个数相一致,并且顺序也要一致。

1
2
@Query("SELECT p FROM Person p WHERE p.lastName = ?1 AND p.email = ?2")
List<Person> testQueryAnnotationParams1(String lastName, String email);

注释:上面代码中的?1,?2表示参数的占位符,需要和方法中所传递的参数顺序一致。X是从1开始。

2. 命名参数(推荐使用此方式):可以定义好参数名,赋值时使用@Param(“参数名”),而不用管顺序。

1
2
3
// 为@Query注解传递参数的方式1:命名参数
@Query("SELECT p FROM Person p WHERE p.lastName = :lastName AND p.email = :email")
List<Person> testQueryAnnotationParams2(@Param("email") String email, @Param("lastName") String lastName);

注释:上面代码中:lastName ,:email 表示为参数命名,方法中所传递的参数使用@Param注解标识命名参数。这种方式不用管参数的顺序。

3. 含有LIKE关键字的查询

方式1:可以在占位符上添加”%”,这样在查询方法中就不用添加”%”

1
2
3
// like查询 Spring Date 允许在占位符上添加%
@Query("SELECT p FROM Person p WHERE p.lastName LIKE %?1% OR p.email LIKE %?2%")
List<Person> testQueryAnnotationLikeParam(String lastName, String email);
1
2
3
4
5
@Test
public void testAnnoationParams3() {
List<Person> persons = personRepsitory.testQueryAnnotationLikeParam("A", "A@126.com");
System.out.println(persons);
}

方式2:不在占位符上添加”%”,这样就必须在查询方法的参数上添加”%”

1
2
3
// like查询
@Query("SELECT p FROM Person p WHERE p.lastName LIKE ?1 OR p.email LIKE ?2")
List<Person> testQueryAnnotationLikeParam2(String lastName, String email);
1
2
3
4
5
@Test
public void testAnnoationParams4() {
List<Person> persons = personRepsitory.testQueryAnnotationLikeParam2("%A%", "%A@126.com%");
System.out.println(persons);
}

方式3:在命名参数上添加”%”

1
2
3
// like查询 使用命名参数
@Query("SELECT p FROM Person p WHERE p.lastName LIKE %:lastName% OR p.email LIKE %:email%")
List<Person> testQueryAnnotationLikeParam3(@Param("email") String email, @Param("lastName") String lastName);

4. 使用原生SQL进行查询

1
2
3
4
5
6
/**
* 设置nativeQuery=true 即可以使用原生的SQL进行查询
* @return
*/
@Query(value = "SELECT count(id) FROM jpa_persons", nativeQuery = true)
long getTotalCount();

注释:当设置nativeQuery=true即可以使用原生SQL进行查询

  • @Modifying注解
    1. 在@Query注解中编写JPQL实现DELETE和UPDATE操作的时候必须加上@modifying注解,以通知Spring Data 这是一个DELETE或UPDATE操作。
    2. UPDATE或者DELETE操作需要使用事务,此时需要 定义Service层,在Service层的方法上添加事务操作。
    3. 注意JPQL不支持INSERT操作。
1
2
3
4
@Transactional
@Modifying
@Query("UPDATE Person p SET p.email = :email WHERE p.id = :id")
void updatePersonEmail(@Param("id") Integer id, @Param("email") String email);

以上方法,那个like这里,还没有使用过,like查询,不知道这里是否是模糊查询,还没有测试过,不过,之前听别人说,sql语句中不建议用模糊查询,会对数据库产生很大压力,对数据库不友好。

indexdb

indexdb概念了解

写这篇文章主要是,因为项目中用到了这个东西,这篇文章的主要内容,我主要是记录一下,当时我完成app登录拦截功能时的思路。做功能之前我主要去网上参考了几篇文章,首先我去看了一下概念,了解概念以后,就分别去了解了一下indexdb是如何建库建表新增查找数据的。链接我提供一下,阮一峰网络日志

indexdb增删改查案例

这里提供一篇参考博客indexdb增删改查实例
因为我要实现登录功能,大概思路是创建数据库,然后创建数据表,将用户名存进去,下次登录直接在本地判断用户名是否存在即可,退出登录以后,先关闭数据库,在删除数据库。下面是我的测试代码,亲测可用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>indexdb</title>
</head>
<body>
<input type="button" onclick="addData(myDB.db,'students')" value="新增数据">
<input type="button" onclick="closeDB(myDB.db)" value="关闭数据库">
<input type="button" onclick="deleteDB(myDB.name)" value="删除数据库">
<script type="text/javascript">
var myDB = {
name: 'test',
version: 1,
db: null
};

var students = [{
id: 1001,
name: "Byron",
age: 24
}, {
id: 1002,
name: "Frank",
age: 30
}, {
id: 1003,
name: "Aaron",
age: 26
}, {
id: 1004,
name: "Casper",
age: 26
}];

function openDB(name, version) {
var version = version || 1;
var request = window.indexedDB.open(name, version);
request.onerror = function (e) {
console.log(e.currentTarget.error.message);
};
request.onsuccess = function (e) {
myDB.db = e.target.result;
};
request.onupgradeneeded = function (e) {
var db = e.target.result;
if (!db.objectStoreNames.contains('students')) {
var store = db.createObjectStore('students', { keyPath: 'id' });
store.createIndex('nameIndex', 'name', { unique: true });
store.createIndex('ageIndex', 'age', { unique: false });
}
console.log('DB version changed to ' + version);
};
}
function closeDB(db) {
db.close();
}

function deleteDB(name) {
indexedDB.deleteDatabase(name);
}

function addData(db, storeName) {
var trans = db.transaction([storeName], 'readwrite');
var store = trans.objectStore(storeName);

for (var i = 0; i < students.length; i++) {
store.add(students[i]);
}
}

function getDataByKey(db, storeName, value) {
var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
var request = store.get(value);
request.onsuccess = function (e) {
var student = e.target.result;
console.log(student.name);
};
}

function updateDataByKey(db, storeName, value) {
var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
var request = store.get(value);
request.onsuccess = function (e) {
var student = e.target.result;
student.age = 35;
store.put(student);
};
}

function deleteDataByKey(db, storeName, value) {
var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
store.delete(value);
}

function clearObjectStore(db, storeName) {
var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
store.clear();
}

function deleteObjectStore(db, storeName) {
var transaction = db.transaction(storeName, 'versionchange');
db.deleteObjectStore(storeName);
}

function fetchStoreByCursor(db, storeName) {
var transaction = db.transaction(storeName);
var store = transaction.objectStore(storeName);
var request = store.openCursor();
request.onsuccess = function (e) {
var cursor = e.target.result;
if (cursor) {
console.log(cursor.key);
var currentStudent = cursor.value;
console.log(currentStudent.name);
cursor.continue();
}
};
}

function getDataByIndex(db, storeName) {
var transaction = db.transaction(storeName);
var store = transaction.objectStore(storeName);
var index = store.index("ageIndex");
index.get(26).onsuccess = function (e) {
var student = e.target.result;
console.log(student.id);
}
}

function getMultipleData(db, storeName) {
var transaction = db.transaction(storeName);
var store = transaction.objectStore(storeName);
var index = store.index("nameIndex");
var request = index.openCursor(null, IDBCursor.prev);
request.onsuccess = function (e) {
var cursor = e.target.result;
if (cursor) {
var student = cursor.value;
console.log(student.name);
cursor.continue();
}
}
}

openDB(myDB.name,myDB.version);
</script>
</body>
</html>

上面是一个封装好的indexdb代码,里面的方法我就暂时研究了indexdb初始化数据库,indexdb新建表并且添加数据,indexdb关闭数据库并且删除数据库,其他的暂时还没有用到了,简单看了一下,就没有测试了,感兴趣的朋友就自己测试吧,这里简单做一个记录,方便以后自己查看和回忆。

myfirstblog

最近搭建了一个自己的博客,用的是默认主题,(可能后期会去copy一个漂亮的主题)搭建博客的初衷是为了记录自己的学习历程,也许很low,也许没有任何参考价值,不过我还是要写,主要原因呢,还想要强迫一下自己学习,通过日记的形式记录自己一天干了啥,而不是傻傻的一天发呆就这样过去了,最近看了同事的博客,看了以前和他一起刚入公司时,他的一些学习历程,当时心里就很不是滋味,看看人家在学习的时候,你在干嘛呀,对吧。假装对自己说,还来得及,也许留下的时间不多了,顶多半年吧,半年以后,能否成为一个稍微看起来优秀的程序员嘛,这是一个未知数,不过,我想拼一把,身体里好战好勇的因子告诉我,这是一个挑战,接受它吧。那就接受任务了,希望最后不要不要打了自己的老脸才好。好啦,这就是我第一篇博客简介啦,接下来的每一天就记录学习日报。