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

    1、MyBatis的介绍

      1. MyBatis 是一个支持普通SQL查询,存储过程和高级映射的优秀持久层(Dao)框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。

      2. MyBatis 消除了几乎所有的JDBC代码和手工设置参数以及结果集的检索。

      3. MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

      4. 一个MyBatis的应用程序都以一个SqlSessionFactory 对象(单例)的实例为核心;

        SqlSession对象完全包含以数据库为背景的所有执行SQL操作的方法。

      5. MyBatis是针对数据库交互的一个辅助框架,也是对jdbc做了的简单封装,以xml配置代替Java代码来管理数据库的交互细节!!

      注意:

        JPA 可以自动建表。

        MyBatis不能自动创建表,如果要建表,必须自己先准备好建表的sql语句。

     

    MyBatis三大核心对象
        1. SqlSessionFactoryBuilder
              目的是创建SqlSessionFactory  ,  用完就扔  , 写在方法内部 , 作为局部变量 , 建造者模式。
        2. SqlSessionFactory
              重量级对象 , 作用域整个应用  , 单例模式使用  , 有二级缓存。
        3. SqlSession
            轻量级的  ,  请求作用域,一个请求对应一个SqlSession对象 , 线程不安全的 , 有一级缓存。
        4. (扩展)Executor 数据库的操作都是调用的Executor接口的方法
                    update:增、删、改所用方法。
                    query:查询所用方法。

     

    MyBatis执行流程: 

      ①:我们需要核心文件(提供联系数据库的环境)

      ②:需要映射文件(提供ORM与运行的SQL语句)

      ③:拿到SqlSession对象,用于执行SQL

     

    2、MyBatis的入门使用

      注意:

        使用Mybatis的方式用两种,一种是xml配置的方式,一种是接口+注解的方式。

        这里主要是介绍xml配置方式。

     

      1.导入相应的jar包

        核心包:mybatis-3.2.1.jar

        数据库驱动包:mysql-connector-java-5.1.26-bin.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
                slf4j-api-1.7.2.jar
                slf4j-log4j12-1.7.2.jar

      2.准备相应的数据

        数据库-->新建数据库-->新建表-->插入测试数据

       3.准备domain实体类、dao和测试类

        注意:类的名称和类型都和我们的product表相对应匹配

      案例:

    domain实体类

    public class Product {
        private    Long id;
        //商品名称
        private String productName;
        //品牌
        private String brand;
        //供应商
        private String supplier;
        //零售价
        private Double salePrice;
        //进价
        private Double costPrice;
        //折扣比例
        private Double cutoff;
        //商品分类编号
        private Long dir_id;

      -----之后是get、set方法(略)
    }

     

    dao层接口

    public interface IProductDao {
        /**
         * 添加一个商品
         */
        void save(Product p);
        /**
         * 更新一个商品
         */
        void update(Product product);
        /**
         * 删除一个商品
         */
        void delete(Long id);
        /**
         * 查询一个商品
         */
        Product findOne(Long id);
        /**
         * 查询所有商品
         */
        List<Product> findAll();
    
    }

    dao层接口实现类 

      注:添加、修改、删除的时候一定要记住提交事务(配置事务、表结构支持事务)。

        JDBC的事务是自动提交的,而JPA、Hibernate、MyBatis事务都是需要手动提交的。

    package cn.wang.dao.daoImpl;
    
    import cn.wang.Utils.MyBatisUtils;
    import cn.wang.dao.IProductDao;
    import cn.wang.domain.Product;
    import org.apache.ibatis.session.SqlSession;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ProductDaoImpl implements IProductDao {
    
        //抽取sql命名空间名字的值
        private final String NAMESPACE = "cn.wang.domain.ProductMapper.";
        //添加方法
        @Override
        public void save(Product p) {
            SqlSession sqlSession =null;
    
            try {
                //获取SqlSession对象(MyBatisUtils是为了方便专门抽取出来的工具类)
                sqlSession = MyBatisUtils.getSession();
                //第一个参数:sql命名空间名字的值+对应sql语句映射的id,第二个参数:传入的值
                sqlSession.insert(NAMESPACE+"insert",p);
                //提交事务
                sqlSession.commit();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭sqlSession,释放资源(很重要,不然项目上线后会造成内存溢出)
                MyBatisUtils.colseSession(sqlSession);
            }
        }
    
        //修改方法
        @Override
        public void update(Product product) {
            SqlSession sqlSession = null;
            try {
                //获取SqlSession对象(MyBatisUtils是为了方便专门抽取出来的工具类)
                sqlSession = MyBatisUtils.getSession();
                //第一个参数:sql命名空间名字的值+对应sql语句映射的id,第二个参数:传入的值
                sqlSession.update(NAMESPACE+"update", product);
                //提交事务
                sqlSession.commit();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭sqlSession,释放资源(很重要,不然项目上线后会造成内存溢出)
                MyBatisUtils.colseSession(sqlSession);
            }
        }
    
        //删除方法
        @Override
        public void delete(Long id) {
            SqlSession sqlSession=null;
    
            try {
                //获取SqlSession对象(MyBatisUtils是为了方便专门抽取出来的工具类)
                sqlSession = MyBatisUtils.getSession();
                //第一个参数是获取查询语句:sql命名空间名字的值+对应sql语句映射的id
                sqlSession.delete(NAMESPACE+"delete", id);
                //提交事务
                sqlSession.commit();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭sqlSession,释放资源(很重要,不然项目上线后会造成内存溢出)
                MyBatisUtils.colseSession(sqlSession);
            }
        }
    
        //查询一条数据
        @Override
        public Product findOne(Long id) {
            SqlSession sqlSession = null;
            Product product= null;
            try {
                //获取SqlSession对象(MyBatisUtils是为了方便专门抽取出来的工具类)
                sqlSession = MyBatisUtils.getSession();
                //第一个参数是获取查询语句:sql命名空间名字的值+对应sql语句映射的id
                product = sqlSession.selectOne(NAMESPACE+"findOne", id);
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭sqlSession,释放资源(很重要,不然项目上线后会造成内存溢出)
                MyBatisUtils.colseSession(sqlSession);
            }
            return product;
        }
    
        //查询所有数据
        @Override
        public List<Product> findAll() {
            SqlSession sqlSession=null;
            List<Product> list=new ArrayList<>();
    
            try {
                //获取SqlSession对象(MyBatisUtils是为了方便专门抽取出来的工具类)
                sqlSession = MyBatisUtils.getSession();
                //第一个参数是获取查询语句:sql命名空间名字的值+对应sql语句映射的id
                list=sqlSession.selectList(NAMESPACE+"findAll");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭sqlSession,释放资源(很重要,不然项目上线后会造成内存溢出)
                MyBatisUtils.colseSession(sqlSession);
            }
            return list;
        }
    }

    抽取出来的MyBatisUtils工具

    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.Reader;
    
    public class MyBatisUtils {
        //保证sqlSessionFactory是单例
        private static SqlSessionFactory sqlSessionFactory;
    
        // SqlSessionFactory类似于JPA的EntityManagerFactory,Hibernate的SessionFactory
        // SqlSession 类似于JPA的EntityManager,Hibernate的Session
    
        //该类被加载的时候就执行该静态代码块
        static {
            try {
                Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            } catch (Exception e) {//异常的类型要写大一些,才能够看到具体的报错
                e.printStackTrace();
            }
        }
        //提供一个外界调用的类
        public static SqlSession getSession(){
            //创建并返回SqlSession对象
            return sqlSessionFactory.openSession();
        }
        //关闭sqlSession,释放资源(很重要,不然项目上线后会造成内存溢出)
        public static void colseSession(SqlSession sqlSession){
            if(sqlSession !=null){
                sqlSession.close();
            }
        }
    }

    jdbc.properties

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql:///数据库名称
    jdbc.username=用户名
    jdbc.password=密码

      3.MyBatis核心配置文件(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>
        <!-- environments:环境集合
            default:默认使用哪一个环境(必须对应一个环境的id)
         -->
    
        <!--引入外部的属性文件
            不写classpath的原因:resources默认到classpath中寻找资源
        -->
        <properties resource="jdbc.properties" />
    
        <!--
            配置自定义别名
            注意:别名不区分大小写。
               共两种配置方式:
                一:一个一个配置(typeAlias)
                        type 类型的完全限定名
                        alias 别名
                二:统一为某个包下的所有类起别名(package)
                        name : 包名   别名就是类名(不区分大小写)
        -->
        <typeAliases>
            <!--方法一-->
            <!--<typeAlias type="cn.wang.domain" alias="Product"/>-->
    
            <!--方法二-->
            <package name="cn.wang.domain"/>
        </typeAliases>
    
        <environments default="development">
            <!--
                environment:一个环境  id:为这个环境取唯一一个id名称
            -->
            <environment id="development">
                <!--
                    transactionManager:事务管理(共有两个值) type:JDBC(支持事务)/MANAGED(什么都不做)
                -->
                <transactionManager type="JDBC" />
                <!-- 数据源, 连接池  type(POOLED):MyBatis自带的连接池
                         type="UNPOOLED" 不使用连接池
                        type="POOLED" 使用连接池
                        type="JNDI" 容器中使用
                 -->
                <dataSource type="POOLED">
                    <!-- 连接数据库的参数 -->
                    <property name="driver" value="${jdbc.driver}" />
                    <property name="url" value="${jdbc.url}" />
                    <property name="username" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
                </dataSource>
            </environment>
        </environments>
        <!-- 注册映射文件,这个mappers代表的是相应的ORM映射文件 -->
        <mappers>
            <mapper resource="cn/wang/domain/ProductMapper.xml" />
        </mappers>
    
    </configuration>

      4.配置映射文件(命名方式:domain实体类名称+Mapper.xml

       注意:

        ① 我们的映射文件在这里是和它对应的domain实体类在同一个层级
            ② 这个映射文件的名称一般叫做 XxxMapper.xml (Xxx代表的是实体类名称)
            ③ namespace的名称为了确定唯一性,请大家根据我的要求取名
                如我们有一个类:
                cn.itsource.domain.Product / cn.itsource.domain.Student
                那这里取名应该是:
                cn.itsource.domain.ProductMapper /cn.itsource.domain.StudentMapper
            ④ 类型都通通使用全限定名

    <?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">
    <!--
        这个Mapper的主要功能就是写sql
        mapper:根
        namespace:命令空间 (用来确定唯一性) 以前这个是可以不加的,现在必需加
         namespace的值,规则的:映射文件XxxMapper.xml所在的包+domain类名+Mapper
     -->
    <mapper namespace="cn.wang.domain.ProductMapper">
        <!--
            select : 这里面写查询语句
            id:sql语句的标识,在同一个namespace下不能重复
    
            parameterType : 传入的参数类型(原本应该用的是全限定名,这里用的是别名)  long:大Long  _long:小long (具体的对应请参见文档)
            resultType : 返回的结果类型(每一条数据返回的对象类型) 自己的对象一定是全限定类名(这里写的是别名)
         -->
        <select id="findOne" parameterType="long" resultType="Product">
            select * from product where id=#{id}
        </select>
        <!--别名不区分大小写-->
        <select id="findAll" resultType="product">
            select * from product
        </select>
    
        <insert id="insert" parameterType="product" keyProperty="id" useGeneratedKeys="true">
            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="long">
            UPDATE product set productName=#{productName} where id=#{id}
        </update>
    
        <delete id="delete" parameterType="long">
            delete FROM product where id=#{id}
        </delete>
    </mapper>

      5.最后进行测试

    public class MybatisTest {
        private IProductDao productDao=new ProductDaoImpl();
    
        @Test
        public void testFindOne(){
            Product product = productDao.findOne(1L);
            System.out.println(product);
        }
    
        @Test
        public void testFindAll(){
            List<Product> list = productDao.findAll();
            for (Product product : list) {
                System.out.println(product);
            }
        }
    
        @Test
        public void testInsert(){
            Product product = new Product();
            product.setProductName("大金刚");
            product.setDir_id(3L);
            product.setSalePrice(100.00);
            product.setSupplier("哈哈哈");
            product.setBrand("哇咔咔");
            product.setCutoff(0.66);
            product.setCostPrice(23.00);
    
            productDao.save(product);
            //获取新添加数据的主键,前提insert标签已经配置了那三个属性
            System.out.println(product.getId());
        }
    
        @Test
        public void testUpdate(){
           Product product = productDao.findOne(1L);
           product.setProductName("大罗金仙");
           productDao.update(product);
        }
        @Test
        public void testDelete(){
    
           productDao.delete(1L);
        }
    
    }

     

  • 相关阅读:
    Oracle中有大量的sniped会话
    Error 1130: Host '127.0.0.1' is not allowed to connect to this MySQL server
    汉字转换为拼音以及缩写(javascript)
    高效率随机删除数据(不重复)
    vs2010 舒服背景 优雅字体 配置
    mvc中的ViewData用到webfrom中去
    jquery ajax return值 没有返回 的解决方法
    zShowBox (图片放大展示jquery版 兼容性好)
    动感效果的TAB选项卡 jquery 插件
    loading 加载提示······
  • 原文地址:https://www.cnblogs.com/wanghj-15/p/11182482.html
Copyright © 2011-2022 走看看