配置文件之resultMap标签
当实体类对象和数据库表字段不一致时
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
mysql> desc user;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(32) | NO | | NULL | |
| birthday | datetime | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| address | varchar(256) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
5 rows in set (0.07 sec)
调整后的测试代码:
package com.scott;
import com.mysql.cj.Session;
import com.scott.dao.UserDao;
import com.scott.domain.QueryVo;
import com.scott.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
/**
* @ClassName: MybatisTest
* @description:
* @date: 2020/6/22 12:08 PM
* @author: Scott
* @version: 1.0
*/
public class MybatisTest {
private InputStream is;
private SqlSession session;
private UserDao userDao;
/**
* 注意:并非你写了init方法它就会自动执行,而是看上面的注解
* 而且,这里的Before After注解的方法都要为public才行
* @throws IOException
*/
@Before
public void init() throws IOException {
is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
session = factory.openSession();
userDao = session.getMapper(UserDao.class);
}
@After
public void destroy() throws IOException {
//提交事务
session.commit();
//释放资源
session.close();
is.close();
}
/**
* test findAll()
*/
@Test
public void testFindAll() throws IOException {
List<User> users = userDao.findAll();
for (User u : users) {
System.out.println(u);
}
}
/**
* 测试保存用户
* @throws IOException
*/
@Test
public void testSaveUser() throws IOException {
User user = new User();
user.setUserName("山本武大郎 测试获取插入后的id");
user.setUserSex("M");
user.setUserBirthday(new Date());
user.setUserAddress("北京三文鱼海鲜市场");
System.out.println("保存操作之前:"+user);
userDao.saveUser(user);
System.out.println("保存操作之后:"+user);
}
/**
* 测试更新用户
* @throws IOException
*/
@Test
public void testUpdateUser() throws IOException {
User user = new User();
user.setUserId(52);
user.setUserName("毛利小武郎");
user.setUserSex("W");
user.setUserBirthday(new Date());
user.setUserAddress("北京三文鱼海鲜市场");
userDao.updateUser(user);
}
/**
* 测试删除用户
* @throws IOException
*/
@Test
public void testDeleteUser() throws IOException {
userDao.deleteUser(52);
}
/**
* 测试根据id查询用户
* @throws IOException
*/
@Test
public void testFindUserById() throws IOException {
User user = userDao.findById(50);
System.out.println(user);
}
/**
* 测试更具username模糊查询用户
* @throws IOException
*/
@Test
public void testFindUsersByName() throws IOException {
List<User> users = userDao.findByName("%王%");
for (User u: users) {
System.out.println(u);
}
}
/**
* 测试根据username模糊查询用户
* @throws IOException
*/
@Test
public void testFindUsersByName1() throws IOException {
List<User> users = userDao.findByName1("王");
for (User u: users) {
System.out.println(u);
}
}
/**
* 测试查询有多少用户
* @throws IOException
*/
@Test
public void testFindUsers() throws IOException {
int count = userDao.findUsers();
System.out.println(count);
}
/**
* 测试通过username模糊查询用户
* 把实体类再包装一层,在实际开发中被广泛使用,由多个对象组成一个查询条件来实现数据的查询
* @throws IOException
*/
@Test
public void testFindUsersByVo() throws IOException {
QueryVo vo = new QueryVo();
User u = new User();
u.setUserName("%王%");
vo.setUser(u);
List<User> users = userDao.findByQueryVo(vo);
for (User user: users) {
System.out.println(user);
}
}
}
我们先来运行testFindAll()
:
User{userId=null, userName='老王', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='小二王', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='小二王', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='传智播客', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='小马宝莉', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='山本武大郎', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='山本武大郎 测试获取插入后的id', userBirthday=null, userSex='null', userAddress='null'}
可以发现除了username有值,其他字段都没封装到实体类中
原因是表字段和实体类属性对不上,那我们就手动指定让它对的上
修改配置文件:
<select id="findAll" resultType="com.scott.domain.User">
select id as userId, username as userName,birthday as userBirthday, sex as userSex, address as userAddress from user
</select>
再运行,发现已经没什么问题了
User{userId=41, userName='老王', userBirthday=Wed Feb 28 07:47:08 CST 2018, userSex='男', userAddress='北京'}
User{userId=42, userName='小二王', userBirthday=Sat Mar 03 05:09:37 CST 2018, userSex='女', userAddress='北京金燕龙'}
User{userId=43, userName='小二王', userBirthday=Mon Mar 05 01:34:34 CST 2018, userSex='女', userAddress='北京金燕龙'}
User{userId=45, userName='传智播客', userBirthday=Mon Mar 05 02:04:06 CST 2018, userSex='男', userAddress='北京金燕龙'}
但是这种写法虽然是解析最快的但是很费劲,有没有简便的方法呢?
<!--配置 查询结果的列名和实体类的属性名的对应关系-->
<resultMap id="userMap" type="com.scott.domain.User">
<!--主键字段的对应-->
<id property="userId" column="id"></id>
<!--非主键字段的对应-->
<result property="userName" column="username"></result>
<result property="userBirthday" column="birthday"></result>
<result property="userSex" column="sex"></result>
<result property="userAddress" column="address"></result>
</resultMap>
<!--配置查询所有-->
<!--id不能乱写,是接口的方法名-->
<!--resultType告诉mabatis把结果封装到哪里去-->
<select id="findAll" resultMap="userMap">
select * from user
</select>
再运行,发现OK