MyBatis 是一款优秀的持久层框架,属于 ORM 映射。前身是 ibatis。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis通过开发者书写SQL 语句,以及对象模型和关系模型的映射(ORM),完成对象模型和关系模型的数据转换。同时支持延迟加载,缓存,映射等。
MyBatis 可以通过简单的XML 或注解来配置和映射对象模型和关系模型,从而完成对象数据和关系数据的转换。
MyBatis 中文网:MyBatis中文网
MyBatis 组成:
核心对象:SqlSessionFactory SqlSession
配置文件
mybatis.cfg.xml -----> 主配置文件,用于配置数据源,链接各种 ORM 映射文件,以及实体类别名、日志等
多个 ORM 映射文件 ----> 用于书写实体类和表的映射关系,操作数据库的 SQL 语句,以及配置持久接口
导入依赖
-
mysql -
mysql-connector-java -
5.1.48 -
org.mybatis -
mybatis -
3.5.9 -
org.mybatis -
mybatis-typehandlers-jsr310 -
1.0.2
1、建立实体类
- public class ProductBean {
- //编号
- private Integer id;
- //商品名
- private String name;
- //生产日期
- private LocalDate createDate;
- //商品单价
- private Integer price;
- }
2、建立业务接口
- public interface IProductService {
- public void add(ProductBean productBean);
- }
3、建立Mapper接口
- public interface IProductMapper {
- public void add(ProductBean productBean);
- }
4、在 resources 目录中导入主配置文件 mybatis.cfg.xml
-
-
"logImpl" value="STDOUT_LOGGING" /> -
-
-
- <package name="com.project.bean"/>
-
-
-
-
default="dev"> -
-
"dev"> -
-
"JDBC"> -
-
"POOLED"> -
"driver" value="com.mysql.jdbc.Driver"/> -
"url" value="jdbc:mysql://localhost:12345/shopDB?characterEncoding=utf-8&allowMultiQueries=true"/> -
"username" value="root"/> -
"password" value="123"/> -
-
-
-
-
-
-
- <package name="com.project.mapper"/>
-
-
5、在 resources 目录中,创建包: com/project/mapper(必须和接口所在包同名,注意:创建包目录打 “ / ” 而非 “ . ”),在包中导入mapper配置文件。
namespace为命名空间,必须和 mapper 接口同名
"com.project.mapper.IProductMapper"> -
"add"> - insert into t_product(p_name,p_createDate,p_price)
- values(#{name},#{createDate},#{price});
-
6、建立 service 父类 BaseService
- public class BaseService {
- private static SqlSessionFactory factory;
- static {
- try {
- //从类路径中,加载主配置文件
- Reader r = Resources.getResourceAsReader("mybatis.cfg.xml");
- //创建会话工厂
- factory = new SqlSessionFactoryBuilder().build(r);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 创建并返回sqlsession对象
- * @return sqlsession对象
- */
- public SqlSession getSession(){
- return factory.openSession();
- }
- }
7、建立 service 接口实现类
- public class ProductServiceImpl extends BaseService implements IProductService {
- @Override
- public void add(ProductBean productBean) {
- //创建并得到会话对象
- SqlSession session = this.getSession();
- //创建并返回mapper接口对象
- IProductMapper mapper = session.getMapper(IProductMapper.class);
- mapper.add(productBean);
-
- //提交事务
- session.commit();
- //关闭连接
- session.close();
- }
- }
在开发中,有时候需要得到新加记录的编号,由于编号很多时候是自动增长列,有DBMS 进行分配。所有,新加记录的编号,开发者是不清楚的。这时,可以在语句块中添加属性 useCenerateKeys,允许得到自动增长列的值,KeyPropertry 表示将自动增长列的值,填充实体对象的哪个属性
"addProduct" useGeneratedKeys="true" keyProperty="id"> - insert into t_product(p_name,p_createDate,p_price)
- values (#{name},#{createDate},#{price})
1、在 mapper 语句中,加入删除语句块
"del"> - delete from t_product where pk_productId=#{id};
如果方法中,只有一个参数,并且该参数是简单类型(int、String),占位符名称可以随意
2、书写 service 方法
- public void del(Integer id) {
- SqlSession session = this.getSession();
- IProductMapper mapper = session.getMapper(IProductMapper.class);
- mapper.del(id);
-
- session.commit();
- session.close();
- }
1、如果 mapper 方法中,有多个参数,必须给参数加上别名
public void update(@Param("pid") Integer id,@Param("price") Integer price);
2、在 mapper 语句中,加入修改语句块
"update"> - update t_product set p_price=#{price} where pk_productId=#{pid};
3、书写业务方法
- public void update( Integer id, Integer price) {
- SqlSession session = this.getSession();
- IProductMapper mapper = session.getMapper(IProductMapper.class);
- mapper.update(id,price);
-
- session.commit();
- session.close();
- }
在执行查询操作时,需要指定查询操作返回的结果。可以通过 resultType 和 resultMap 指定义。
resultType 用于指定返回的实体类型。可以是简单类型(int,String),可以是对象类型。 当返回的是实体类型时,要求属性名和列名一致。否则无法根据列名封装对象的属性。
resultMap 用于定义属性和数据库列的对应关系,提高重用性,其他查询语句也可以引用。当列名和属性同名时可以不用写映射。
查询所有:
1、在 mapper 文件中定义resultMap 映射
"productMap" type="productBean"> -
"pk_productId" property="id"> -
"p_name" property="name"> -
"p_createDate" property="createDate"> -
"p_price" property="price">
2、在 mapper 文件中书写查询语句块
- select * from t_product;
3、书写业务方法
- public List
findAll() { - SqlSession session = this.getSession();
- IProductMapper mapper = session.getMapper(IProductMapper.class);
- List
list = mapper.findAll(); -
- session.close();
- return list;
- }
条件查询时,mabatis有两种占位符 $和#、
#在生成 SQL 时,对应字符类型、日期类型参数,会拼装引号。
$在生成 SQL 时,不会拼装引号,可用于 order by 之类的参数拼装,使用$时容易引起 SQL 注入。
按姓名模糊查询
1、在 mapper 文件中,书写 SQL
- select * from t_product where p_name like "%"#{name}"%";
2、书写业务方法
- public List
findByName(String name) { - SqlSession session = this.getSession();
- IProductMapper mapper = session.getMapper(IProductMapper.class);
- List
list = mapper.findByName(name); -
- session.close();
- return list;
- }
1、建立业务接口方法
- public CutPageBean
cutByItem(int pageNO,String name, - LocalDate startDate, LocalDate endDate);
2、建立 Mapper 接口方法
- /**
- * 分页查询当前页数据
- * @param name 商品名
- * @param startDate 生产起始日期
- * @param endDate 生产结束日期
- * @param startRow 起始记录数
- * @param pageSize 查询条数
- * @return 商品集合
- */
- public List
cutList(@Param("name") String name, - @Param("startDate") LocalDate startDate,
- @Param("endDate") LocalDate endDate,
- @Param("startRow") Integer startRow,
- @Param("pageSize") Integer pageSize);
- /**
- * 分页统计总记录数
- * @param name 商品名
- * @param startDate 生产开始日期
- * @param endDate 生产结束日期
- * @return 总记录数
- */
- public int cutCount(@Param("name") String name,
- @Param("startDate") LocalDate startDate,
- @Param("endDate") LocalDate endDate);
3、在 Mapper 文件中,书写 SQL 语句 如果一段 SQL 语句可以用于多个语句块时,可以用
"dynaSql"> - <if test="name != null and name != '' ">
- and p_name like "%"#{name}"%"
- if>
- <if test="startDate != null">
- and p_createDate >= #{createDate}
- if>
- <if test="endDate != null">
-
- and p_createDate <= #{endDate}
- ]]>
- if>
if 标题条件为真时,表示拼接指定的 SQL 语句。由于在 XML 文件中有一些特殊字符,比如:>、<、&等,这时可以用 包起来。这样无论里面是什么值都当字符串处理,不会因为有特殊符号,而导致编译报错。
引入语句块,采用标签
- select * from t_product where 1=1
-
"dynaSql"> - limit #{startRow},#{pageSize}
-
- select count(*) from t_product where 1=1
-
"dynaSql">
4、书写业务方法
- @Override
- public CutPageBean
cutByItem(int pageNO, String name, - LocalDate startDate, LocalDate endDate) {
- SqlSession session = this.getSession();
- IProductMapper mapper = session.getMapper(IProductMapper.class);
- CutPageBean
cutBean = new CutPageBean<>(); - cutBean.setList(mapper.cutList(name,startDate,endDate,
- (pageNO-1)*cutBean.PAGESIZE,cutBean.PAGESIZE));
- cutBean.setCount(mapper.cutCount(name,startDate,endDate));
- return cutBean;
- }
mybatis 注解
使用 mybatis 注解开发,可以在定义 mapper 接口时书写 SQL 语句。可以省去类配置文件,简洁方便。但是比较复杂的 SQL 和动态 SQL 还是建议书写配置类文件。