您的位置:首页 > 编程语言 > Java开发

MyBatis-动态SQL、关联映射、MyBatis整合Spring

2017-04-22 20:11 579 查看
注:环境使用上篇MyBatis搭建环境

输入输出映射

1、parameterType输入类型
传递POJO包装对象作为查询条件,可以避免更改源代码。
public class UserVo {
// 包含其他的POJO
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
在映射文件xml中,配置:
<!-- 使用包装类型查询 -->
<select id="findUserByUsername" parameterType="cn.demo.pojo.vo.UserVo" resultType="cn.demo.pojo.User">
select * from user where username like
"%"#{user.username}"%"
</select>
接口中添加相应方法:
/**
* 根据用户名查询id
*/
public List<User> findUserByUsername(UserVo uservo);


2、resultType输出类型
如:查询用户总记录数   ( 输出简单类型 )
<!-- 查询用户总记录数 -->
<select id="findUserCount" resultType="Integer">
select count(*) from user
</select>
Mapper接口中添加相应方法

3、resultMap
resultMap可以将查询结果映射为复杂类型的POJO。
如:查询订单表orders的所有数据
<!-- 查询所有 -->
<select id="findAllOrders" resultMap="ordersMap">
select id,user_id,number,createtime,note from orders
</select>
其中user_id可以通过
user_id  as  userId 来映射到POJO中,此时不需要使用resultMap,而是resultType="Orders"。
而使用resultMap时:
<resultMap type="orders" id="ordersMap">		 <!-- 最终映射成POJO -->
<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>

动态SQL

1、if标签
注意字符串类型数据需要进行 判空字符串的校验
2、where标签
3、sql片段,使用时使用include标签,达到sql重用
如果想使用另外的Mapper映射文件配置的sql片段,可以在 include标签的refid 前面加上对应的xml的namespace

<!-- 声明sql片段 -->
<sql id="userFields">
id,username,sex,address
</sql>
<!-- 额外的字段抽取出来 -->
<sql id="userBirthday">
birthday
</sql>
<!-- 根据条件查询用户 -->
<select id="findUserByWhere" parameterType="user" resultType="user">

select <include refid="userFields"/>,<include refid="userBirthday"/> from user

<where>  	<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->
<if test=" sex != null and sex != '' ">
and sex = #{sex}
</if>
<if test=" username != null and username != '' ">
and username like "%"#{username}"%"
</if>
</where>
</select>


4、foreach标签
向sql传递数组或list时,MyBatis使用foreach解析
如:根据多个id查询用户信息
<!-- 根据多个id查询用户 -->
<select id="findUserByIds" parameterType="uservo" resultType="User">
select * from user
<where>
<!-- foreach标签:遍历
parameterType为数组 'Integer[]'时	:collection="array"
parameterType为集合 'list'时		:collection="list"
parameterType为对象				:collection="对象中属性名",此时的parameterType即对象
item: 指遍历到的元素的别名
-->
<foreach collection="ids" item="id" open=" id in (" close=")" separator=",">
#{id}
</foreach>
</where>
</select>


关联映射

1、一对一映射
需求:查询所有订单信息,关联查询下单用户信息

方法1:使用resultType:
定义OrderUser类继承Orders类,添加有关用户信息的字段:
public class OrderUser extends Orders {
private String username;
private String address;
Mapper映射文件中:
<!-- 查询所有订单,关联查询下单用户
一对一关联:方式1 resultType
-->
<select id="findOrderUser" resultType="orderuser">
SELECT
o.id,
o.user_id as userId,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
orders o
LEFT JOIN USER u ON o.user_id = u.id
</select>


定义专门的POJO类作为输出类型,其中定义了sql查询结果集所有的字段。此方法较常用。

方式2:使用resultMap
定义专门的resultMap来映射一对一结果
在Orders类中,添加对用户User类的引用:
private User user;
Mapper映射文件中:
<resultMap type="Orders" id="order_user_map">
<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">
<!-- 配置主键  表示user_id是关联查询对象的唯一标识 -->
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
</association>
</resultMap>
<!-- 一对一关联:方式2 resultMap -->
<select id="findOrderUser" resultMap="order_user_map">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
orders o
LEFT JOIN USER u ON o.user_id = u.id
</select>


2、一对多映射
需求:查询用户信息及其关联的订单信息,此处直接使用resultMap方式
User类中,添加对Orders的引用:
private List<Orders> orders;
Mapper映射文件中:
<resultMap type="user" id="user_orders_map">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="sex" column="sex"/>
<result property="birthday" column="birthday"/>
<result property="address" column="address"/>
<!-- 一对多 -->
<collection property="orders" javaType="list" ofType="orders">
<!-- 配置主键 -->
<id property="id" column="oid"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
<!-- 查询所有用户,关联查询用户下订单信息 -->
<select id="findUserOrders" resultMap="user_orders_map">
SELECT
u.id,
u.username,
u.sex,
u.birthday,
u.address,
o.id oid,
o.number,
o.createtime,
o.note
FROM
USER u
LEFT JOIN orders o ON u.id = o.user_id
</select>


接口中添加相应方法,进行测试。

MyBatis整合Spring

1、SqlSessionFactory对象应该放到spring容器中作为单例存在。
2、传统dao的开发方式中,应该从spring容器中获得sqlsession对象。

3、Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象。

4、数据库的连接以及数据库连接池事务管理都交给spring容器来完成。

整合需要的jar包:
1、spring的jar包

2、Mybatis的jar包

3、Spring+mybatis的整合包。

4、Mysql的数据库驱动jar包。

5、数据库连接池的jar包。

步骤:
1、创建工程
2、导入jar包
3、加入配置文件:
SqlMapConfig.xml、applicationContext.xml、db.properties、log4j.properties
4、Dao的开发( 有两种方式:原始Dao开发 /Mapper代理方式 ):
5、创建POJO类
6、原始Dao开发接口+实现类完成:
dao实现类继承MyBatis内置的SqlSessionDaoSupport类
7、实现Mapper映射文件xml配置
8、spring容器配置Dao实现类
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- MyBatis核心配置 -->
<property name="configLocation" value="classpath:SqlMapConfig.xml" />
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>

<!-- 原始Dao开发 -->
<bean id="userDao" class="cn.test.mybatis.dao.impl.UserDao">
<!-- 将sqlSessionFactory注入 -->
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
9、使用junit测试:
@Test
public void testFindUserByUsername() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserDao userDao = (IUserDao) ac.getBean("userDao");
List<User> list = userDao.findUserByUsername("张");
for (User user : list) {
System.err.println(user);
}
}


1-5同上,
6、Mapper代理形式开发Dao
7、配置Mapper映射文件

8、实现Mapper接口
9、方式一:配置Mapper代理:
<!-- 方式1:配置Mapper代理 -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!-- 配置Mapper接口 -->
<property name="mapperInterface" value="cn.test.mybatis.Mapper.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
10、方式二:扫描包形式配置Mapper:
<!-- 方式2:扫描包形式配置Mapper
扫描包及子包接口和映射文件,此时每个mapper对象代理的id为类名,首字母小写
前提条件:Mapper接口类和Mapper映射文件同包同名
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置接口所在包 -->
<property name="basePackage" value="cn.test.mybatis.Mapper" />
</bean>

MyBatis逆向工程

官方网站的Mapper自动生成工具mybatis-generator-core来生成POJO类和Mapper映射。
1、导入逆向工程
2、修改配置文件
数据库连接信息
修改要生成的数据库表
POJO类所在包路径
Mapper所在包路径
3、执行工程main主函数,以生成的Mapper接口,通过Mapper代理测试即可。

注:
逆向工程生成的代码只能做单表查询。
不能在生成的代码上进行扩展( 数据库变更导致 ),因为如果数据库变更,需要重新使用逆向工程生成代码,原有代码
被覆盖。
一张表会生成四个文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息