MyBatis框架功能与Hibernate一样。 都是持久化框架。都是操作JDBC。做ORM框架。 1 MyBatis框架比Hibernate小。 2 做的是针对SQL语句查询结果进行封装。2 MyBatis框架是什么?
MyBatis是一个针对SQL语句的ORM持久化框架。 1 针对SQL语句 在MyBatis框架中,我们要写SQL语句,针对SQL查询的结果进行封装。 2 ORM 将查询结果可以封装成一个实体对象。 3 持久化 使用JDBC进行数据库操作。3 编写第一个MyBatis框架的工程 3.1 创建工程并导入MyBatis的jar 3.2 配置MyBatis框架
在src目录下创建mybatis.xml文件。
3.3 ORM映射
1 数据库表:goods_type
2 编写实体类:GoodsType
public class GoodsType {
private int typeId;
private String typeName;
在MyBatis框架中SQL语句是程序员自己编写。
在MyBatis框架时,编写的SQL语句是独立于java源文件之外。
1 编写在xml配置文件(推荐)
2 编写在方法的注解
注意:编写一个与类名同名的xml文件。
在这个xml中编写对应的CURD的SQL语句。
select * from goods_type
resultType="com.no1.domain.GoodsType" 表示查询结果的每一条记录封装成指定的类型。
(只有在字段名称与属性名称一致时可用)
3.6 获得一个SqlSession的实例……
在MyBatis中使用核心组件SqlSession进行CRUD操作。
@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();
}
}
3.7 通过SqlSession组件的方法调用CRUD
查询所有
public void test01() {
try {
List 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();
}
}
4 配置本地DTD文件
Q:为什么要配置DTD文件?
4.1 找到本地dtd文件 4.2 在工具中绑定 5 当表中字段名称与实体类中属性名称不一致 5.1 创建数据库表 goods 5.2 创建实体类 5.3 编写Goods.xml文件DTD相当于是编写XML文件的代码提示蓝本,在XML文件中声明DTD的ID或者URL,再在MyEclipse或者Eclipse中配置一下,重新打开这个XML文件,就可以用alt+/获得像编写JAVA代码一样的提示功能。具体的配置方法可以百度一下~
当然,这个文件主要的功能是验证XML文件编写的合法性,也就是一个约束,要求你只能按DTD定义的格式写。
建议去看一下XML相关知识。
5.4 在mybatis.xml文件中注册Goods.xml文件
在实际开发中,不直接使用SqlSession的实例,而是使用Mapper接口,构建dao层。
6.1 Mapper接口是什么映射器是你创建的绑定映射语句的接口(interface) 映射器接口的实例可以从SqlSession中获得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;
}
6.4 编写Mapper接口
Mapper接口相当于Hebernate中的DAO
在这个接口中声明针对Goods这个实体类进行哪些CRUD操作
public interface GoodsMapper {
public List findAll();
}
6.5 编写GoodsMapper接口的实现类
在MyBatis框架中,接口的实现类是一个XML文件
在GoodsMapper接口的同目录创建一个叫GoodsMapper.xml文件
6.6 在mybatis.xml文件中注册GoodsMapper.xml文件
6.7 从SqlSession中获得Mapper接口的实例……
GoodsMapper goodsMapper = this.sqlSession.getMapper(GoodsMapper.class);7 带参数的查询 7.1 只有一个参数时
只有一个参数时,在xml文件中只要制定类型就可以
在sql语句中可以使用任意名称的参数
public Goods findById(int id);7.2 多个参数时
按价格区间查询的方法
public ListfindByPrice( @Param("minPrice") double minPrice, @Param("maxPrice") double maxPrice);
这个时候不用写parameterType参数
8 使用对象作为参数 8.1 保存商品public void save(Goods goods);
insert into goods(goods_id, goods_name, goods_price, goods_type) values(#{goodsId}, #{goodsName}, #{goodsPrice}, #{goodsType})
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();
}
8.2 多条件查询的对象
public class GoodsSearchVO {
private String goodsName;
private double minPrice;
private double maxPrice;
……
public ListfindBySearchVO(GoodsSearchVO goodsSearchVO);
try {
GoodsMapper goodsMapper
= this.sqlSession.getMapper(GoodsMapper.class);
GoodsSearchVO goodsSearchVO = new GoodsSearchVO("球", 100, 300);
List goodsList
= goodsMapper.findBySearchVO(goodsSearchVO);
for (Goods goods : goodsList) {
System.out.println(goods);
}
} finally{
this.sqlSession.close();
}
8.3 使用对象封装聚合查询的结果 GoodsGroupVO
查询所有的商品的最大价格和最小价格
public class GoodsGroupVO {
private double minPrice;
private double maxPrice;
public GoodsGroupVO findByGroup();9 MyBatis中的分页查询 9.1 SQL语句的分页查询
MySQL: limit 索引, 个数 Oracle: 二层子查询 + rownum9.2 导入分页插件的jar文件
需要使用的jar文件
项目中的jar包
在mybatis.xml文件中注册插件
9.4 使用分页插件
分页插件使用一个静态方法设置
有效范围: 进队后面的第一个查询有效
PageHelper.startPage(1, 2); ListgoodsList = goodsMapper.findAll(); PageHelper.startPage(int pageNum, int size);
1、 int pageNum 当前页码, 从 1 开始
2、 int size 每页记录数量
比如当前页吗,总记录数量等
通过这些信息进行页面分页控制。 上一页, 下一页
在分页插件中提供了一个叫PageInfo的类,这个类封装了分页的相关信息
通过构造方法装载分页的集合对象
PageInfopageInfo = new PageInfo (goodsList);
分页相关信息的方法使用
try{
GoodsMapper goodsMapper
= this.sqlSession.getMapper(GoodsMapper.class);
PageHelper.startPage(1, 2);
List goodsList = goodsMapper.findAll();
PageInfo pageInfo = new PageInfo(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();
}
注意控制上一页,下一页合理范围(上一页不会 <= 0, 下一页不会 超过总页码),相关的if语句自己完成
10 关联关系映射在MyBatis的框架中可以进行关联关系的映射,但是种类没有Hibernate那么多10.1 只有二类关联关系
第一类: 对一 有一个实体类需要映射
第二类: 对多 有一个集合需要映射
现在只处理对一的情况,所以在Goods类中有一个GoodsType类的对象
public class GoodsType {
private int typeId;
private String typeName;
public class Goods {
private int goodsId;
private String goodsName;
private double goodsPrice;
private int goodsNum;
private GoodsType goodsType;
Goods类最后一个属性 设计为GoodsType类型,表明对一关系
11.3 编写Mapper接口public interface GoodsMapper {
public List findAll();
11.4 编写XML文件
在这个XML文件中配置关联对象的映射,在MyBatis中有三种解决方案可选
11.4.1 第一种直接通过对象打点调用属性的方式做映射 要求: 查询语句要使用连接查询
11.4.2 第二种
引用关联关系对象的Mapper映射
GoodsTypeMapper.xml文件
GoodsMapper.xml文件
11.4.3 第三种
调用关联关系对象的Mapper的查询方法
public interface GoodsTypeMapper {
public GoodsType findById(int typeId);
GoodsMapper.xml中
12 对多的关联映射
一个类型有多个商品
设计为: 在类型类中有一个商品的集合
public class GoodsType {
private int typeId;
private String typeName;
private List goodsList;
12.2 编写GoodsTypeMapper接口
public interface GoodsTypeMapper {
public List findAll();
12.3 编写XML文件
映射从一个类型到多个商品
12.3.1 第一种,连接查询所有商品信息 12.3.2 第二种 调用关联关系对象的Mapper的查询方法public interface GoodsMapper {
public List findByType(int goodsTypeId);
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 goodsList;
14.2 编写Mapper接口
public interface GoodsMapper {
public List findAll();
public List findByType(int typeId);
public interface GoodsTypeMapper {
public List findAll();
public GoodsType findById(int typeId);
14.3 编写XML文件
14.3.1 编写GoodsMapper.xml文件
针对对象在编写查询语句时,直接使用连接查询
编写映射时直接关联关系对象的resultMap映射
14.3.2 编写GoodsTypeMapper.xml文件
针对集合,不用连接查询集合的数据
select * from goods_type select * from goods_type where typeId = #{id}
针对集合映射时,不要映射集合
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 goodsList = goodsMapper.findByType(typeId);
// 组装
goodsType.setGoodsList(goodsList);
return goodsType;
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}finally{
sqlSession.close();
}
}
}
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);
update goods where goods_id = #{goodsId} goods_name = #{goodsName}, goods_price = #{goodsPrice}, goods_num = #{goodsNum}, goods_type = #{goodsType.typeId},
使用动态SQL,我们要修改商品,可以不必先从数据库中查询出来
15.2 where标签在查询语句中的使用public class GoodsSearchVO {
private String goodsName;
private Double minPrice;
private Double maxPrice;
public List
15.3 foreach标签的使用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 goods_name like concat('%', #{goodsName}, '%') and goods_price > #{minPrice} and goods_price < #{maxPrice}
批量插入
public void saveBat(ListgoodsList);
insert into goods (goods_name, goods_price, goods_num, goods_type) values (#{goods.goodsName}, #{goods.goodsPrice}, #{goods.goodsNum}, #{goods.goodsType.typeId})
批量删除
public void delBat(Listseq);
16 MyBatis 整合 Spring 16.1 Spring 整合MyBatis框架时delete from goods where goods_id in #{id}
1.spring抢MyBatis的连接 2 Spring抢Mapper接口 3 spring抢Mapper.xml文件16.2 创建工程并导入jar包
导入MyBatis框架
导入Spring框架
16.3 Spring抢MyBatis的连接1 MyBatis的配置文件中不用写连接参数
2 在applicationContext.xml文件中配置数据源
3配置一个MyBatis的sqlSessionFactory
@Repository("GoodsMapper")
public interface GoodsMapper {
public List findAll();
public void save(Goods goods);
}
Mapper.xml文件没有什么改动,这里不再提供了
@Repository("GoodsTypeMapper")
public interface GoodsTypeMapper {
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 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);
}
}
}
16.9 测试
Albert.Zhou.CH总结 前辈经验于此,与各位分享 2019-03-20
-------------------------------To be continued------------------------------



