欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【java框架】MyBatis(1)—MyBatis入门

程序员文章站 2022-04-15 13:41:36
1. MyBatis认识 MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis可以使用简单的XML配置或注解来配置和映射原生信息,将接口和Java的POJO(Plain Ordinary Java Object,普通Java对象)映射成数据库中的数据。 2. ......

1.   mybatis认识

mybatis是一款优秀的持久层框架,它支持定制化sql、存储过程以及高级映射。mybatis可以使用简单的xml配置或注解来配置和映射原生信息,将接口和java的pojo(plain ordinary java object,普通java对象)映射成数据库中的数据。

2.   使用mybatis完成基础的crud

2.1.导入对应mybatis及数据库连接jar包

asm-3.3.1.jar

cglib-2.2.2.jar

commons-logging-1.1.1.jar

javassist-3.17.1-ga.jar

log4j-1.2.17.jar

mybatis-3.2.1.jar

mysql-connector-java-5.1.26-bin.jar

slf4j-api-1.7.2.jar

slf4j-log4j12-1.7.2.jar

【java框架】MyBatis(1)—MyBatis入门

2.2.建立数据库的表

【java框架】MyBatis(1)—MyBatis入门

2.3. 对应数据库表创建domain类

public class product {
private long id;
private long dir_id;    // 商品分类编号
private string productname;// 商品名称
private string supplier; // 供应商
private string brand; // 品牌
private double saleprice;  // 零售价
private double cutoff; // 折扣比例
private double costprice; // 进价
。。。。// getter与setter略过
}

2.4. 配置mybatis核心配置文件

mybatis的核心配置文件放在项目的资源文件resources目录下,文件命名为mybatis-config.xml,具体的配置如下:

mybatis-config.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>
    <!-- 引入jdbc.properties配置文件 -->
    <properties resource="jdbc.properties"></properties>
    <!--别名的配置,类的全限定名可以使用别名
        alias:别名名称
        type:别名所对应的类的全限定名,别名的使用与大小写无关-->
    <typealiases>
        <typealias alias="product" type="cn.yif.mybatis.domain.product"></typealias>
        <typealias alias="user" type="cn.yif.mybatis.domain.user"></typealias>
    </typealiases>
    <!--mybatis环境配置-->
    <environments default="development">
        <environment id="development">
            <transactionmanager type="jdbc"/>
            <!-- 数据库连接配置 -->
            <datasource type="pooled">
                <property name="driver" value="${driverclassname}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </datasource>
        </environment>
</environments>
<!—- mapper.xml文件配置 -->
    <mappers>
        <mapper resource="cn/yif/mybatis/mapper/productmapper.xml"/>
        <mapper resource="cn/yif/mybatis/mapper/usermapper.xml"/>
    </mappers>
</configuration>

2.5. 关联jdbc.properties文件配置

driverclassname = com.mysql.jdbc.driver
url = jdbc:mysql://localhost:3306/mybatis01_0317
username = root
password = admin

2.6. 对象关系映射文件xxxmapper.xml

映射文件xxxmapper.xml是对应domain属性与daoimpl中方法并与数据库字段产生关系的唯一映射配置,在这里面我们可以存放基础的crud对应的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">
<!-- namespace:用来找唯一的mapper文件,一般是domain的全路径名+mapper来命名 -->
<mapper namespace="cn.yif.mybatis.domain.product">
    <!--id表示唯一标识,parametertype标识参数的类型,resulttype表示返回值的类型-->
    <select id="querybyid" parametertype="long" resulttype="cn.yif.mybatis.domain.product">
        select * from product where id = #{id}
    </select>
    <select id="queryall" resulttype="cn.yif.mybatis.domain.product">
        select * from product
    </select>
    <!--添加时拿到返回的主键:
        parametertype:需要传入的对象
        usegeneratedkeys:是否需要主键
        keycolumn:数据库中对应主键的列
        keyproperty:对象中主键对应的id-->
   <insert id="insert" parametertype="cn.yif.mybatis.domain.product" usegeneratedkeys="true"
            keycolumn="id" keyproperty="id">
       insert into product(productname, dir_id, saleprice, supplier, brand, cutoff, costprice)
        values (#{productname}, #{dir_id}, #{saleprice}, #{supplier}, #{brand}, #{cutoff}, #{costprice})
    </insert>
    <update id="update" parametertype="cn.yif.mybatis.domain.product">
        update product set productname = #{productname}, dir_id = #{dir_id}, saleprice = #{saleprice},
        supplier = #{supplier}, brand = #{brand}, cutoff = #{cutoff}, costprice = #{costprice}
        where id = #{id}
    </update>
    <delete id="delete" parametertype="long">
        delete from product where id = #{id}
    </delete>
</mapper>

2.7. 获取sqlsession对象并抽取工具util类

首先我们需要读取mybatis-config.xml核心资源文件,通过sqlsessionfactorybuilder构建者来创建一个sqlsessionfactory工厂,通过sqlsessionfactory来创建sqlsession对象。通过sqlsession就可以执行我们的数据库增删查改的xml中的配置语句,最终使用之后还需要及时关闭sqlsession语句对象。基于这种增删改查操作都是同样的我们可以抽取一个工具类mybatisutil,具体实现如下:

public class mybatisutil {
    private static sqlsessionfactory sqlsessionfactory = null;
    private static reader reader = null;

    // 因为sqlsessionfactory是线程安全的,每次初始化只需要创建一个sqlsessionfactory实例
    static {
        try {
            reader = resources.getresourceasreader("mybatis-config.xml");
            sqlsessionfactory = new sqlsessionfactorybuilder().build(reader);
        } catch (ioexception e) {
            e.printstacktrace();
        }
    }

    // sqlsession是线程不安全的类,每个线程内单独去获取当前线程的sqlsession
    public static sqlsession getsqlsession(){
        return sqlsessionfactory.opensession();
    }

    // 关闭sqlsession
    public static void closesqlsession(sqlsession sqlsession){
        if(sqlsession != null){
            sqlsession.close();
        }
    }
}

2.8. 对应实现增删查改的daoimpl代码

productdaoimpl.java

public class productdaoimpl implements iproductdao {
    public static final string name_space = "cn.yif.mybatis.domain.product.";

    @override
    public void insert(product product) {
        sqlsession sqlsession = mybatisutil.getsqlsession();
        sqlsession.insert(name_space + "insert", product);
        mybatisutil.closesqlsession(sqlsession);
    }

    @override
    public void update(product product) {
        sqlsession sqlsession = mybatisutil.getsqlsession();
        sqlsession.update(name_space + "update", product);
        mybatisutil.closesqlsession(sqlsession);
    }

    @override
    public void delete(long id) {
        sqlsession sqlsession = mybatisutil.getsqlsession();
        sqlsession.delete(name_space + "delete", id);
        mybatisutil.closesqlsession(sqlsession);
    }

    @override
    public product querybyid(long id) {
        sqlsession sqlsession = mybatisutil.getsqlsession();
        product product = sqlsession.selectone(name_space + "querybyid", id);
        mybatisutil.closesqlsession(sqlsession);
        return product;
    }

    @override
    public list<product> queryall() {
        sqlsession sqlsession = mybatisutil.getsqlsession();
        list<product> list = sqlsession.selectlist(name_space + "queryall");
        mybatisutil.closesqlsession(sqlsession);
        return list;
    }
}

2.9. 对应junit4测试类实现

public class productdaoimpltest {
    @org.junit.test
    public void insert() {
        iproductdao productdao = new productdaoimpl();
        product product = new product();
        product.setproductname("测试产品112");
        product.setbrand("testbrand");
        product.setcostprice(237.5);
        product.setcutoff(0.85);
        product.setdir_id(4l);
        product.setsaleprice(520.0);
        product.setsupplier("甲骨文");
        system.out.println("添加之前,查看id:" + product.getid());
        productdao.insert(product);
        system.out.println("添加之后,查看id:" + product.getid());
    }

    @org.junit.test
    public void update() {
        iproductdao productdao = new productdaoimpl();
        product product = new product();
        product.setid(22l);
        product.setproductname("测试产品114");
        product.setbrand("testbrand114");
        product.setcostprice(237.1);
        product.setcutoff(0.45);
        product.setdir_id(4l);
        product.setsaleprice(520.1);
        product.setsupplier("甲骨文114");
        productdao.update(product);
   }

    @org.junit.test
    public void delete() {
        iproductdao productdao = new productdaoimpl();
        productdao.delete(24l);
    }

    @org.junit.test
    public void querybyid() {
        iproductdao productdao = new productdaoimpl();
        product product = productdao.querybyid(31l);
        system.out.println(product);
    }

    @org.junit.test
    public void queryall() {
        iproductdao productdao = new productdaoimpl();
        list<product> list = productdao.queryall();
        for (product product: list) {
            system.out.println(product);
        }
    }
}

3.   mybatis配置使用细节

3.1. 添加insert时拿到返回的主键

对应在xxxmapper.xml中需要做如下配置:

<!--添加时拿到返回的主键:
        parametertype:需要传入的对象
        usegeneratedkeys:是否需要主键
        keycolumn:数据库中对应主键的列
        keyproperty:对象中主键对应的id-->
<insert id="insert" parametertype="cn.yif.mybatis.domain.product" usegeneratedkeys="true"
            keycolumn="id" keyproperty="id">
        insert into product(productname, dir_id, saleprice, supplier, brand, cutoff, costprice)
        values (#{productname}, #{dir_id}, #{saleprice}, #{supplier}, #{brand}, #{cutoff}, #{costprice})
</insert>

3.2. log4j日志配置

log4j是mybatis提供的日志打印依赖jar包,可以帮助我们进行分析和定位问题。在log4j日志配置文件中我们可以规定日志打印显示的级别:

日志等级:从低到高(大小写没有关系,但是在配置的时候都建议使用大写)

等级从低到高(大小写没有关系,但是在配置的时候建议都写大写)
trace:详细  (建议开发的时候用)
dedug:调试,类似于system.out.print
info:信息,类似于jpa打印sql等级
warn:警告,程序可以正常运行,出现提示
error:错误,出现异常  (建议正式环境)

具体配置文件应命名为log4j.properties,配置如下:

log4j.properties:

#log4j.properties(日志文件):
#全局配置:先配置一个日志的根,这个级别是error
log4j.rootlogger=error, stdout
#局部配置 :把左边包名改成你自己的包名:表示我们自己这个路径下的代码级别
#级别说明:trace(详细)、debug(调试)、info(信息)、warn(警告)、error(错误)
log4j.logger.cn.yif.mybatis=trace
#在控制台输出和输出的格式
log4j.appender.stdout=org.apache.log4j.consoleappender
log4j.appender.stdout.layout=org.apache.log4j.patternlayout
log4j.appender.stdout.layout.conversionpattern=%d %p [%c] - %m%n

3.3.mybatis中设置类的别名typealiases

①    mybatis的内置别名

mybatis中包含内置别名,即无需配置,mybatis框架自动涵盖的别名,可以直接使用。

具体包含如下别名类型:

【java框架】MyBatis(1)—MyBatis入门

②    自定义别名

具体配置及其使用:

别名需要在mybatis-config.xml中使用,位置在<properties>标签之后:

<!--别名的配置,类的全限定名可以使用别名
      alias:别名名称
      type:别名所对应的类的全限定名,别名的使用与大小写无关-->
<typealiases>
    <typealias alias="product" type="cn.yif.mybatis.domain.product"></typealias>
     <typealias alias="user" type="cn.yif.mybatis.domain.user"></typealias>
</typealiases>

使用别名:

在xxxmapper.xml文件中对应的类全限定名即可使用别名,且与大小写无关。

【java框架】MyBatis(1)—MyBatis入门

3.4.列名与属性名不一致resultmap

数据库中的列名与domain类中的属性名不一致时,如果直接使用resulttype对应,执行sql查询语句等会出现相应值为null的情况,这时需要配置resultmap进行关系映射对应,告诉sql这个数据库中的列是对应domain类中的哪个属性,具体配置如下:

<?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">
<!-- namespace:用来找唯一的mapper文件,一般是domain的全路径名+mapper来命名 -->
<mapper namespace="cn.yif.mybatis.domain.user">
  <!--当domain中的属性与数据库中的字段列不一致时,需要使用resultmap
        id表示唯一标识,对应select中的resultmap
        type表示返回值类型
        column:对应数据库中的列名
        property:对应domain中类的属性字段-->
  <resultmap id="usermap" type="user">
      <result column="username" property="name"></result>
      <result column="password" property="pwd"></result>
  </resultmap>
  <!--id表示唯一标识,parametertype标识参数的类型,resulttype表示返回值的类型-->
  <select id="getuserbyid" parametertype="integer" resultmap="usermap">
        select * from user where id = #{id}
  </select>
</mapper>