1 复习引言
mybatis是一个持久层框架,是apache下的开源项目,前身是itbatis,是一个不完全的ORM框架,mybatis提供输入和输出的映射,需要程序员自己写sql语句,mybatis重点对sql语句的灵活操作。适合用于:需求变化频繁, 数据模型不固定的项目。
mybatis架构
SqlMapConfig.xml(名称不固定),配置内容:数据源、事务、properties、typeAliases、settings、mapper配置。
SqlSessionFactory--会话工厂,作用是创建SqlSession,实际开发中以单例模式管理 SqlSessionFactory。
SqlSession--会话,是一个面向用户(程序员)的接口,使用mapper代理方法开发是不需要程序员直接调用sqlSession的方法。是线程不安全,最佳适用场合方法体内。
mybatis开发dao的方法:
1、原始dao开发方法,需要程序员编写dao接口和实现类,此方法在当前企业中还有使用,因为ibatis使用的就是原始dao开发方法。
2、mapper代理方法,程序员只需要写mapper接口(相当于dao接口),mybatis自动根据mapper接口和mapper接口对应的statement自动生成代理对象(接口实现类对象)。
开发需要遵循规则:
1)mapper.xml中namespace是mapper接口的全限定名
2)mapper.xml中statement的id为mapper接口方法名
3)mapper.xml中statement的输入映射类型(parameterType)和mapper接口方法输入参数类型一致
4) mapper.xml中statement的输出映射类型(resultType)和mapper接口方法返回结果类型一致
resultType和resultMap都可以完成输出映射:
resultType映射要求sql查询的列名和输出映射pojo类型的属性名一致
resultMap映射时对sql查询的列名和输出映射pojo类型的属性名作一个对应关系。
动态sql:
#{}和${}完成输入参数的属性值获取,通过OGNL获取parameterType指定pojo的属性名。
#{}:占位符号,好处防止sql注入
${}:sql拼接符号
if
where
foreach
热身:跟我提供的1-5章的sql文件建立数据表,先建立数据表 sql_table.sql ,再导入数据sql_data.sql
数据表分析
分析表与表之间的关系:
用户user和订单orders:
user---->orders:一个用户可以创建多个订单 一对多
orders-->user:一个订单只能由一个用户创建 一对一
订单orders和订单明细orderdetail:
orders-->orderdetail:一个订单可以包括多个订单明细 一对多
orderdetail-->orders:一个订单明细只属于一个订单 一对一
订单明细orderdetail和商品信息items:
orderdetail-->items:一个订单明细对应一个商品信息 一对一
items--> orderdetail:一个商品对应多个订单明细 一对多
2、一对一查询(resultType实现)
OrdersCustomMapper编写
package com.ycy.mybatis.dao; import com.ycy.mybatis.module.Orders; import com.ycy.mybatis.module.OrdersCustom; import java.util.List; /** * Created by Administrator on 2015/9/9 0009. */ public interface OrdersCustomMapper { public List<OrdersCustom> findOrderCustomer() throws Exception; }
OrdersCustomMapper.xml编写
<?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"> <!--命名空间:分类管理sql隔离,方便管理--> <mapper namespace="com.ycy.mybatis.dao.OrdersCustomMapper"> <select id="findOrderCustomer" resultType="OrdersCustom"> SELECT o.*, u.username, u.address FROM orders o, USER u WHERE o.user_id = u.id </select> </mapper>OrdersCustomMapper测试编写
package com.ycy.mybatis.test; import com.ycy.mybatis.dao.OrdersCustomMapper; import com.ycy.mybatis.dao.UserMapper; import com.ycy.mybatis.module.OrdersCustom; import com.ycy.mybatis.module.User; 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.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; /** * Created by Administrator on 2015/8/31 0031. */ public class MybatisTest6 { private SqlSessionFactory sqlSessionFactory = null; @Before public void before() throws IOException { String resource="SqlMapConfig.xml"; InputStream in = Resources.getResourceAsStream(resource); sqlSessionFactory= new SqlSessionFactoryBuilder().build(in); } @Test public void findOrderCustomer() throws Exception { SqlSession sqlSession=sqlSessionFactory.openSession(); OrdersCustomMapper ordersCustomMapper= sqlSession.getMapper(OrdersCustomMapper.class); List<OrdersCustom> ordersCustoms= ordersCustomMapper.findOrderCustomer(); sqlSession.close(); for (OrdersCustom ordersCustom : ordersCustoms) { System.out.println(ordersCustom.getUsername()); } } }
2、一对一查询(resultMap实现)
<pre name="code" class="html">public class Orders { private Integer id; private Integer userId; private String number; private Date createtime; private String note; //用户信息 private User user; //getset 省略 篇幅问题 }
OrdersCustomMapper.xml
<?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"> <!--命名空间:分类管理sql隔离,方便管理--> <mapper namespace="com.ycy.mybatis.dao.OrdersCustomMapper"> <resultMap id="orderResultMap" type="orders"> <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="user" javaType="user"> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="address" property="address"/> </association> </resultMap> <!--resultType进行查询--> <select id="findOrderCustomer" resultType="OrdersCustom"> SELECT o.*, u.username, u.address FROM orders o, USER u WHERE o.user_id = u.id </select> <!--使用resultmap进行查询--> <select id="findOrderResultMap" resultMap="orderResultMap"> SELECT o.*, u.username, u.address FROM orders o, USER u WHERE o.user_id = u.id </select> </mapper>
OrdersCustomMapper.java
package com.ycy.mybatis.dao; import com.ycy.mybatis.module.Orders; import com.ycy.mybatis.module.OrdersCustom; import java.util.List; /** * Created by Administrator on 2015/9/9 0009. */ public interface OrdersCustomMapper { public List<OrdersCustom> findOrderCustomer() throws Exception; public List<Orders> findOrderResultMap() throws Exception; }
测试:MybatisTest6
package com.ycy.mybatis.test; import com.ycy.mybatis.dao.OrdersCustomMapper; import com.ycy.mybatis.dao.UserMapper; import com.ycy.mybatis.module.Orders; import com.ycy.mybatis.module.OrdersCustom; import com.ycy.mybatis.module.User; 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.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; /** * Created by Administrator on 2015/8/31 0031. */ public class MybatisTest6 { private SqlSessionFactory sqlSessionFactory = null; @Before public void before() throws IOException { String resource="SqlMapConfig.xml"; InputStream in = Resources.getResourceAsStream(resource); sqlSessionFactory= new SqlSessionFactoryBuilder().build(in); } @Test public void findOrderCustomer() throws Exception { SqlSession sqlSession=sqlSessionFactory.openSession(); OrdersCustomMapper ordersCustomMapper= sqlSession.getMapper(OrdersCustomMapper.class); List<OrdersCustom> ordersCustoms= ordersCustomMapper.findOrderCustomer(); sqlSession.close(); for (OrdersCustom ordersCustom : ordersCustoms) { System.out.println(ordersCustom.getUsername()); } } @Test public void findOrderResultMap() throws Exception { SqlSession sqlSession=sqlSessionFactory.openSession(); OrdersCustomMapper ordersCustomMapper= sqlSession.getMapper(OrdersCustomMapper.class); List<Orders> ordersList= ordersCustomMapper.findOrderResultMap(); sqlSession.close(); for (Orders ordersCustom : ordersList) { System.out.println(ordersCustom.getUser().getUsername()); } } }
3、resultMap与resultType初步总结
resultType:要自定义pojo 保证sql查询列和pojo的属性对应,这种方法相对较简单,所以应用广泛。
resultMap:使用association完成一对一映射需要配置一个resultMap,过程有点复杂,如果要实现延迟加载就只能用resultMap实现 ,如果为了方便对关联信息进行解析,也可以用association将关联信息映射到pojo中方便解析。