MyBatis详解

MyBatis 是一款优秀的持久层框架,属于 ORM 映射。前身是 ibatis。

MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis通过开发者书写SQL 语句,以及对象模型和关系模型的映射(ORM),完成对象模型和关系模型的数据转换。同时支持延迟加载,缓存,映射等。

MyBatis 可以通过简单的XML 或注解来配置和映射对象模型和关系模型,从而完成对象数据和关系数据的转换。

MyBatis 中文网:MyBatis中文网


MyBatis 组成:

核心对象:SqlSessionFactory SqlSession

配置文件

mybatis.cfg.xml -----> 主配置文件,用于配置数据源,链接各种 ORM 映射文件,以及实体类别名、日志等

多个 ORM 映射文件 ----> 用于书写实体类和表的映射关系,操作数据库的 SQL 语句,以及配置持久接口


mybatis 环境搭建

导入依赖

<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.48</version>
</dependency>
<dependency>
        <groupId>org.mybatis</groupId>
         <artifactId>mybatis</artifactId>
         <version>3.5.9</version>
</dependency>
<dependency>
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis-typehandlers-jsr310</artifactId>
         <version>1.0.2</version>
</dependency>

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

<configuration>
   <settings>
<!--      日志-->
      <setting name="logImpl" value="STDOUT_LOGGING" />
   </settings>
​
   <typeAliases>
<!--      <typeAlias type="com.project.bean.ProductBean" alias="product"></typeAlias>-->
<!--      将指定包中所有实体类,以实体类的类名,作为别名-->
      <package name="com.project.bean"/>
   </typeAliases>
​
​
   <environments default="dev">  
​
        <environment id="dev">  
​
            <transactionManager type="JDBC"></transactionManager>  
​
            <dataSource type="POOLED">
<!--            配置驱动类-->
            <property name="driver" value="com.mysql.jdbc.Driver"/>
<!--            配置URL,allowMultiQueries=true 表示允许一个语块中,书写多条SQL语句-->
            <property name="url" value="jdbc:mysql://localhost:12345/shopDB?characterEncoding=utf-8&amp;allowMultiQueries=true"/>
<!--            配置用户名-->
            <property name="username" value="root"/>
<!--            配置密码-->
            <property name="password" value="123"/>
            </dataSource>  
​
        </environment>  
​
    </environments>  
   
   <mappers>
<!--      加载指定包中所有的mapper文件,要求 mapper 文件名和接口名同名,
 mapper 文件中的命名空间,必须和接口同名-->
      <package name="com.project.mapper"/>
   </mappers>
</configuration>  

5、在 resources 目录中,创建包: com/project/mapper(必须和接口所在包同名,注意:创建包目录打 “ / ” 而非 “ . ”),在包中导入mapper配置文件。

namespace为命名空间,必须和 mapper 接口同名

<mapper namespace="com.project.mapper.IProductMapper">
    <insert id="add">
        insert into t_product(p_name,p_createDate,p_price)
        values(#{name},#{createDate},#{price});
    </insert>
</mapper>

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 表示将自动增长列的值,填充实体对象的哪个属性

<insert id="addProduct" useGeneratedKeys="true" keyProperty="id">
    insert into t_product(p_name,p_createDate,p_price)
    values (#{name},#{createDate},#{price})
</insert>

删除:

1、在 mapper 语句中,加入删除语句块

<delete id="del">
    delete from t_product where pk_productId=#{id};
</delete>

如果方法中,只有一个参数,并且该参数是简单类型(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 id="update">
    update t_product set p_price=#{price} where pk_productId=#{pid};
</update>

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();
}

mybatis 查询操作

在执行查询操作时,需要指定查询操作返回的结果。可以通过 resultType 和 resultMap 指定义。

resultType 用于指定返回的实体类型。可以是简单类型(int,String),可以是对象类型。 当返回的是实体类型时,要求属性名和列名一致。否则无法根据列名封装对象的属性。

resultMap 用于定义属性和数据库列的对应关系,提高重用性,其他查询语句也可以引用。当列名和属性同名时可以不用写映射。


查询所有:

1、在 mapper 文件中定义resultMap 映射

<resultMap id="productMap" type="productBean">
    <id column="pk_productId" property="id"></id>
    <result column="p_name" property="name"></result>
    <result column="p_createDate" property="createDate"></result>
    <result column="p_price" property="price"></result>
</resultMap>

2、在 mapper 文件中书写查询语句块

<select id="findAll" resultMap="productMap">
    select * from t_product;
</select>

3、书写业务方法

public List<ProductBean> findAll() {
    SqlSession session = this.getSession();
    IProductMapper mapper = session.getMapper(IProductMapper.class);
    List<ProductBean> list = mapper.findAll();
​
    session.close();
    return list;
}

条件查询:

条件查询时,mabatis有两种占位符 $和#、

#在生成 SQL 时,对应字符类型、日期类型参数,会拼装引号。

$在生成 SQL 时,不会拼装引号,可用于 order by 之类的参数拼装,使用$时容易引起 SQL 注入。

按姓名模糊查询

1、在 mapper 文件中,书写 SQL

<select id="findByName" resultMap="productMap">
    select * from t_product where p_name like "%"#{name}"%";
</select>

2、书写业务方法

public List<ProductBean> findByName(String name) {
    SqlSession session = this.getSession();
    IProductMapper mapper = session.getMapper(IProductMapper.class);
    List<ProductBean> list = mapper.findByName(name);
​
    session.close();
    return list;
}

动态条件分页查询

1、建立业务接口方法

public CutPageBean<ProductBean> cutByItem(int pageNO,String name,
 LocalDate startDate, LocalDate endDate);

2、建立 Mapper 接口方法

/**
* 分页查询当前页数据
* @param name 商品名
* @param startDate 生产起始日期
* @param endDate 生产结束日期
* @param startRow 起始记录数
* @param pageSize 查询条数
* @return 商品集合
*/
public List<ProductBean> 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 语句可以用于多个语句块时,可以用<sql>标签独立出来,便于重用

<sql id="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">
        <![CDATA[
        and p_createDate <= #{endDate}
        ]]>
    </if>
</sql>

if 标题条件为真时,表示拼接指定的 SQL 语句。由于在 XML 文件中有一些特殊字符,比如:>、<、&等,这时可以用 <![CDATA[]]> 包起来。这样无论里面是什么值都当字符串处理,不会因为有特殊符号,而导致编译报错。

引入<sql>语句块,采用<include>标签

<select id="cutList" resultMap="productMap">
    select * from t_product where 1=1
    <include refid="dynaSql"></include>
    limit #{startRow},#{pageSize}
</select>
​
<select id="cutCount" resultType="int">
    select count(*) from t_product where 1=1
    <include refid="dynaSql"></include>
</select>

4、书写业务方法

@Override
public CutPageBean<ProductBean> cutByItem(int pageNO, String name,
 LocalDate startDate, LocalDate endDate) {
    SqlSession session = this.getSession();
    IProductMapper mapper = session.getMapper(IProductMapper.class);
    CutPageBean<ProductBean> 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 还是建议书写配置类文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值