1. 查询
除了单条记录的查询,这里我们来尝试查询一组记录。
IUserMapper接口添加下面方法:
1
|
List<User> getUsers(String name);
|
在User.xml中添加:
1
2
3
4
5
6
7
8
9
10
|
< resultMap type = "User" id = "userList" > <!-- type为返回列表元素的类全名或别名 -->
< id column = "id" property = "id" />
< result column = "name" property = "name" />
< result column = "age" property = "age" />
< result column = "address" property = "address" />
</ resultMap >
< select id = "getUsers" parameterType = "string" resultMap = "userList" > <!-- resultMap为上面定义的User列表 -->
select * from `user` where name like #{name}
</ select >
|
测试方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Test
public void queryListTest() {
SqlSession session = sqlSessionFactory.openSession();
try {
IUserMapper mapper = session.getMapper(IUserMapper. class );
List<User> users = mapper.getUsers( "%a%" ); // %在sql里代表任意个字符。
for (User user : users) {
log.info( "{}: {}" , user.getName(), user.getAddress());
}
} finally {
session.close();
}
}
|
如果联表查询,返回的是复合对象,需要用association关键字来处理。
如User发表Article,每个用户可以发表多个Article,他们之间是一对多的关系。
(1) 创建Article表,并插入测试数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
-- Drop the table if exists
DROP TABLE IF EXISTS `Article`;
-- Create a table named 'Article'
CREATE TABLE `Article` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int NOT NULL ,
`title` varchar (100) NOT NULL ,
`content` text NOT NULL ,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- Add several test records
INSERT INTO `article`
VALUES
( '1' , '1' , 'title1' , 'content1' ),
( '2' , '1' , 'title2' , 'content2' ),
( '3' , '1' , 'title3' , 'content3' ),
( '4' , '1' , 'title4' , 'content4' );
|
(2) com.john.hbatis.model.Article类:
1
2
3
4
5
6
7
|
public class Article {
private int id;
private User user;
private String title;
private String content;
// Getters and setters are omitted
}
|
(3) 在IUserMapper中添加:
1
|
List<Article> getArticlesByUserId( int id);
|
(4) 在User.xml中添加:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
< resultMap type = "com.john.hbatis.model.Article" id = "articleList" >
< id column = "a_id" property = "id" />
< result column = "title" property = "title" />
< result column = "content" property = "content" />
< association property = "user" javaType = "User" > <!-- user属性映射到User类 -->
< id column = "id" property = "id" />
< result column = "name" property = "name" />
< result column = "address" property = "address" />
</ association >
</ resultMap >
< select id = "getArticlesByUserId" parameterType = "int" resultMap = "articleList" >
select u.id, u.name, u.age, u.address, a.id a_id, a.title, a.content
from article a
inner join user u
on a.user_id=u.id and u.id=#{id}
</ select >
|
(5)测试方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Test
public void getArticlesByUserIdTest() {
SqlSession session = sqlSessionFactory.openSession();
try {
IUserMapper mapper = session.getMapper(IUserMapper. class );
List<Article> articles = mapper.getArticlesByUserId( 1 );
for (Article article : articles) {
log.info( "{} - {}, author: {}" , article.getTitle(), article.getContent(), article.getUser().getName());
}
} finally {
session.close();
}
}
|
附:
除了在association标签内定义字段和属性的映射外,还可以重用User的resultMap:
1
|
< association property = "user" javaType = "User" resultMap = "userList" />
|
2. 新增
IUserMapper接口添加下面方法:
int addUser(User user);
User.xml添加:
1
2
3
|
< insert id = "addUser" parameterType = "User" useGeneratedKeys = "true" keyProperty = "id" > <!-- useGeneratedKeys指定myBatis使用数据库自动生成的主键,并填充到keyProperty指定的属性上。如果未指定,返回对象拿不到生成的值 -->
insert into user(name,age,address) values(#{name},#{age},#{address})
</ insert >
|
测试方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Test
public void addUserTest() {
User user = new User( "Lucy" , 102 , "Happy District" );
SqlSession session = sqlSessionFactory.openSession();
try {
IUserMapper mapper = session.getMapper(IUserMapper. class );
int affectedCount = mapper.addUser(user);
session.commit(); // 默认为不自动提交。调用session.getConnection().getAutoCommit()查看
log.info( "{} new record was inserted successfully whose id: {}" , affectedCount, user.getId());
} finally {
session.close();
}
}
|
3. 更新
接口添加方法:
1
|
int updateUser(User user);
|
User.xml添加:
1
2
3
4
|
< update id = "updateUser" parameterType = "User" >
update `user` set name=#{name}, age=#{age}, address=#{address}
where id=#{id}
</ update >
|
测试方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@Test
public void updateUserTest() {
SqlSession session = sqlSessionFactory.openSession();
try {
IUserMapper mapper = session.getMapper(IUserMapper. class );
User user = mapper.getUserById( 8 );
user.setAddress( "Satisfied District" );
int affectedCount = mapper.updateUser(user); // 除了要修改的属性外,user的其它属性也要赋值,否则这些属性会被数据库更新为初始值(null或0等),可以先查询一次,但这样会增加和数据库不必要的交互。后面的条件判断能避免此问题。
log.info( "Affected count: {}" , affectedCount);
session.commit();
} finally {
session.close();
}
}
|
4. 删除
接口添加方法:
1
|
int deleteUser( int id);
|
User.xml添加:
1
2
3
|
< delete id = "deleteUser" parameterType = "int" >
delete from `user` where id=#{id}
</ delete >
|
测试方法:
1
2
3
4
5
6
7
8
9
10
11
12
|
@Test
public void deleteUserTest() {
SqlSession session = sqlSessionFactory.openSession();
try {
IUserMapper mapper = session.getMapper(IUserMapper. class );
int affectedCount = mapper.deleteUser( 8 );
log.info( "Affected count: {}" , affectedCount);
session.commit();
} finally {
session.close();
}
}
|