Mybatis学习记录(3)
1.输出映射和输入映射
Mapper.xml映射文件定义了操作数据库的sql,每个sql就是一个statement,映射文件是mybatis的核心。
(1)parameterType(输入类型)
1.传递简单类型
使用占位符#{},或者${}进行sql拼接。
2.传递pojo对象
使用ognl表达式解析对象字段的值,#{}或者${}括号中的值 为pojo属性名称。
3.传递pojo包装对象
开发中可以通过使用pojo传递查询条件,查询的条件可能是综合的查询条件,这时可以使用包装对象传递输入参数。
包装对象:Pojo类中的一个属性是另一个pojo
即新建一个queryInfo类将所需要的查询条件全部声明到此类中,并生成get,set方法。
编写QueryInfo类 UserQueryInfo.java
package com.javaweb.mybatis.model.queryInfo; import java.io.Serializable; import com.javaweb.mybatis.model.User; public class UserQueryInfo implements Serializable{ /**
*
*/
private static final long serialVersionUID = 1L; private User user; public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} }
Mapper.xml配置文件
<!-- 根据用户名模糊查询 -->
<select id="findUserByQueryInfo" parameterType="com.javaweb.mybatis.model.queryInfo.UserQueryInfo" resultType="com.javaweb.mybatis.model.User">
select * from mybatis_user where username like "%${user.userName}%"
</select>
Mapper接口
public interface UserMapper {
/**
* 遵循四个原则
* 1.接口方法名 ==User.xml中的id名
* 2.返回值类型与Mapper.xml的返回值类型一致
* 3.方法的入参类型与Mapper.xml中的入参类型一致
* 4.命名空间绑定此接口,即Mapper.xml的namespace是此接口的路径
*/ public List<User> findUserByQueryInfo(UserQueryInfo queryInfo);
Jubit单元测试类:
@Test
public void testMapperQueryInfo() throws Exception{
//加载核心配置文件
String resource="sqlMapConfig.xml";
InputStream in=Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession=sqlSessionFactory.openSession(); //SqlSession帮我生成一个实现类
UserMapper userMapper=sqlSession.getMapper(UserMapper.class); UserQueryInfo queryInfo =new UserQueryInfo();
User user=new User();
user.setUserName("王");
queryInfo.setUser(user); List<User> userList=userMapper.findUserByQueryInfo(queryInfo);
for(User u:userList){
System.out.println(u);
}
}
2.resultType(输出类型)
(1)输出简单类型
需求查询用户表的数据总条数
Mapper接口:
public interface UserMapper {
/**
* 遵循四个原则
* 1.接口方法名 ==User.xml中的id名
* 2.返回值类型与Mapper.xml的返回值类型一致
* 3.方法的入参类型与Mapper.xml中的入参类型一致
* 4.命名空间绑定此接口,即Mapper.xml的namespace是此接口的路径
*/ //查询数据条数
public Integer countUser();
Mapper.xml配置文件
<!-- 查询数据条数 -->
<select id="countUser" resultType="Integer">
select count(1) from mybatis_user where 1=1 and id=2
</select>
Junit单元测试类:
@Test
public void testMapperCountUserQueryInfo() throws Exception{
//加载核心配置文件
String resource="sqlMapConfig.xml";
InputStream in=Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession=sqlSessionFactory.openSession(); //SqlSession帮我生成一个实现类
UserMapper userMapper=sqlSession.getMapper(UserMapper.class); Integer countUser = userMapper.countUser();
System.out.println(countUser);
}
(2)输出pojo对象
见上一章
(3)输出pojo列表
见上一章
3.resultMap(输出类型)
resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致才能映射成功。
但是如果是sql查询字段名和pojo的属性名不一致,就可以通过resultMap将字段名和属性名手动做一个对应关系,resultMap实质上还需要将查询结果映射到pojo对象中。
resultMap可以实现将映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
示例:查询订单表order中的所有数据
数据库表构造如下:
Order对象order.java
public class Order implements Serializable{ /**
*
*/
private static final long serialVersionUID = 1L; private String id;
private String userId;
private Integer number;
private String note;
private Date createTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "Order [id=" + id + ", userId=" + userId + ", number=" + number + ", note=" + note + ", createTime="
+ createTime + "]";
}
OrderMapper.java接口
/**
* 订单接口
* @author fanyukai
*
*/
public interface OrderMapper { public List<Order> orderList();
}
Mapper.xml配置文件
<mapper namespace="com.javaweb.mybatis.mapper.OrderMapper">
<!-- id:设置resultMap的id -->
<resultMap type="com.javaweb.mybatis.model.Order" id="orders">
<!-- 定义主键 -->
<!-- property:主键在pojo的属性名 -->
<!-- colunm:主键在数据库中的列名 -->
<id property="id" column="id" /> <!-- 定义普通属性 -->
<result column="user_id" property="userId"/>
</resultMap> <!-- 查询所有订单 -->
<select id="orderList" resultMap="orders">
select id,user_id,number,note,createtime from mybatis_orders
</select>
</mapper>
Junit单元测试类:
@Test
public void testMapperOrderList() throws Exception{
//加载核心配置文件
String resource="sqlMapConfig.xml";
InputStream in=Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession=sqlSessionFactory.openSession(); //SqlSession帮我生成一个实现类
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); List<Order> orderList=orderMapper.orderList();
for(Order orders :orderList){
System.out.println(orders);
}
}
3.动态sql
(1)通过mybatis提供的各种标签方法实现动态拼接sql
<sql>和<include>标签
(2)where,if 标签
4.关联查询
一对一关联:一份订单对应一个用户
使用resultMap,定义专门的resultMap用于映射一对一查询结果
sql语句:
select
o.id,
o.user_id,
o.number,
o.note,
o.createtime,
u.id,
u.username
FROM mybatis_orders o
LEFT JOIN mybatis_user u
ON o.user_id=u.id
改造pojo类
public class Order implements Serializable{ /**
*
*/
private static final long serialVersionUID = 1L; private String id;
private String userId;
private Integer number;
private String note;
private Date createTime; //附加对象 用户对象
private User user; public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
/* 后面get,set方法省略*/
Mapper.xml配置文件
<resultMap type="com.javaweb.mybatis.model.Order" id="order">
<!-- 定义普通属性 -->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createTime"/> <!-- 一对一 -->
<association property="user" javaType="com.javaweb.mybatis.model.User" >
<id column="id" property="user_id"/>
<result column="userName" property="userName"/>
</association>
</resultMap> <!-- 一对一关联查询 以订单为中心关联用户 -->
<select id="selectOrder" resultMap="order">
select
o.id,
o.user_id,
o.number,
o.note,
o.createtime,
u.id,
u.username
FROM mybatis_orders o
LEFT JOIN mybatis_user u
ON o.user_id=u.id
</select>
Mapper接口:
public interface OrderMapper { //一对一关联查询 以订单为中心关联用户 public List<Order> selectOrder();
Junit单元测试类:
@Test
public void testMapperOrderOneToOne() throws Exception{
//加载核心配置文件
String resource="sqlMapConfig.xml";
InputStream in=Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession=sqlSessionFactory.openSession(); //SqlSession帮我生成一个实现类
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); List<Order> orderList=orderMapper.selectOrder();
for(Order orders :orderList){
System.out.println(orders);
}
}
一对多关联:一个用户对应多个订单
sql语句
select
o.id,
o.user_id,
o.number,
o.note,
o.createtime,
u.username
FROM mybatis_user u
LEFT JOIN mybatis_orders o
ON o.user_id=u.id
改造pojo类 User.java:
public class User implements Serializable{ /**
* user表的pojo对象
*/
private static final long serialVersionUID = 1L;
private String id;
private String userName;
private String userAge;
private String userSex;
private String userAddress; //附加对象list 一对多
private List<Order> orderList; public List<Order> getOrderList() {
return orderList;
}
public void setOrderList(List<Order> orderList) {
this.orderList = orderList;
}
/*后面get,set方法省略*/
Mapper.xml配置文件:
<!-- 一对多 以用户为中心-->
<resultMap type="com.javaweb.mybatis.model.User" id="user">
<id column="id" property="id"/>
<result column="username" property="userName"/> <!-- 一对多 -->
<collection property="orderList" ofType="com.javaweb.mybatis.model.Order">
<!-- 配置主键,是关联Order的唯一标识 -->
<id column="id" property="id"/>
<result column="number" property="userName"/>
<result column="user_id" property="userId"/>
<result column="note" property="note"/>
<result column="createtime" property="createTime"/>
</collection> </resultMap>
<select id="selectUserList" resultMap="order">
select
o.id,
o.user_id,
o.number,
o.note,
o.createtime,
u.username
FROM mybatis_user u
LEFT JOIN mybatis_orders o
ON o.user_id=u.id
</select>
Mapper接口:
public interface OrderMapper { //一对多关联
public List<User> selectUserList();
}
Junit单元测试类:
@Test
public void testMapperOrderOneToMany() throws Exception{
//加载核心配置文件
String resource="sqlMapConfig.xml";
InputStream in=Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession=sqlSessionFactory.openSession(); //SqlSession帮我生成一个实现类
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); List<User> selectUserList = orderMapper.selectUserList();
for(User user :selectUserList){
System.out.println(user);
}
}
Mybatis学习记录(3)的更多相关文章
- MyBatis 学习记录5 MyBatis的二级缓存
主题 之前学习了一下MyBatis的一级缓存,主要涉及到BaseExecutor这个类. 现在准备学习记录下MyBatis二级缓存. 配置二级缓存与初始化发生的事情 首先二级缓存默认是不开启的,需要自 ...
- MyBatis 学习记录3 MapperMethod类
主题 之前学习了一下MapperProxy的生产过程,自定义Mapper类的对象是通过动态代理生产的,调用自定义方法的时候实际上是调用了MapperMethod的execute方法:mapperMet ...
- MyBatis 学习记录7 一个Bug引发的思考
主题 这次学习MyBatis的主题我想记录一个使用起来可能会遇到,但是没有经验的话很不好解决的BUG,在特定情况下很容易发生. 异常 java.lang.IllegalArgumentExceptio ...
- MyBatis 学习记录6 TypeHandler
主题 因为对MyBatis在JDBC数据和Java对象之间数据转化比较感兴趣,所以就记录并学习一下TypeHandler. 使用场景 如上图所示,观察下接口方法就能明白.TypeHandler主要用于 ...
- MyBatis 学习记录4 MyBatis的一级缓存
主题 分享记录一下MyBatis的一级缓存相关的学习. Demo public static void firstLevelCache() { init("mybatis-config.xm ...
- mybatis 学习记录1
起因 以前刚学习java三大框架的时候持久层框架我是自学的是hibernate..感觉蛮好用的,so easy..后来大三实习公司用的是jpa(hibernate外包装一层)...再后来工作1年多用的 ...
- mybatis学习记录六——一对一、一对多和多对多查询
9 订单商品数据模型 9.1 数据模型分析思路 1.每张表记录的数据内容 分模块对每张表记录的内容进行熟悉,相当 于你学习系统 需求(功能)的过程. 2.每张表重要的字段设置 非空 ...
- Mybatis学习记录(六)----Mybatis的高级映射
1.一对多查询 1.1 需求 查询订单及订单明细的信息. 1.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. SELECT orders. ...
- Mybatis学习记录(五)----Mybatis的动态SQL
1. 什么是动态sql mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 1.1 需求 用户信息综合查询列表和用户信息查询列表总数这两个statemen ...
- MyBatis 学习记录1 一个简单的demo
主题 最近(N个月前)clone了mybatis的源码..感觉相比于spring真的非常小...然后看了看代码觉得写得很精简...感觉我的写代码思路和这个框架比较相似(很难具体描述...就是相对来说比 ...
随机推荐
- elasticsearch学习(三):分布式
es的分布式思想跟现在流行的很多开发技术的分布式一个道理.一个es 搜索服务作为一个集群,集群中存在很多节点,一个节点就是一个搜索服务器.这么多节点中,会按照一定的机制推举出一个 master节点,该 ...
- lca最近公共祖先(st表/倍增)
大体思路 1.求出每个元素在树中的深度 2.用st表预处理的方法处理出f[i][j],f[i][j]表示元素i上方第2^j行对应的祖先是谁 3.将较深的点向上挪,直到两结点的深度相同 4.深度相同后, ...
- jzoj6009. 【THUWC2019模拟2019.1.18】Counting (dp)
Description 羽月最近发现,她发动能力的过程是这样的: 构建一个 V 个点的有向图 G,初始为没有任何边,接下来羽月在脑中构建出一个长度为 E 的边的序列,序列中元素两两不同,然后羽月将这些 ...
- uoj#335. 【清华集训2017】生成树计数(prufer序列+生成函数+多项式)
传送门 好神仙的题目--又一次有了做一题学一堆的美好体验 据说本题有第二类斯特林数+分治\(FFT\)的做法,然而咱实在看不懂写的是啥,题解贴这里,有兴趣的可以自己去瞅瞅,看懂了记得回来跟咱讲讲 前置 ...
- Vue实现任务列表效果
<!DOCTYPE html> <html lang="en"> <head> ...
- 调试接口,返回的json数据,我定义了一个类,用来序列化,其中有一个字段定义为string 然后序列化的时候报错
调试接口,返回的json数据,我定义了一个类,用来序列化,其中有一个字段定义为string 然后序列化的时候报错 在需要解析的类型类上加上声明 eg:
- Centos 7 install cacti监控
首先,先安装LNMP服务 安装一: 如果觉得安装起来麻烦,可以到如下网站进行安装: https://lnmp.org/install.html 安装二: 采用yum或者安装包的方式进行安装,具体操作请 ...
- JavaScript进阶 - 第9章 DOM对象,控制HTML元素
第9章 DOM对象,控制HTML元素 9-1 认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属 ...
- easyui---accordion(手风琴)
首先配置好easyui环境 1.ACCORDION(手风琴) class:class=easyui-accordion, 事件: 查找: function selectPanel(){ //会弹出输入 ...
- php:封装了个时间函数,返回类似“1分钟前发布”,“5小时前发布”,“3年前发布”
处理和时间有关的时候,像发布问题等通常不会用date格式的时间,而是用类似"3分钟前发布"等格式,下面封装的php函数就可以使用: 注意:当有用到strtotime()函数的记得加 ...