zoukankan      html  css  js  c++  java
  • MyBatis入门

    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

    2.2.建立数据库的表

    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框架自动涵盖的别名,可以直接使用。

    具体包含如下别名类型:

    ②    自定义别名

    具体配置及其使用:

    别名需要在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文件中对应的类全限定名即可使用别名,且与大小写无关。

    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>
  • 相关阅读:
    HDU 1074 Doing Homework 状态压缩dp
    通过pwnable.kr从零学pwn
    php四个常用类封装
    web安全(入门篇)
    GD库
    php上传文件那些事
    windows内网渗透的一些笔记
    有关linux内网渗透的一些笔记
    Xcode 6以后默认不支持armv7s架构
    关键字搜索后描红
  • 原文地址:https://www.cnblogs.com/ysd139856/p/12538443.html
Copyright © 2011-2022 走看看