参考:【itheima】
[toc]
输入映射和输出映射
每个sql是一个statement
parameterType(输入类型)
传递简单类型
- 参考Mybatis笔记(一)
传递pojo对象
- ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称
传递pojo包装对象
开发中通过pojo传递查询条件,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。
代码
定义别名
xml1
2
3
4
5
6
7<typeAliases>
<!--
使用扫描法 批量定义别名
定义后,别名=类名,不区分大小写,单建议按java命名规则(userMapper)
-->
<package name="com.machine.vo" />
</typeAliases>包装对象
java1
2
3
4
5
6
7
8
9
10
11public class QueryVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}mapper接口
java1
2
3
4
5public interface UserMapper {
public List<User> findUserByQueryVo(QueryVo queryVo) throws Exception;
}mapper映射
xml1
2
3
4
5
6
7
8
9<!--
parameterType:mapper接口中方法名的输入参数:queryVo
public List<User> findUserByQueryVo(QueryVo queryVo)
${user.username}: queryVo类中的属性,使用ognl表达式取值
-->
<select id="findUserByQueryVo" parameterType="queryVo"
resultType="com.machine.po.User" >
SELECT * FROM User WHERE username like '%${user.username}%'
</select>测试代码
java1
2
3
4
5
6QueryVo queryVo = new QueryVo();
User user = new User();
user.setUsername("m");
queryVo.setUser(user);
List<User> userList = userMapper.findUserByQueryVo(queryVo);
resultType(输出类型)
- 输出简单类型
- 输出pojo对象
- 输出pojo列表 List<>
resultMap
resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系,resultMap实质上还需要将查询结果映射到pojo对象中。
代码
Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28<!--
id:resultMap唯一标志
type:最终映射的java对象
-->
<resultMap id="userResultMap" type="user" >
<!--
id:主键
result:普通列
column:sql列名
property:pojo属性名字
-->
<id column="id_" property="id" />
<result column="username_" property="username" />
<result column="sex_" property="sex" />
<result column="birthday_" property="birthday" />
<result column="address_" property="address" />
</resultMap>
<!--此时查询出来的 数据库列名 和pojo名 不对应 需要用resultMap转换-->
<select id="findUserById" parameterType="int" resultMap="userResultMap">
select id id_ ,
username username_ ,
sex sex_ ,
birthday birthday_ ,
address address_
from User
where id = #{id}
</select>测试代码:
Code1
User user = userMapper.findUserById(2);
动态sql
if
mapper接口
1 | public List<User> findUserBySexAndUsername(User user); |
mapper映射
1 | <select id="findUserBySexAndUsername" parameterType="user" resultType="user"> |
测试代码
1 | User user = new User(); |
where
1 | <!--where可以自动处理第一个and--> |
Sql片段(抽取where)
1 | <!-- |
foreach
使用场景
- parameterType传入参数有List
- 需求如: select * from User where username like ‘%m%’ and id in(1,3,5)
代码
Code1
2
3
4
5
6public class QueryVo {
private User user;
private List<Integer> ids;
//setter getter
}Code1
2
3
4
5public interface UserMapper {
public List<User> findUserByQueryVo(QueryVo queryVo) throws Exception;
}Code1
2
3
4
5
6
7
8<select id="findUserByQueryVo" parameterType="queryVo"
resultType="user" >
select * from User
where username like '%${user.username}%'
<foreach collection="ids" open=" and id in(" close=")" separator="," item="id">
#{id}
</foreach>
</select>测试代码
Code1
2
3
4
5
6
7
8
9
10
11
12
13QueryVo queryVo = new QueryVo();
User user = new User();
user.setUsername("m");
queryVo.setUser(user);
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(3);
ids.add(5);
queryVo.setIds(ids);
List<User> userList = userMapper.findUserByQueryVo(queryVo);
关联查询
用户订单模型
一个用户可以下多个订单,一个订单只对应一个用户一对一查询
案例:查询订单信息,关联查询用户信息
方法一:自动映射(定义专门的PO作为输出类型)
sql:
Code1
2
3
4
5
6
7
8SELECT
orders.*,
user.username,
userss.address
FROM
orders,
user
WHERE orders.user_id = user.idpo类:
Code1
2
3
4
5
6public class OrdersCustom extends Orders {
//继承Orders,再添加User属性即可
private String username;// 用户名称
private String address;// 用户地址
//set getMapper.xml:
Code1
2
3
4
5
6
7
8
9
10<!-- 查询所有订单信息 -->
<select id="findOrdersList" resultType="cn.itcast.mybatis.po.OrdersCustom">
SELECT
orders.*,
user.username,
user.address
FROM
orders,user
WHERE orders.user_id = user.id
</select>Mapper接口:
Code1
public List<OrdersCustom> findOrdersList() throws Exception;
测试:
Code1
List<OrdersCustom> list = userMapper.findOrdersList();
方法二:手动映射(在Orders类里包含User类)
Code1
2
3
4
5
6public class Orders {
private int id;
private String createTime;
private String state;
private User user;Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39<!-- 查询订单关联用户信息使用resultmap -->
<resultMap type="com.machine.po.Orders" id="orderUserResultMap">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!--
一对一关联映射
association:表示进行关联查询单条记录
-->
<!--
property:Orders对象的user属性
javaType:user属性对应 的类型
-->
<association property="user" javaType="com.machine.po.User">
<!--
column:user表的主键对应的列
property:user对象中id属性
-->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findOrdersWithUserResultMap" resultMap="orderUserResultMap">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
orders o
JOIN `user` u ON u.id = o.user_id
</select>
一对多查询
查询用户信息及 关联的订单信息
代码
pojo
Code1
2
3
4
5
6
7
8
9
10public class User {
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
private List<Orders> ordersList;
//set getmapper.xml
xml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<resultMap id="userOrdersRM" type="user">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<result column="address" property="address"/>
<!--
一对多映射关系
property: User类中对应集合 属性名
ofType:集合的类型 此处使用别名
-->
<collection property="ordersList" ofType="orders">
<id column="orderId" property="id" />
<result column="createTime" property="createTime"/>
<result column="state" property="state"/>
</collection>
</resultMap>
<select id="findUserOrders" resultMap="userOrdersRM">
select u.* ,
o.id orderId,
o.create_time createTime,
o.state
from user u
LEFT JOIN orders o ON u.id = o.user_id
</select>接口
Code1
public List<User> findUserOrders();
测试:
Code1
List<User> userOrdersList = userMapper.findUserOrders();
Mybatis整合Spring
整合思路
- SqlSessionFactory对象应该放到spring容器中作为单例存在。
- 传统dao的开发方式中,应该从spring容器中获得sqlsession对象。
- Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象。
- 数据库的连接以及数据库连接池事务管理都交给spring容器来完成。
整合需要的jar包
- spring的jar包
- Mybatis的jar包
- Spring+mybatis的整合包。
- Mysql的数据库驱动jar包。
- 数据库连接池的jar包。
整合的步骤
第一步:创建一个java工程。
第二步:导入jar包。(上面提到的jar包)
第三步:mybatis的配置文件sqlmapConfig.xml
第四步:编写Spring的配置文件
1、数据库连接及连接池
2、事务管理(暂时可以不配置)
3、sqlsessionFactory对象,配置到spring容器中
4、mapeer代理对象或者是dao实现类配置到spring容器中。
第五步:编写dao或者mapper文件
第六步:测试。SqlMapConfig.xml
1 | <?xml version="1.0" encoding="UTF-8" ?> |
applicationContext.xml
1 | <?xml version="1.0" encoding="UTF-8"?> |
db.properties
Dao的开发
传统Daok开发方式(不重要)
接口+实现类来完成。需要dao实现类需要继承SqlsessionDaoSupport类
1 | public interface UserDao { |
1 | public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao { |
1 | <!--传统DAO开发,需要给支持类(父类) 注入sqlSessionFactory--> |
1 | <mapper namespace="user"> |
1 | <mappers> |
测试:
1 |
|
Mapper代理形式开发Dao(不重要)
1 | <!-- 配置mapper代理对象 --> |
扫描包的形式配置mapper(推荐)
mybatis mapper开发规范:见Mybatis笔记(一)
- namespace
- 方法名=id名
- …
配置
Code1
2
3
4
5
6
7<!--
使用扫描包 的形式 创建mapper代理对象
遵守规范:UserMapper.java 和UserMapper放在同一个mapper包下
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.machine.ms.mapper"/>
</bean>以上配置后,不需要以下配置
Code1
2
3
4<mappers>
<!--扫描包-->
<package name="com.machine.ms.mapper" />
</mappers>代码总结
SqlMapConfig.xml
Code1
2
3
4
5
6
7
8
9
10
11<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<!--扫描包,配置别名-->
<package name="com.machine.ms.po"/>
</typeAliases>
</configuration>applicationContext.xml
Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
<!--加载配置文件-->
<context:property-placeholder location="classpath:db.properties" />
<!--数据库连接池-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--Spring管理sqlSessionFactory,使用mybatis-spring整合包-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--数据库连接池-->
<property name="dataSource" ref="dataSource"/>
<!--加载mybatis全局配置文件-->
<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"/>
</bean>
<!--使用扫描包 的形式 创建mapper代理对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.machine.ms.mapper"/>
</bean>
</beans>UserMapper.xml
Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.machine.ms.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="user">
SELECT * FROM user where id = #{id}
</select>
<insert id="insertUser" parameterType="user" >
INSERT INTO user(username,birthday,sex,address)
VALUES(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>UserMapper.java
Code1
2
3
4public interface UserMapper {
public User findUserById(int id);
public void InsertUser(User user);
}测试:
Code1
2
3
4
5
6
7
8
9
10
11
12@Test
public void test2(){
ApplicationContext context =
new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
//Spring返回mapper代理对象
UserMapper userMapper = context.getBean(UserMapper.class);
User user = userMapper.findUserById(2);
System.out.println(user);
}




