接着上一篇《javaweb实战之商城项目开发(二)》这一篇主要实现通用的BaseDao.java和使用resultMap映射关联对象
一.通用的BaseDao.java
既然要大家都能用,所以使用了泛型.其中要注意的问题就是类似User.getClass().getName()这样的代码是需要修改的.修改方法就是使用参数Class tc传递过来,然后在使用tc.getName()即可.
完整代码:
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
|
package com.dao;
import com.model.Pager;
import com.util.SessionUtil;
import com.util.SystemContext;
import org.apache.ibatis.session.SqlSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by nl101 on 2016/2/23.
*/
public class BaseDao<T> {
/**
* 根据id取出一个T类型
* @param id 要取出T类型的id
* @return
*/
public T load(Class<T> tc, int id){
SqlSession session = SessionUtil.getSession();
T t = null ;
try {
t = session.selectOne(tc.getName()+ ".load" ,id);
} finally {
SessionUtil.closeSession(session);
}
return t;
}
/**
* 添加一个T类型
* @param t 要添加的T类型
* @return true成功
*/
public boolean add(T t){
int isAdd = 0 ;
SqlSession session = SessionUtil.getSession();
try {
isAdd = session.insert(t.getClass().getName()+ ".add" ,t);
session.commit(); //提交
} catch (Exception e) {
session.rollback(); //提交失败则回滚
} finally {
SessionUtil.closeSession(session);
}
return isAdd> 0 ;
}
/**
*根据id删除T类型
* @param id 要删除T的id
* @return true成功
*/
public boolean delete(Class<T> t, int id){
int isDelete = 0 ;
SqlSession session = SessionUtil.getSession();
try {
isDelete = session.delete(t.getName()+ ".delete" ,id);
session.commit();
} catch (Exception e) {
session.rollback(); //失败返回
System.out.println( "删除用户失败" );
e.printStackTrace();
} finally {
SessionUtil.closeSession(session);
}
return isDelete> 0 ;
}
/**
*更新T类型
* @param t 要更新的用户
* @return true成功
*/
public boolean update(T t){
int isUpdate = 0 ;
SqlSession session = SessionUtil.getSession();
try {
isUpdate = session.delete(t.getClass().getName()+ ".update" ,t);
session.commit();
} catch (Exception e) {
session.rollback(); //失败返回
System.out.println( "更新用户失败" );
e.printStackTrace();
} finally {
SessionUtil.closeSession(session);
}
return isUpdate> 0 ;
}
/**
* 根据指定条件分页查询
* @param maps 指定条件集合
* @return
*/
public Pager<T> find(Class<T> t,Map<String,Object> maps){
int pageStart = SystemContext.getPageStart(); //分页起始
int pageSize = SystemContext.getPageSize(); //分页大小
Pager<T> pagers = new Pager<>();
maps.put( "pageStart" ,pageStart);
maps.put( "pageSize" ,pageSize);
SqlSession session = SessionUtil.getSession();
List<T> datas = null ;
try {
datas = session.selectList(t.getName()+ ".find" ,maps); //获取记录
pagers.setDatas(datas);
pagers.setPageSize(pageSize);
pagers.setPageStart(pageStart);
int totalRecord = session.selectOne(t.getName()+ ".findcount" ,maps); //获取记录总数
pagers.setTotalRecord(totalRecord);
pagers.setPageIndex(pageStart/pageSize+ 1 );
} finally {
SessionUtil.closeSession(session);
}
return pagers;
}
/**
* 根据指定条件取出部分数据
* @param maps 指定条件集合
* @return
*/
public Pager<T> list(Class<T> t,Map<String,Object> maps){
Pager<T> pagers = new Pager<>();
SqlSession session = SessionUtil.getSession();
List<T> datas = null ;
try {
datas = session.selectList(t.getName()+ ".list" ,maps); //获取记录
pagers.setDatas(datas);
pagers.setTotalRecord(datas.size());
} finally {
SessionUtil.closeSession(session);
}
return pagers;
}
}
|
同样的UserDao.java也需要相应的修改
1
2
3
4
5
6
7
8
9
10
11
12
|
public class UserDao extends BaseDao<User>{
/**
* 根据id取出一个用户
* @param id 要取出用户的id
* @return
*/
public User load( int id){
return super .load(User. class ,id);
}
/* 其他函数就不一一贴出来了,都是类似的写法*/
}
|
二.resultMap的映射
简单来说当数据库中的字段信息和对象的属性不一致时需要通过resultMap来映射.
举个例子:Address属性中有一个User的实体类,如下
1
2
3
4
5
6
7
8
9
|
public class Address {
private int id;
private String name;
private String phone;
private String postcode;
//直接给user对象,来代替user_id
private User user;
`````````
}
|
那么我们想取出来一个Address的同时也取出其对应的user,然而这是两个对象,且两者都有id属性,所以对于mybatis在调用set方法设置属性时就会混乱而使用resultMap的目的就是消除这种混乱.
编写load的sql
1
2
3
4
5
6
|
<! --加载一个地址-->
<! --这里需要表连接,取出User,又连接保证取出的地址不为空,并且为重复属性id取别名-->
< select id= "load" parameterType= "int" resultMap= "addressMap" >
select *,t1.id AS 'a_id' from address t1 RIGHT JOIN user t2 ON
(t1.user_id = t2.id) WHERE t1.id=#{id};
</ select >
|
这里就使用的resultMap来映射,这个resultMap的名字叫做addressMap.
addressMap
1
2
3
4
5
6
7
8
9
10
11
12
|
<resultMap id= "addressMap" type= "Address" autoMapping= "true" >
<!--把结果中的a_id映射为id,其他的autoMapping = true 会自动匹配-->
<id column= "a_id" property= "id" />
<!--取出关联属性-->
<association property= "user" javaType= "User" >
<!--把user_id映射为user的id-->
<id column= "user_id" property= "id" />
<result column= "username" property= "username" />
<result column= "nickname" property= "nickname" />
<result column= "type" property= "type" />
</association>
</resultMap>
|
- type 代表其类型,不包括关联属性
- autoMapping true表示消除冲突后,剩下的属性会自动匹配
- id和result id 和 result 都映射一个单独列的值到简单数据类型,不同是 id 表示的结果将是当比较对象实例时用到的标识属性,一般是主键
- association 代表关联属性,这里设置的是User,对于关联映射,其里面想要显示的属性必须要手动指定property,不然会无法映射
上面配置完,当搜索出来的时候,mybatis就会自动调用其相应的set方法,把属性设置到实体类中.
测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package com.dao;
import com.model.Address;
public class AddressDao extends BaseDao<Address> {
public static void main(String[] args) {
AddressDao addressDao = new AddressDao();
Address address = addressDao.load( 1 );
System.out.println(address.toString());
}
/**
* 加载一个地址
* @param id 要加载地址的id
* @return 返回要加载的地址,null则加载失败
*/
public Address load( int id){
return super .load(Address. class ,id);
}
}
|
效果图可以看出来,只要是映射的关联属性都取出来了,没映射的都为null
按照这样的想法把其他函数补全
xml代码:
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
|
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
< mapper namespace = "com.model.Address" >
<!--当数据库中的字段信息和对象的属性不一致时需要通过resultMap来映射 -->
< resultMap id = "addressMap" type = "Address" autoMapping = "true" >
<!--把结果中的a_id映射为id,其他的autoMapping = true会自动匹配-->
< id column = "a_id" property = "id" />
<!--取出关联属性-->
< association property = "user" javaType = "User" >
<!--把user_id映射为user的id-->
< id column = "user_id" property = "id" />
< result column = "username" property = "username" />
< result column = "nickname" property = "nickname" />
< result column = "type" property = "type" />
</ association >
</ resultMap >
<!--加载一个地址-->
<!--这里需要表连接,取出User,又连接保证取出的地址不为空,并且为重复属性id取别名-->
< select id = "load" parameterType = "int" resultMap = "addressMap" >
select *,t1.id AS 'a_id' from address t1 RIGHT JOIN user t2 ON (t1.user_id = t2.id) WHERE t1.id=#{id};
</ select >
<!--增加一个地址-->
< insert id = "add" parameterType = "Address" >
insert into address values (null,#{name},#{phone},#{postcode},${user_id})
</ insert >
<!--删除一个地址-->
< delete id = "delete" parameterType = "int" >
DELETE FROM address WHERE id=#{id}
</ delete >
<!--修改一个地址-->
< update id = "update" parameterType = "Address" >
UPDATE address SET name=#{name},phone=#{phone},postcode=#{postcode} where id=#{id}
</ update >
<!--找出指定用户所有的地址-->
< select id = "list" parameterType = "Map" resultMap = "addressMap" >
SELECT *,t1.id AS 'a_id' FROM address t1 RIGHT JOIN user t2 ON (t1.user_id=t2.id) WHERE t1.user_id=#{user_id}
</ select >
</ mapper >
|
java代码:
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
|
package com.dao;
import com.model.Address;
import com.model.Pager;
import java.util.HashMap;
import java.util.Map;
/**
* Created by nl101 on 2016/2/23.
*/
public class AddressDao extends BaseDao<Address> {
public static void main(String[] args) {
AddressDao addressDao = new AddressDao();
Pager<Address> pagers = addressDao.list( 1 );
System.out.println(pagers.getDatas().size());
}
/**
* 加载一个地址
* @param id 要加载地址的id
* @return 返回要加载的地址,null则加载失败
*/
public Address load( int id){
return super .load(Address. class ,id);
}
/**
* 添加一个地址
* @param address 要添加的地址
* @param user_id 要添加的地址对应的user_id
* @return true成功
*/
public boolean add(Address address, int user_id){
UserDao userDao = new UserDao();
if (userDao.load(user_id)== null ){
return false ;
}
return super .add(address);
}
/**
* 删除一个地址
* @param id 要删除地址对应的id
* @return true删除成功
*/
public boolean delete( int id){
return super .delete(Address. class ,id);
}
/**
* 更新一个地址
* @param address 要更新的地址
* @return true更新成功
*/
public boolean update(Address address){
return super .update(address);
}
/**
* 根据用户id取出该用户所有地址
* @param user_id
* @return
*/
public Pager<Address> list( int user_id){
Map<String,Object> maps = new HashMap<>();
maps.put( "user_id" ,user_id);
return super .list(Address. class ,maps);
}
}
|
ADO层按照这样写,就没问题了。
以上就是本文的全部内容,整个javaweb商城项目开发就为大家分享到这,希望对大家的学习有所帮助。