1、parameterType(输入类型)——传递pojo包装对象
开发中通过可以使用pojo传递查询条件。
查询条件可能是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如查询用户信息的时候,将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。
包装对象:Pojo类中的一个属性是另外一个pojo。
需求:根据用户名模糊查询用户信息,查询条件放到QueryVo的user属性中。
总配置文件sqlMapConfig.xml
<configuration>
<properties resource="jdbc.properties"/>
<typeAliases>
<package name="cn.ctgu.mybatis.bean"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="123456" />
dataSource>
environment>
environments>
<mappers>
<package name="cn.ctgu.mybatis.mapper"/>
mappers>
configuration>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
编写QueryVo
public class QueryVo {
// 包含其他的pojo
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
sql语句
SELECT * FROM user WHERE username LIKE '%张%'
UserMapper.xml文件
<mapper namespace="cn.ctgu.mybatis.mapper.UserMapper">
<select id="findUserByQueryVo" parameterType="QueryVo" resultType="cn.ctgu.mybatis.bean.User">
select * from user where username like '%${user.username}%'
select>
mapper>
Mapper接口
package cn.ctgu.mybatis.mapper;
import java.util.List;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
public interface UserMapper {
//用mapper动态代理取代UserDao UserDaoImpl
//须遵循四个原则
//
测试
package cn.ctgu.mybatis.junit;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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.Test;
import cn.ctgu.mybatis.bean.Orders;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
import cn.ctgu.mybatis.mapper.OrderMapper;
import cn.ctgu.mybatis.mapper.UserMapper;
public class MybatisMapperTest {
@Test
public void testMapperQueryVo() throws IOException {
//加载核心配置文件
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);
QueryVo vo=new QueryVo();
User user=new User();
user.setUsername("五");
vo.setUser(user);
Listus=userMapper.findUserByQueryVo(vo);
for(User u:us) {
System.out.println(u);
}
}
}
2、输出类型
需求:查询用户表数据条数
UserMapper.xml
<mapper namespace="cn.ctgu.mybatis.mapper.UserMapper">
<select id="countUser" resultType="Integer">
select count(*) from user
select>
mapper>
UserMapper.java(Mapper接口)
package cn.ctgu.mybatis.mapper;
import java.util.List;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
public interface UserMapper {
//查询数据条数
public Integer countUser();
}
测试方法
package cn.ctgu.mybatis.junit;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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.Test;
import cn.ctgu.mybatis.bean.Orders;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
import cn.ctgu.mybatis.mapper.OrderMapper;
import cn.ctgu.mybatis.mapper.UserMapper;
public class MybatisMapperTest {
@Test
public void testMapperQueryVoCount() throws IOException {
//加载核心配置文件
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 i=userMapper.countUser();
System.out.println(i);
}
}
3、resultMap
resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
需求:查询订单表order的所有数据
Orders.java
package cn.ctgu.mybatis.bean;
import java.io.Serializable;
import java.util.Date;
public class Orders implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//附加用户对象(一对一关联,即一个订单只能对应一个用户)
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number == null ? null : number.trim();
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note == null ? null : note.trim();
}
@Override
public String toString() {
return "Orders [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
+ ", note=" + note + "]";
}
}
当mapper.xml中sql查询列(user_id,即数据库中的字段)和Order类属性(userId)不一致,所以查询结果不能映射到pojo中。
需要定义resultMap,把orderResultMap将sql查询列(user_id)和Order类属性(userId)对应起来
OrderMapper.xml
<mapper namespace="cn.ctgu.mybatis.mapper.OrderMapper">
<resultMap type="Orders" id="orders">
<result column="user_id" property="userId"/>
resultMap>
<select id="selectOrdersList" resultMap="orders">
Select id,user_id,number,createtime,note from orders
select>
mapper>
下面的只做说明(比较清晰)
改造OrderMapper.xml,如下:
<mapper namespace="cn.itcast.mybatis.mapper.OrderMapper">
<resultMap type="order" id="orderResultMap">
<id property="id" column="id" />
<result property="userId" column="user_id" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
resultMap>
<select id="queryOrderAll" resultMap="orderResultMap">
SELECT id, user_id,
number,
createtime, note FROM `order`
select>
mapper>
测试
package cn.ctgu.mybatis.junit;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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.Test;
import cn.ctgu.mybatis.bean.Orders;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
import cn.ctgu.mybatis.mapper.OrderMapper;
import cn.ctgu.mybatis.mapper.UserMapper;
public class MybatisMapperTest {
//查询订单列表
@Test
public void testOrderList() throws IOException {
//加载核心配置文件
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);
ListorderList=orderMapper.selectOrdersList();
for(Orders orders:orderList) {
System.out.println(orders);
}
}
4、动态sql
通过mybatis提供的各种标签方法实现动态拼接sql。
需求:根据性别和名字查询用户
UserMapper.xml
<mapper namespace="cn.ctgu.mybatis.mapper.UserMapper">
<sql id="selector">
select * from user
sql>
<select id="selectUserBySexAndUsername" parameterType="User" resultType="User">
<include refid="selector">include>
<where>
<if test="sex!=null and sex!=''">
and sex=#{sex}
if>
<if test="username!=null and username!=''">
and username=#{username}
if>
where>
select>
mapper>
UserMapper.java
package cn.ctgu.mybatis.mapper;
import java.util.List;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
public interface UserMapper {
//根据性别和名字查询用户
public ListselectUserBySexAndUsername(User user);
}
测试类
package cn.ctgu.mybatis.junit;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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.Test;
import cn.ctgu.mybatis.bean.Orders;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
import cn.ctgu.mybatis.mapper.OrderMapper;
import cn.ctgu.mybatis.mapper.UserMapper;
public class MybatisMapperTest {
//根据性别和名字查询用户
@Test
public void testfindUserBySexAndUsername() throws IOException {
//加载核心配置文件
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);
User user=new User();
user.setSex("1");
// user.setUsername("张小明");
Listusers=userMapper.selectUserBySexAndUsername(user);
for(User user2:users) {
System.out.println(user2);
}
}
}
foreach标签
向sql传递数组或List,mybatis使用foreach解析,如下:
根据多个id查询用户信息
三种方法:1、改造QueryVo 2、数组 3、列表
改造的QueryVo.java
package cn.ctgu.mybatis.bean;
import java.io.Serializable;
import java.util.List;
public class QueryVo implements Serializable{
/**
* 包装类
*/
private static final long serialVersionUID = 1L;
private User user;
ListidsList;
Integer[]ids;
public List getIdsList() {
return idsList;
}
public void setIdsList(List idsList) {
this.idsList = idsList;
}
public Integer[] getIds() {
return ids;
}
public void setIds(Integer[] ids) {
this.ids = ids;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
UserMapper.xml
<mapper namespace="cn.ctgu.mybatis.mapper.UserMapper">
<sql id="selector">
select * from user
sql>
<select id="selectUserByIds" parameterType="QueryVo" resultType="User">
<include refid="selector">include>
<where>
<foreach collection="idsList" item="id" separator="," open="id in(" close=")">
#{id}
foreach>
where>
select>
<select id="selectUserByIds1" parameterType="QueryVo" resultType="User">
<include refid="selector">include>
<where>
<foreach collection="list" item="id" separator="," open="id in(" close=")">
#{id}
foreach>
where>
select>
<select id="selectUserByIds2" parameterType="QueryVo" resultType="User">
<include refid="selector">include>
<where>
<foreach collection="array" item="id" separator="," open="id in(" close=")">
#{id}
foreach>
where>
select>
mapper>
UserMapper.java
package cn.ctgu.mybatis.mapper;
import java.util.List;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
public interface
//根据多个id查询用户信息
public List selectUserByIds2(Integer[] ids);
public List selectUserByIds1(List ids);
public List selectUserByIds(QueryVo vo); //方法三之ListidsList
}
测试类
package cn.ctgu.mybatis.junit;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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.Test;
import cn.ctgu.mybatis.bean.Orders;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
import cn.ctgu.mybatis.mapper.OrderMapper;
import cn.ctgu.mybatis.mapper.UserMapper;
public class MybatisMapperTest {
//多个id查询
@Test
public void testfindUserIDs() throws IOException {
//加载核心配置文件
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);
List ids=new ArrayList<>();
ids.add(16);
ids.add(22);
ids.add(24);
QueryVo vo=new QueryVo();
vo.setIdsList(ids);
Listusers=userMapper.selectUserByIds(vo);
for(User user2:users) {
System.out.println(user2);
}
}
@Test
public void testfindUserIDs1() throws IOException {
//加载核心配置文件
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);
Listids=new ArrayList();
ids.add(16);
ids.add(22);
ids.add(24);
Listusers=userMapper.selectUserByIds1(ids);
for(User user2:users) {
System.out.println(user2);
}
}
//多个id查询
@Test
public void testfindUserIDs2() throws IOException {
//加载核心配置文件
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[] ids=new Integer[3];
ids[0]=22;
ids[1]=16;
ids[2]=24;
Listusers=userMapper.selectUserByIds2(ids);
for(User user2:users) {
System.out.println(user2);
}
}
}
5、关联查询
需求:查询所有订单信息,关联查询下单用户信息。
注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。
方法一:使用resultType
使用resultType,改造订单pojo类,此pojo类中包括了订单信息和用户信息
这样返回对象的时候,mybatis自动把用户信息也注入进来了
改造pojo类
OrderUser类继承Order类后OrderUser类包括了Order类的所有字段,只需要定义用户的信息字段即可,如下图:
UserMapper.xml
在UserMapper.xml添加sql,如下
<select id="queryOrderUser" resultType="orderUser">
SELECT
o.id,
o.user_id
userId,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
`order` o
LEFT JOIN `user` u ON o.user_id = u.id
select>
UserMapper.java
在UserMapper接口添加方法,如下图:
测试方法
在UserMapperTest添加测试方法,如下:
@Test
public void testQueryOrderUser() {
// mybatis和spring整合,整合之后,交给spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 创建Mapper接口的动态代理对象,整合之后,交给spring管理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 使用userMapper执行根据条件查询用户
List list = userMapper.queryOrderUser();
for (OrderUser ou : list) {
System.out.println(ou);
}
// mybatis和spring整合,整合之后,交给spring管理
sqlSession.close();
}
方法二:使用resultMap
使用resultMap,定义专门的resultMap用于映射一对一查询结果。
改造pojo类
在Order类中加入User属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。
Orders.java
package cn.ctgu.mybatis.bean;
import java.io.Serializable;
import java.util.Date;
public class Orders implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//附加用户对象(一对一关联,即一个订单只能对应一个用户)
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number == null ? null : number.trim();
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note == null ? null : note.trim();
}
@Override
public String toString() {
return "Orders [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
+ ", note=" + note + "]";
}
}
OrderMapper.xml
<mapper namespace="cn.ctgu.mybatis.mapper.OrderMapper">
<resultMap type="Orders" id="order">
<result column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<association property="user" javaType="User">
<id column="uId" property="id"/>
<result column="username" property="username">result>
association>
resultMap>
<select id="selectOrders" resultMap="order">
select
o.id,
o.user_id,
o.number,
o.createtime,
u.username
from orders o
left join user u
on o.user_id=u.id
select>
mapper>
下面的只做说明
<resultMap type="order" id="orderUserResultMap">
<id property="id" column="id" />
<result property="userId" column="user_id" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
<association property="user" javaType="user">
<id property="id" column="user_id" />
<result property="username" column="username" />
<result property="address" column="address" />
association>
resultMap>
<select id="queryOrderUserResultMap" resultMap="orderUserResultMap">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
`order` o
LEFT JOIN `user` u ON o.user_id = u.id
select>
OrderMapper.xml
package cn.ctgu.mybatis.mapper;
import java.util.List;
import cn.ctgu.mybatis.bean.Orders;
import cn.ctgu.mybatis.bean.User;
public interface OrderMapper {
//一对一关联查询,以订单为中心关联用户
public ListselectOrders();
}
测试类
package cn.ctgu.mybatis.junit;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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.Test;
import cn.ctgu.mybatis.bean.Orders;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
import cn.ctgu.mybatis.mapper.OrderMapper;
import cn.ctgu.mybatis.mapper.UserMapper;
public class MybatisMapperTest2 {
//一对一关联查询
@Test
public void testOrderList() throws IOException {
//加载核心配置文件
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);
ListselectOrdersList=orderMapper.selectOrders();
for(Orders orders:selectOrdersList) {
System.out.println(orders);
}
}
}
效果
测试效果如下图:
6、一对多查询
案例:查询所有用户信息及用户关联的订单信息。
用户信息和订单信息为一对多关系。
改造pojo类User.java
package cn.ctgu.mybatis.bean;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
private List ordersList;
public List getOrdersList() {
return ordersList;
}
public void setOrderList(List ordersList) {
this.ordersList = ordersList;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
}
}
OrderMapper.xml
<mapper namespace="cn.ctgu.mybatis.mapper.OrderMapper">
<resultMap type="User" id="user">
<result column="user_id" property="id"/>
<result column="username" property="username"/>
<collection property="ordersList" ofType="Orders">
<id column="id" property="id"/>
<result column="number" property="number">result>
collection>
resultMap>
<select id="selectUserList" resultMap="user">
select
o.id,
o.user_id,
o.number,
o.createtime,
u.username
from user u
left join orders o
on o.user_id=u.id
select>
mapper>
下面的只做说明
<resultMap type="user" id="userOrderResultMap">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="birthday" column="birthday" />
<result property="sex" column="sex" />
<result property="address" column="address" />
<collection property="orders" javaType="list" ofType="order">
<id property="id" column="oid" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
collection>
resultMap>
<select id="queryUserOrder" resultMap="userOrderResultMap">
SELECT
u.id,
u.username,
u.birthday,
u.sex,
u.address,
o.id oid,
o.number,
o.createtime,
o.note
FROM
`user` u
LEFT JOIN `order` o ON u.id = o.user_id
select>
OrderMapper.java
package cn.ctgu.mybatis.mapper;
import java.util.List;
import cn.ctgu.mybatis.bean.Orders;
import cn.ctgu.mybatis.bean.User;
public interface OrderMapper {
//一对多关联
public ListselectUserList();
}
测试类
package cn.ctgu.mybatis.junit;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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.Test;
import cn.ctgu.mybatis.bean.Orders;
import cn.ctgu.mybatis.bean.QueryVo;
import cn.ctgu.mybatis.bean.User;
import cn.ctgu.mybatis.mapper.OrderMapper;
import cn.ctgu.mybatis.mapper.UserMapper;
public class MybatisMapperTest2 {
@Test
public void testUserList() throws IOException {
//加载核心配置文件
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);
Listusers=orderMapper.selectUserList();
for(User user:users) {
System.out.println(user);
}
}
}
6、Mybatis整合Spring
6.1 整合思路
1、SqlSessionFactory对象应该放到spring容器中作为单例存在。
2、传统dao的开发方式中,应该从spring容器中获得sqlsession对象。
3、Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象。
4、数据库的连接以及数据库连接池事务管理都交给spring容器来完成。
6.2 整合需要的jar包
1、spring的jar包
2、Mybatis的jar包
3、Spring+mybatis的整合包。
4、Mysql的数据库驱动jar包。
5、数据库连接池的jar包。
jar包位置如下所示:
配置文件
sqlmapConfig.xml
<configuration>
<typeAliases>
<package name="cn.ctgu.mybatis.bean" />
typeAliases>
<mappers>
<package name="com.ctgu.mybatis.mapper"/>
mappers>
configuration>
applicationContext.xml
SqlSessionFactoryBean属于mybatis-spring这个jar包
对于spring来说,mybatis是另外一个架构,需要整合jar包。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:sqlMapConfig.xml"/>
bean>
<bean id="userDao" class="cn.ctgu.mybatis.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
bean>
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
<property name="mapperInterface" value="cn.ctgu.mybatis.mapper.UserMapper"/>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.ctgu.mybatis.mapper"/>
bean>
beans>
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
log4j.properties(输出日志信息的)
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
6.3 Dao开发
两种dao的实现方式:
1、原始dao的开发方式
2、使用Mapper代理形式开发方式
a)直接配置Mapper代理
b)使用扫描包配置Mapper代理
需求:
1.实现根据用户id查询
2.实现根据用户名模糊查询
3.添加用户
创建pojo User.java
package cn.ctgu.mybatis.bean;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
}
}
6.3.1 传统dao的开发方式
原始的DAO开发接口+实现类来完成。
需要dao实现类需要继承SqlsessionDaoSupport类
UserMapper.xml
<mapper namespace="cn.ctgu.mybatis.mapper.UserMapper">
<select id="findUserById" parameterType="Integer" resultType="User">
select * from user where id=#{v}
select>
mapper>
UserMapper.java
package cn.ctgu.mybatis.mapper;
import cn.ctgu.mybatis.bean.User;
public interface UserMapper {
public User findUserById(Integer id);
}
实现UserDaoImpl实现类
编写DAO实现类,实现类必须集成SqlSessionDaoSupport
SqlSessionDaoSupport提供getSqlSession()方法来获取SqlSession
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
@Override
public User findUserById(int id) {
// 获取SqlSession
SqlSession sqlSession = super.getSqlSession();
// 使用SqlSession执行操作
User user = sqlSession.selectOne("queryUserById", id);
// 不要关闭sqlSession
return user;
}
}
测试类
ublic class UserDaoTest {
private ApplicationContext context;
@Before
public void setUp() throws Exception {
this.context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
}
@Test
public void testFindUserById() {
// 获取userDao
UserDao userDao = this.context.getBean(UserDao.class);
User user = userDao.findUserById(1);
System.out.println(user);
}
}
6.3.2 Mapper代理形式开发dao
UserMapper.xml
<mapper namespace="cn.ctgu.mybatis.mapper.UserMapper">
<select id="findUserById" parameterType="Integer" resultType="User">
select * from user where id=#{v}
select>
mapper>
UserMapper.java
package cn.ctgu.mybatis.mapper;
import cn.ctgu.mybatis.bean.User;
public interface UserMapper {
public User findUserById(Integer id);
}
mapper代理方式和mapper扫描方式都已经写入到上面的applicationContext.xml中,参考上面的即可。
测试类
package cn.ctgu.mybatis.junit;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.ctgu.mybatis.bean.User;
import cn.ctgu.mybatis.mapper.UserMapper;
public class JunitTest {
@Test
public void testMapper() {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
// ac.getBean(UserMapper.class);
UserMapper mapper=ac.getBean(UserMapper.class);//扫描版的
// UserMapper mapper=(UserMapper) ac.getBean("userMapper");
User user=mapper.findUserById(10);
System.out.println(user);
}
}
7、逆向工程
使用官方网站的Mapper自动生成工具mybatis-generator-core-1.3.2来生成po类和Mapper映射文件。
7.1 导入逆向工程
7.4 修改配置文件
在generatorConfig.xml中配置Mapper生成的详细信息,如下图:
注意修改以下几点:
1.修改要生成的数据库表
2.pojo文件所在包路径
3.Mapper所在的包路径
配置文件如下:
<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root"
password="123456">
jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
javaTypeResolver>
<javaModelGenerator targetPackage="cn.ctgu.mybatis.bean"
targetProject=".\src">
<property name="enableSubPackages" value="false" />
<property name="trimStrings" value="true" />
javaModelGenerator>
<sqlMapGenerator targetPackage="cn.ctgu.mybatis.mapper"
targetProject=".\src">
<property name="enableSubPackages" value="false" />
sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER"
targetPackage="cn.ctgu.mybatis.mapper"
targetProject=".\src">
<property name="enableSubPackages" value="false" />
javaClientGenerator>
<table schema="" tableName="user">table>
<table schema="" tableName="orders">table>
context>
generatorConfiguration>
7.5 生成逆向工程代码
找到下图所示的java文件,执行工程main主函数,
刷新工程,发现代码生成,如下图:
7.6 测试逆向工程代码
复制生成的代码到mybatis-spring工程,如下图
修改spring配置文件
在applicationContext.xml修改
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:sqlMapConfig.xml"/>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.ctgu.mybatis.mapper"/>
bean>
beans>
7.7 编写测试方法
package cn.ctgu.mybatis.junit;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.ctgu.mybatis.bean.User;
import cn.ctgu.mybatis.bean.UserExample;
import cn.ctgu.mybatis.mapper.UserMapper;
public class JunitTest {
@Test
public void testMapper() {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper=ac.getBean(UserMapper.class);
UserExample example=new UserExample();
String username="明";
example.createCriteria().andSexEqualTo("1").andUsernameLike("%"+username+"%");
example.setOrderByClause("id desc");//设置排序条件
int countByExample=userMapper.countByExample(example);
System.out.println(countByExample);
User user=userMapper.selectByPrimaryKey(10);
System.out.println(user);
Listusers=userMapper.selectByExample(example);
for(User user2:users) {
System.out.println(user2.getId());//查询
}
}
}
注意:
1.逆向工程生成的代码只能做单表查询
2.不能在生成的代码上进行扩展,因为如果数据库变更,需要重新使用逆向工程生成代码,原来编写的代码就被覆盖了。
3.一张表会生成4个文件