• Review-MyBatis


    MyBatis

    1 学习方法

    MyBatis框架功能与Hibernate一样。
    都是持久化框架。都是操作JDBC。做ORM框架。
    1 MyBatis框架比Hibernate小。
    2 做的是针对SQL语句查询结果进行封装。
    
    • 1
    • 2
    • 3
    • 4

    2 MyBatis框架是什么?

    MyBatis是一个针对SQL语句的ORM持久化框架。
    1 针对SQL语句
    	在MyBatis框架中,我们要写SQL语句,针对SQL查询的结果进行封装。
    2 ORM
    	将查询结果可以封装成一个实体对象。
    3 持久化
    	使用JDBC进行数据库操作。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3 编写第一个MyBatis框架的工程

    3.1 创建工程并导入MyBatis的jar

    3.2 配置MyBatis框架

    在src目录下创建mybatis.xml文件。

    <?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>
    	<environments default="development">
    		<environment id="development">
    			<transactionManager type="JDBC" />
    			<dataSource type="POOLED">
    				<property name="driver" value="com.mysql.jdbc.Driver" />
    				<property name="url" value="jdbc:mysql://127.0.0.1:3306/t2?useUnicode=true&characterEncoding=utf8" />
    				<property name="username" value="root" />
    				<property name="password" value="root" />
    			</dataSource>
    		</environment>
    	</environments>
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3.3 ORM映射

    1 数据库表:goods_type

    2 编写实体类:GoodsType
    public class GoodsType {
    private int typeId;
    private String typeName;

    3.4 编写SQL语句(写在XML文件)

    在MyBatis框架中SQL语句是程序员自己编写。
    在MyBatis框架时,编写的SQL语句是独立于java源文件之外。
    1 编写在xml配置文件(推荐)
    2 编写在方法的注解

    注意:编写一个与类名同名的xml文件。
    在这个xml中编写对应的CURD的SQL语句。

    <?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.zpark.tea_mgr.domain.GoodsType">
    	<select id="findAll" resultType="com.zpark.tea_mgr.domain.GoodsType">
    		select * from goods_type
    	</select>
    </mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    resultType="com.no1.domain.GoodsType" 表示查询结果的每一条记录封装成指定的类型。
    (只有在字段名称与属性名称一致时可用)

    3.5 在MyBatis配置文件中注册SQL的XML文件

    <?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>
    	<environments default="development">……</environments>
    	<mappers>
    		<mapper resource="com/zpark/tea_mgr/domain/GoodsType.xml" />
    	</mappers>
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.6 获得一个SqlSession的实例

    在MyBatis中使用核心组件SqlSession进行CRUD操作。
    
    • 1
    	@Before
    	public void before() {
    		try {
    			String resource = "mybatis.xml";
    			Reader reader = Resources.getResourceAsReader(resource);
    SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);
    			this.sqlSession = ssf.openSession();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.7 通过SqlSession组件的方法调用CRUD

    查询所有

    	public void test01() {
    		try {
    List<GoodsType> goodsTypeList = this.sqlSession.selectList("com.zpark.tea_mgr.domain.GoodsType.findAll");
    			for (GoodsType goodsType : goodsTypeList) {
    				System.out.println(goodsType);
    			}
    		} catch(Exception e) {
    			e.printStackTrace();
    		} finally {
    			this.sqlSession.close();
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4 配置本地DTD文件

    Q:为什么要配置DTD文件?

    DTD相当于是编写XML文件的代码提示蓝本,在XML文件中声明DTD的ID或者URL,再在MyEclipse或者Eclipse中配置一下,重新打开这个XML文件,就可以用alt+/获得像编写JAVA代码一样的提示功能。具体的配置方法可以百度一下~
    当然,这个文件主要的功能是验证XML文件编写的合法性,也就是一个约束,要求你只能按DTD定义的格式写。
    建议去看一下XML相关知识。

    4.1 找到本地dtd文件

    在这里插入图片描述

    4.2 在工具中绑定

    在这里插入图片描述

    5 当表中字段名称与实体类中属性名称不一致

    5.1 创建数据库表 goods

    在这里插入图片描述

    5.2 创建实体类

    在这里插入图片描述

    5.3 编写Goods.xml文件

    5.4 在mybatis.xml文件中注册Goods.xml文件
    在这里插入图片描述

    5.5 完成CRUD并测试

    6 使用Mapper接口开发MyBatis项目

    在实际开发中,不直接使用SqlSession的实例,而是使用Mapper接口,构建dao层。

    6.1 Mapper接口是什么

    映射器是你创建的绑定映射语句的接口(interface)
    映射器接口的实例可以从SqlSession中获得
    
    • 1
    • 2

    6.2 创建工程并导入jar

    6.3 编写实体类

    public class Goods {
    //	goods_id	int
    	private int goodsId;
    //	goods_name	varchar
    	private String goodsName;
    //	goods_price	double
    	private double goodsPrice;
    //	goods_num	int
    	private int goodsNum;
    //	goods_type	int
    	private int goodsType;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    6.4 编写Mapper接口

    Mapper接口相当于Hebernate中的DAO
    在这个接口中声明针对Goods这个实体类进行哪些CRUD操作

    public interface GoodsMapper {
    	public List<Goods> findAll();
    }
    
    • 1
    • 2
    • 3

    6.5 编写GoodsMapper接口的实现类

    在MyBatis框架中,接口的实现类是一个XML文件
    在GoodsMapper接口的同目录创建一个叫GoodsMapper.xml文件

    <mapper namespace="com.zpark.tea_mgr.mapper.GoodsMapper">
    	<select id="findAll" resultMap="resultGoods">
    		select * from goods
    	</select>
    	<resultMap type="com.zpark.tea_mgr.domain.Goods" id="resultGoods">
    		<id property="goodsId" column="goods_id" javaType="int" />
    		<result property="goodsName" column="goods_name" javaType="java.lang.String" />
    		<result property="goodsPrice" column="goods_price" javaType="double" />
    		<result property="goodsNum" column="goods_num" javaType="int" />
    		<result property="goodsType" column="goods_type" javaType="int" />
    	</resultMap>
    </mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    6.6 在mybatis.xml文件中注册GoodsMapper.xml文件

    <configuration>
    	<environments default="development">……</environments>
    	<mappers>
    		<mapper resource="com/zpark/tea_mgr/mapper/GoodsMapper.xml" />
    	</mappers>
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    6.7 从SqlSession中获得Mapper接口的实例

    GoodsMapper goodsMapper = this.sqlSession.getMapper(GoodsMapper.class);
    
    • 1

    7 带参数的查询

    7.1 只有一个参数时

    只有一个参数时,在xml文件中只要制定类型就可以
    在sql语句中可以使用任意名称的参数

    public Goods findById(int id);
    
    • 1
    <select id="findById"  parameterType="int"  resultMap="resultGoods">
    	select * from goods 
    	where goods_id = #{id}
    </select>
    
    • 1
    • 2
    • 3
    • 4

    7.2 多个参数时

    按价格区间查询的方法

    public List<Goods> findByPrice(
    @Param("minPrice") double minPrice, @Param("maxPrice") double maxPrice);
    
    • 1
    • 2
    <select id="findByPrice" resultMap="resultGoods">
    	select * from goods
    	where goods_price between #{minPrice} and #{maxPrice}  
    </select>
    
    • 1
    • 2
    • 3
    • 4

    这个时候不用写parameterType参数

    8 使用对象作为参数

    8.1 保存商品

    public void save(Goods goods);
    
    • 1
    <insert id="save" parameterType="com.zpark.tea_mgr.domain.Goods">
    	insert into goods(goods_id, goods_name, goods_price, goods_type)
    	values(#{goodsId}, #{goodsName}, #{goodsPrice}, #{goodsType})
    </insert>
    
    • 1
    • 2
    • 3
    • 4
    try {
    			GoodsMapper goodsMapper = this.sqlSession.getMapper(GoodsMapper.class);
    			Goods goods = new Goods();
    			goods.setGoodsName("测试用商品A");
    			goods.setGoodsPrice(6666);
    			goods.setGoodsNum(66);
    			goods.setGoodsType(4);
    			goodsMapper.save(goods);
    			this.sqlSession.commit();
    			System.out.println("新增商品成功");
    		} catch(Exception e){
    			e.printStackTrace();
    			this.sqlSession.rollback();
    			throw new RuntimeException(e);
    		} finally{
    			this.sqlSession.close();
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    8.2 多条件查询的对象

    public class GoodsSearchVO {
    	private String goodsName;
    	private double minPrice;
    	private double maxPrice;
    
    • 1
    • 2
    • 3
    • 4

    ……

    public List<Goods> findBySearchVO(GoodsSearchVO goodsSearchVO);
    
    • 1
    <select id="findBySearchVO"
            parameterType="com.zpark.tea_mgr.vo.GoodsSearchVO" resultMap="resultGoods">
    	select * from goods
    	where goods_name like concat('%', concat(#{goodsName}, '%'))
    	and goods_price between #{minPrice} and #{maxPrice}
    </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    try {
    		GoodsMapper goodsMapper 
    = this.sqlSession.getMapper(GoodsMapper.class);
    		GoodsSearchVO goodsSearchVO = new GoodsSearchVO("球", 100, 300);
    		List<Goods> goodsList 
    = goodsMapper.findBySearchVO(goodsSearchVO);
    		for (Goods goods : goodsList) {
    			System.out.println(goods);
    		}
    	} finally{
    		this.sqlSession.close();
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    8.3 使用对象封装聚合查询的结果 GoodsGroupVO

    查询所有的商品的最大价格和最小价格
    
    • 1
    public class GoodsGroupVO {
    	private double minPrice;
    	private double maxPrice;
    
    • 1
    • 2
    • 3
    public GoodsGroupVO findByGroup();
    
    • 1
    <select id="findByGroup" resultType="com.zpark.tea_mgr.vo.GoodsGroupVO">
    		select 
    		min(goods_price) as 'minPrice',
    		max(goods_price) as 'maxPrice'
    		from goods
    	</select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    9 MyBatis中的分页查询

    9.1 SQL语句的分页查询

    MySQL:  	limit 索引, 个数
    Oracle:		二层子查询 + rownum
    
    • 1
    • 2

    9.2 导入分页插件的jar文件

    需要使用的jar文件
    在这里插入图片描述

    项目中的jar包
    在这里插入图片描述

    9.3 在MyBatis中注册分页的插件

    在mybatis.xml文件中注册插件

    <plugins>
    	<plugin interceptor="com.github.pagehelper.PageHelper">
    		<property name="dialect" value="mysql" />
    	</plugin>
    </plugins>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    9.4 使用分页插件

    分页插件使用一个静态方法设置
    有效范围: 进队后面的第一个查询有效

    PageHelper.startPage(1, 2);
    List<Goods> goodsList = goodsMapper.findAll();
      PageHelper.startPage(int pageNum, int size);
    
    • 1
    • 2
    • 3

    1、 int pageNum 当前页码, 从 1 开始
    2、 int size 每页记录数量

    9.5 获得分页信息

    比如当前页吗,总记录数量等
    通过这些信息进行页面分页控制。 上一页, 下一页
    在分页插件中提供了一个叫PageInfo的类,这个类封装了分页的相关信息
    通过构造方法装载分页的集合对象

    PageInfo<Goods> pageInfo = new PageInfo<Goods>(goodsList);
    
    • 1

    分页相关信息的方法使用

    try{
    			GoodsMapper goodsMapper 
    = this.sqlSession.getMapper(GoodsMapper.class);
    			PageHelper.startPage(1, 2);
    			List<Goods> goodsList = goodsMapper.findAll();
    			PageInfo<Goods> pageInfo = new PageInfo<Goods>(goodsList);
    			for (Goods goods : pageInfo.getList()) {
    				System.out.println(goods);
    			}
    			System.out.println("当前页码:" + pageInfo.getPageNum());
    			System.out.println("每页记录数:" + pageInfo.getPageSize());
    			System.out.println("总页码数:" + pageInfo.getPages());
    			System.out.println("总记录数:" + pageInfo.getTotal());
    			System.out.println("上一页:" + pageInfo.getPrePage());
    			System.out.println("下一页:" + pageInfo.getNextPage());
    		} finally{
    			this.sqlSession.close();
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    注意控制上一页,下一页合理范围(上一页不会 <= 0, 下一页不会 超过总页码),相关的if语句自己完成

    10 关联关系映射

    在MyBatis的框架中可以进行关联关系的映射,但是种类没有Hibernate那么多
    
    • 1

    10.1 只有二类关联关系

    第一类: 对一 有一个实体类需要映射
    第二类: 对多 有一个集合需要映射

    11 对一的关联映射

    11 .1数据库中关联关系

    在这里插入图片描述

    11.2 实体对象之间的关系

    现在只处理对一的情况,所以在Goods类中有一个GoodsType类的对象

    public class GoodsType {
    	private int typeId;
    	private String typeName;
    
    • 1
    • 2
    • 3
    public class Goods {
    	private int goodsId;
    	private String goodsName;
    	private double goodsPrice;
    	private int goodsNum;
    	private GoodsType goodsType;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Goods类最后一个属性 设计为GoodsType类型,表明对一关系

    11.3 编写Mapper接口

    public interface GoodsMapper {
    	public List<Goods> findAll();
    
    • 1
    • 2

    11.4 编写XML文件

    在这个XML文件中配置关联对象的映射,在MyBatis中有三种解决方案可选

    11.4.1 第一种

    直接通过对象打点调用属性的方式做映射
    要求: 查询语句要使用连接查询
    
    • 1
    • 2
    <!-- 第一种方案:使用连接查询 -->
    	<select id="findAll" resultMap="resultGoods">
    		select * from goods
    		left join goods_type
    		on goods_type.typeId = goods.goods_type
    	</select>
    	<resultMap type="com.zpark.tea_mgr.domain.Goods" id="resultGoods">
    		<id property="goodsId" column="goods_id" javaType="int" />
    		<result property="goodsName" column="goods_name" javaType="java.lang.String" />
    		<result property="goodsPrice" column="goods_price" javaType="double" />
    		<result property="goodsNum" column="goods_num" javaType="int" />
    		<!-- 第一种方案:直接使用打点调用属性的方式 -->
    		<result property="goodsType.typeId" column="typeId" javaType="int" />
    		<result property="goodsType.typeName" column="typeName" javaType="java.lang.String" />
    	</resultMap>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    11.4.2 第二种

    引用关联关系对象的Mapper映射
    GoodsTypeMapper.xml文件

    <resultMap type="com.zpark.tea_mgr.domain.GoodsType" id="resultGoodsType">
    	<id property="typeId" column="typeId" javaType="int" />
    	<result property="typeName" column="typeName" 
    javaType="java.lang.String" />
    </resultMap>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    GoodsMapper.xml文件

    <association property="goodsType"
    	javaType="com.zpark.tea_mgr.domain.GoodsType"			resultMap="com.zpark.tea_mgr.mapper.GoodsTypeMapper.resultGoodsType" />
    
    • 1
    • 2

    11.4.3 第三种

    调用关联关系对象的Mapper的查询方法

    public interface GoodsTypeMapper {
    	public GoodsType findById(int typeId);
    
    • 1
    • 2
    <select id="findById" parameterType="int" resultMap="resultGoodsType">
    	select * from goods_type where typeId = #{id}
    </select>
    
    • 1
    • 2
    • 3

    GoodsMapper.xml

    <!-- 第三种方案: 查自己就好了 -->
    <select id="findAll" resultMap="resultGoods">
    	select * from goods
    </select>
    <!-- 第三种方案: 使用关联关系对象的查询的方法 -->
    <association property="goodsType"
    	javaType="com.zpark.tea_mgr.domain.GoodsType" 
    	select="com.zpark.tea_mgr.mapper.GoodsTypeMapper.findById" 
    	column="goods_type" />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    12 对多的关联映射

    一个类型有多个商品
    设计为: 在类型类中有一个商品的集合

    12.1 编写实体类

    public class GoodsType {
    	private int typeId;
    	private String typeName;
    	private List<Goods> goodsList;
    
    • 1
    • 2
    • 3
    • 4

    12.2 编写GoodsTypeMapper接口

    public interface GoodsTypeMapper {
    	public List<GoodsType> findAll();
    
    • 1
    • 2

    12.3 编写XML文件

    映射从一个类型到多个商品

    12.3.1 第一种,连接查询所有商品信息

    <select id="findAll" resultMap="resultGoodsType">
    		select * from goods_type
    		left join goods
    		on goods.goods_type = goods_type.typeId
    </select>
    <resultMap type="com.zpark.tea_mgr.domain.GoodsType" id="baseGoodsType">
    	<id property="typeId" column="typeId" javaType="int" />
    	<result property="typeName" column="typeName" 
    javaType="java.lang.String" />
    </resultMap>
    <resultMap type="com.zpark.tea_mgr.domain.GoodsType" id="resultGoodsType" 
    extends="baseGoodsType">
    <collection property="goodsList" javaType="java.util.List" 
    			ofType="com.zpark.tea_mgr.domain.Goods" 
    			resultMap="com.zpark.tea_mgr.mapper.GoodsMapper.resultGoods"
     /> 
    </resultMap>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    12.3.2 第二种 调用关联关系对象的Mapper的查询方法

    public interface GoodsMapper {
    	public List<Goods> findByType(int goodsTypeId);
    
    • 1
    • 2
    <select id="findByType" parameterType="int" resultMap="resultGoods">
    	select * from goods where goods_type = #{id}
    </select>
    <!-- 第二种方案 --> 
    <collection property="goodsList" javaType="java.util.List" 
    		ofType="com.zpark.tea_mgr.domain.Goods"
    		select="com.zpark.tea_mgr.mapper.GoodsMapper.findByType" 
    		column="typeId" />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    13 开发环境应用方案

    13.1 不要使用双向映射

    13.2 针对一个对象的映射,使用连接查询

    13.3 针对一个集合的映射,不要再MyBatis的Mapper文件中映射

    ** 但要提供查询的方法,在业务层完成组装**

    14 映射案例 ---- 最佳解决方案

    14.1 编写实体类

    public class Goods implements Serializable{
    	private static final long serialVersionUID = 8874153057031505335L;
    	private Integer goodsId;
    	private String goodsName;
    	private Double goodsPrice;
    	private Integer goodsNum;
    	private GoodsType goodsType;
    public class GoodsType {
    	private Integer typeId;
    	private String typeName;
    	private List<Goods> goodsList;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    14.2 编写Mapper接口

    public interface GoodsMapper {
    	public List<Goods> findAll();
    	/**
    	 * 给关联关系对象(商品类型)提供查找其下商品的方法
    	 * 如果要查某个商品类型信息的时候要带出相关的商品信息
    	 * @param typeId 某个商品类型的ID
    	 * @return 返回某个商品类型下的商品集
    	 */
    	public List<Goods> findByType(int typeId);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    public interface GoodsTypeMapper {
    	public List<GoodsType> findAll(); 
    	public GoodsType findById(int typeId);
    
    • 1
    • 2
    • 3

    14.3 编写XML文件

    14.3.1 编写GoodsMapper.xml文件

    针对对象在编写查询语句时,直接使用连接查询

    <select id="findAll" resultMap="BaseResultMap">
    		select * from goods
    		left join goods_type
    		on goods_type.typeId = goods.goods_type
    </select>
    <select id="findByType" parameterType="java.lang.Integer"
    resultMap="BaseResultMap">
    		select * from goods
    		left join goods_type
    		on goods_type.typeId = goods.goods_type
    		where goods_type = #{id}
    </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    编写映射时直接关联关系对象的resultMap映射

    <resultMap type="com.zpark.tea_mgr.domain.Goods" id="BaseResultMap">
    	<id column="goods_id" property="goodsId" jdbcType="INTEGER" />
    	<result column="goods_name" 
    property="goodsName" jdbcType="VARCHAR" />
    	<result column="goods_price" property="goodsPrice" jdbcType="DOUBLE" />
    	<result column="goods_num" property="goodsNum" jdbcType="INTEGER" />
    	<association property="goodsType"
    javaType="com.zpark.tea_mgr.domain.GoodsType"			 resultMap="com.zpark.tea_mgr.mapper.GoodsTypeMapper.BaseResultMap" />
    </resultMap>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    14.3.2 编写GoodsTypeMapper.xml文件

    针对集合,不用连接查询集合的数据

    <select id="findAll" resultMap="BaseResultMap">
    	select * from goods_type
    </select>
    <select id="findById" parameterType="java.lang.Integer"
           resultMap="BaseResultMap">
    	select * from goods_type
    	where typeId = #{id}
    </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    针对集合映射时,不要映射集合

    <resultMap type="com.zpark.tea_mgr.domain.GoodsType" id="BaseResultMap">
    	<id property="typeId" column="typeId" javaType="java.lang.Integer" />
    	<result column="typeName" property="typeName" jdbcType="VARCHAR" />
    </resultMap>
    
    • 1
    • 2
    • 3
    • 4

    14.4 编写service层

    public class GoodsTypeService {
    	public GoodsType findById(int typeId){
    		SqlSession sqlSession = null;
    		try{
    			String resource = "mybatis.xml";
    			Reader reader = Resources.getResourceAsReader(resource);
    			SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);
    			sqlSession = ssf.openSession();
    			GoodsTypeMapper goodsTypeMapper =
     sqlSession.getMapper(GoodsTypeMapper.class);
    			GoodsType goodsType = goodsTypeMapper.findById(typeId);
    			GoodsMapper goodsMapper =
     sqlSession.getMapper(GoodsMapper.class);
    			List<Goods> goodsList = goodsMapper.findByType(typeId);
    			// 组装
    			goodsType.setGoodsList(goodsList);
    			return goodsType;
    		}catch(Exception e){
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		}finally{
    			sqlSession.close();
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    14.5 测试

    15 动态SQL

    15.1 set标签在update语句中的使用

    public interface GoodsMapper {
    	public void update(Goods goods);
    	public Goods findById(int goodsId);
    	public void updateByDynamicSQL(Goods goods);
    
    • 1
    • 2
    • 3
    • 4
    <update id="updateByDynamicSQL"
                  parameterType="com.zpark.tea_mgr.domain.Goods">
    		update goods
    		<set>
    			<if test="goodsName != null">
    				goods_name = #{goodsName},
    			</if>
    			<if test="goodsPrice != null">
    				goods_price = #{goodsPrice},
    			</if>
    			<if test="goodsNum != null">
    				goods_num = #{goodsNum},
    			</if>
    			<if test="goodsType != null and goodsType.typeId != null">
    				goods_type = #{goodsType.typeId},
    			</if>
    		</set>
    		where goods_id = #{goodsId}
    	</update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    使用动态SQL,我们要修改商品,可以不必先从数据库中查询出来

    15.2 where标签在查询语句中的使用

    public class GoodsSearchVO {
    	private String goodsName;
    	private Double minPrice;
    	private Double maxPrice;
    public List<Map<String, Object>> findBySearchVO(GoodsSearchVO goodsSearchVO);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    <select id="findBySearchVO"
    parameterType="com.zpark.tea_mgr.vo.GoodsSearchVO"
    	        resultType="java.util.Map">
    		select
    		goods_name as 'goodsName',
    		goods_price as 'goodsPrice',
    		goods_num as 'goodsNum',
    		typeName as 'typeName'
    		from goods
    		left join goods_type
    		on goods_type.typeId = goods.goods_type
    		<where>
    			<if test="goodsName != null">
    				goods_name like concat('%', #{goodsName}, '%')
    			</if>
    			<if test="minPrice != null">
    				and goods_price &gt; #{minPrice}
    			</if>
    			<if test="maxPrice != null">
    				and goods_price &lt; #{maxPrice}
    			</if>
    		</where>
    	</select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    15.3 foreach标签的使用

    批量插入

    public void saveBat(List<Goods> goodsList);
    
    • 1
    <insert id="saveBat" parameterType="java.util.List">
    	insert into goods (goods_name, goods_price, goods_num, goods_type)
    	values
    	<foreach collection="list" item="goods" separator=",">
    		(#{goods.goodsName}, #{goods.goodsPrice}, #{goods.goodsNum},
    #{goods.goodsType.typeId})
    	</foreach>
    </insert>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    批量删除

    public void delBat(List<Integer> seq);
    
    • 1
    <delete id="delBat" parameterType="java.util.List">
    	delete from goods
    	where goods_id in 
    	<foreach collection="list" item="id" separator="," open="(" close=")"
     index="index">
    		#{id}
    	</foreach>
    </delete>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    16 MyBatis 整合 Spring

    16.1 Spring 整合MyBatis框架时

    1.spring抢MyBatis的连接
    2 Spring抢Mapper接口
    3 spring抢Mapper.xml文件
    
    • 1
    • 2
    • 3

    16.2 创建工程并导入jar包

    导入MyBatis框架

    在这里插入图片描述

    导入Spring框架

    在这里插入图片描述

    16.3 Spring抢MyBatis的连接

    1 MyBatis的配置文件中不用写连接参数
    在这里插入图片描述

    2 在applicationContext.xml文件中配置数据源
    在这里插入图片描述

    3配置一个MyBatis的sqlSessionFactory
    在这里插入图片描述

    16.4 Spring抢Mapper.xml文件

    在这里插入图片描述

    16.5 Spring配置事务处理对象

    在这里插入图片描述

    16.6 编写实体类

    16.7 编写Mapper接口

    @Repository("GoodsMapper")
    public interface GoodsMapper {
    	public List<Goods> findAll();
    	public void save(Goods goods);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Mapper.xml文件没有什么改动,这里不再提供了

    @Repository("GoodsTypeMapper")
    public interface GoodsTypeMapper {
    
    • 1
    • 2

    16.8 编写业务层 GoodsService

    @Service("GoodsService")
    public class GoodsService {
    	
    	@Autowired
    	@Qualifier("GoodsMapper")
    	private GoodsMapper goodsMapper;
    	
    	public GoodsMapper getGoodsMapper() {
    		return goodsMapper;
    	}
    
    	public void setGoodsMapper(GoodsMapper goodsMapper) {
    		this.goodsMapper = goodsMapper;
    	}
    
    	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
    	public List<Goods> findAll(){
    		try{
    			return this.goodsMapper.findAll();
    		}catch(Exception e){
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		}
    	}
    	
    	@Transactional(propagation = Propagation.REQUIRED, 
    rollbackFor = { Exception.class })
    	public void save(Goods goods){
    		try{
    			this.goodsMapper.save(goods);
    			System.out.println("保存成功!");
    		}catch(Exception e){
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		}
    	}
    	
    }
    
    • 1
    • 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

    16.9 测试

    							Albert.Zhou.CH总结 前辈经验于此,与各位分享
    												2019-03-20
    
    • 1
    • 2

    -------------------------------To be continued------------------------------

  • 相关阅读:
    《21天精通TypeScript-5》类型注解与原始类型
    ETHERNET/IP从站转CANOPEN主站连接AB系统的配置方法
    gdb调试
    mysql创建定时器(event),定时调用存储过程(Procedure)将查询出结果集并批量插入新表
    MySQL 崩溃恢复过程分析
    MySQL概览
    day42 62.不同路径 63. 不同路径 II
    Geth无法获取早期block的transaction信息
    阿里巴巴首推 2022 年金九银十 1000 道 Java 工程师面试题手册(P7岗),整整的10w字文档
    java毕业设计线上助农销售管理演示2021mybatis+源码+调试部署+系统+数据库+lw
  • 原文地址:https://blog.csdn.net/qq_41550190/article/details/126160375