注: 关于MyBatis的sql映射文件中的mapper元素的namespace属性
注:以下代码中主要显示sql映射文件中语句,其他环境配置等代码见初始MyBatis-1
1、使用select 完成单条件查询操作
UserMapper.xml
UserMapper.java
/**
* 根据用户名模糊查询用户列表
* @param userName 用户姓名
* @return User列表
* @throws Exception
*/
public List getUserListByUserName(String userName)throws Exception;
2、使用select完成多条件传操作
UserMapper.xml
UserMapper.java
/**
* 查询用户列表(对象入参)
* @param user
* @return
* @throws Exception
*/
public List getUserList(User user)throws Exception;
UserMapper.xml
UserMapper.java
/**
* 查询用户列表(map入参)
* @param user
* @return
* @throws Exception
*/
public List getUserListByMap(Map userMap)throws Exception;
3、使用resultMap完成查询结果的展现
需求: 查询所有用户列表,其中的角色信息要以角色名称(userRoleName)展示,而User表中只有userId属性且与Role(角色表)主外键关系对应。
解决方案:
UserMapper.java不做更改
User.java
添加属性userRoleName
private String userRoleName; //角色名称
public String getUserRoleName() {
return userRoleName;
}
public void setUserRoleName(String userRoleName) {
this.userRoleName = userRoleName;
}
UserMapper.xml
UserMapperTest.java测试类
/**
* 查询用户列表
*/
@Test
public void testGetUserList() {
SqlSession sqlSession = null;
List ulist = null;
try {
sqlSession = MyBatisUtil.createSqlSession();
// 对象入参
User user = new User();
user.setUserName("赵");
user.setUserRole(3);
ulist = sqlSession.getMapper(UserMapper.class).getUserList(user);
for (User u : ulist) {
logger.info("用户编码:"+u.getUserCode()+",用户姓名:"+u.getUserName()+",用户角色:"+u.getUserRoleName()+",用户地址:"+u.getAddress());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
}
讲解:
resultMap元素的属性值和子节点
id属性 唯一标识,此id值用于select元素resultMap属性的引用
type属性 表示该resultMap的映射结果类型
result子节点 用于标识一些简单属性,
result节点的属性:1、column属性表示从数据库中查询的字段名
2、property表示查询出来的字段值赋给实体对象的哪个属性
MyBatis中在对查询进行select映射时的两种方式resultType和resultMap之间的关联与区别
区别:
关联:
在使用MyBatis进行查询映射时,实际上查询出的每个字段信息都放在一个对应的map里面,key对象字段名,value对应相应的值,当select元素提供的返回类型属性为resultType时,MyBatis会将map中的键值对取出赋给resultType所指定的对象的属性(即调用对象属性的setter方法)。
因此,当使用resultType,直接在后台就能接收到相应的对象属性值。由此可看出,其实MyBatis的每个查询映射的返回值类型都是resultMap,只是当提供的返回值类型是resultType时,MyBatis会自动把对应的值赋给指定对象的属性,而当返回值类型为resultMap时,因为map不能很好的表示领域模型,所以需要手动转化为对应的实体对象。( 领域模型:业务对象模型[对象])
注:
1、insert插入操作
UserMapper.java
/**
* 添加用户
* @param user
* @return
*/
public int add(User user)throws Exception;
UserMapper.xml
insert into
smbms_user(userCode,userName,userPassword,gender,birthday,phone,
address,userRole,createdBy,creationDate)
values(#{userCode},#{userName},#{userPassword},#{gender},#{birthday},
#{phone},#{address},#{userRole},#{createdBy},#{creationDate})
2、update更新操作
UserMapper.java
/**
* 修改用户
* @param user
* @return
*/
public int modify(User user)throws Exception;
UserMapper.xml
UPDATE smbms_user set userCode=#{userCode},
userName=#{userName},userPassword=#{userPassword},gender=#{gender},
birthday=#{birthday},phone=#{phone},address=#{address},
userRole=#{userRole},modifyBy=#{modifyBy},modifyDate=#{modifyDate}
WHERE id=#{id}
3、使用@Param注解实现多参数注入
需求: 修改指定用户的个人密码
分析: 可以明确方法传入的参数有两个,用户id和新密码,需要修改列只有一个,所以将条件参数封装为对象不合适,所以此处运用@Param实现多参数传递,代码如下
UserMapper.java
/**
* 为指定用户修改密码
* @param id
* @param pwd
* @return
*/
public int updatePwd(@Param("id")Integer id,@Param("userPassword")String pwd)throws Exception;
UserMapper.xml
update smbms_user set userPassword=#{userPassword}
where id=#{id}
UserMapperTest.java测试类
/**
* 修改密码
*/
@Test
public void testUpdatePwd() {
SqlSession sqlSession = null;
int count = 0;
try {
sqlSession = MyBatisUtil.createSqlSession();
count = sqlSession.getMapper(UserMapper.class).updatePwd(16, "888888");
// int i=2/0; //模拟操作失败
sqlSession.commit(); //提交
} catch (Exception e) {
sqlSession.rollback(); //回滚
e.printStackTrace();
count = 0;
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
logger.debug("updatePwd count---->" + count);
}
讲解:
使用@Param与不使用的区别
若不使用@Param注解,则会报错,报错信息类似于Parameter’参数名’
not found。深入MyBatis源码,MyBatis的参数类型为Map,若使用 @Param注解参数,那么就会记录指定的参数名(@Param后括号内的名称)为key;若参数没有加@Param,那么就会记录"param"+它的序号作为Map的key,故在进行多参数入参时,若没有使用@Param指定参数,那么映射的sql语句中获取不到#{参数名}
,从而报错。
@Param注解参数使用场景
(1)一般情况下,超过4个以上的参数最好封装为对象(特别是常规的增加、修改操作,字段较多的情况)
(2)对于参数固定,推荐使用@Param,原因是此方法较灵活,代码可读性高
注: 当参数为基础数据类型时,不管是多参数入参还是单独一个参 数,都需要使用@Param注解参数
4、delete删除操作
UserMapper.java
/**
* 删除指定用户
* @param id
* @return
*/
public int deleteUserById(@Param("id")Integer id)throws Exception;
UserMapper.xml
delete from smbms_user
where id=#{id}
1、association(一对一):
映射到某个JavaBean的某个复杂类型数据,比如Java类,即JavaBean内部嵌套一个复杂数据类型的属性,这种情况就属于复杂类型的关联。注:association仅处理一对一的关联关系。
属性
注: 在做映射的过程中,要确保所有的列名都是唯一且无歧义的
Demo演示
需求: 根据角色id获取用户列表
User.java添加属性Role对象
private Role role; //角色
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
Role.java
package cn.smbms.pojo;
import java.util.Date;
/**
* 用户角色类
* @author 14062
*
*/
public class Role {
private Integer id; //主键id
private String roleCode; //角色编码
private String roleName; //角色名称
private Integer createdBy; //创建者
private Date creationDate; //创建日期
private Integer modifyBy; //修改者
private Date modifyDate; //修改日期
//省略getter/setter方法
}
UserMapper.java
/**
* 根据roleId查询用户列表
* @param roleId
* @return
*/
public List getUserListByRoleId(@Param("userRole")Integer roleId)throws Exception;
UserMapper.xml
UserMapperTest.java测试类
/**
* 根据角色id获取用户列表
*/
@Test
public void testGetUserListByRoleId() {
SqlSession sqlSession = null;
List list = new ArrayList();
try {
sqlSession = MyBatisUtil.createSqlSession();
list = sqlSession.getMapper(UserMapper.class).getUserListByRoleId(2);
logger.info("符合条件的用户数:" + list.size());
for (User user : list) {
logger.info("用户姓名:" + user.getUserName());
logger.info("用户角色:" + user.getRole().getId());
logger.info("用户角色:" + user.getRole().getRoleName());
logger.info("角色编码:" + user.getRole().getRoleCode());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
}
2、collection(一对多):
作用与association类似,也是映射到JavaBean的某个复杂数据类型的 属性,区别是这个类型是一个集合列表,即JavaBean内部嵌套一个复杂数据类型(集合)属性。
属性
例:
注: 以上代码可以理解为一个属性名为adressList,类型为Address的 集合
Demo演示
需求: 获取指定用户的相关信息和地址列表
分析: 一个用户有多个地址,用户对地址为一对多的关系
User.java添加属性List
地址集合
private List addressList; //用户地址列表
public List getAddressList() {
return addressList;
}
public void setAddressList(List addressList) {
this.addressList = addressList;
}
UserMapper.java
/**
* 获取指定用户的相关信息和地址列表
*/
public List getAddressListByUserId(@Param("id")Integer userId);
UserMapper.xml
UserMapperTest.java
/**
* 根据用户id获取地址列表-测试
*/
@Test
public void testGetAddressListByUserId() {
SqlSession sqlSession = null;
List list = new ArrayList();
try {
sqlSession = MyBatisUtil.createSqlSession();
list = sqlSession.getMapper(UserMapper.class).getAddressListByUserId(2);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
logger.info("用户数量:" + list.size());
if (list.size() > 0) {
for (User u : list) {
logger.info("用户姓名:" + u.getUserName());
logger.info("用户密码:"+u.getUserPassword());
logger.info("--------------地址列表-----------------");
for (Address a : u.getAddressList()) {
logger.info("用户id:"+a.getUserId());
logger.info("联系人:" + a.getContact());
logger.info("地址详情:" + a.getAddressDesc());
logger.info("邮政编码:" + a.getPostCode());
}
}
}
}
mybatis运行时要先通过resources把核心配置文件也就是mybatis.xml文件加载进来,然后通过xmlConfigBulider来解析,解析完成后把结果放入configuration中,并把它作为参数传入到build()方法中,并返回一个defaultSQLSessionFactory。我们再调用openSession()方法,来获取SqlSession,在构建SqlSession的同时还需要transaction和executor用于后续执行操作。 推荐文章MyBatis运行原理