zoukankan      html  css  js  c++  java
  • Mybatis入门和简单Demo

    一、Mybatis的诞生

      回顾下传统的数据库开发,JDBC和Hibernate是使用最普遍的技术,但这两种ORM框架都存在一定的局限性:

      JDBC:最原生的技术,简单易学,执行速度快,效率高,适合大数据量的操作,但存在代码繁琐,需要关心驱动的加载,连接的关闭等操作,对于分页等复杂用法,需要自己手动写代码实现。

      Hibernate:以面向对象的方式设计和访问,不用写SQL,不用管底层具体数据库的语法,但对于多表操作灵活性差,复杂的HQL难写难理解,执行速度慢,只适合小数据量的操作。

      基于上述技术的瓶颈,诞生了一种在这两者之间找到平衡点的ORM框架,结合它们的优点,摒弃它们的缺点,这就是myBatis,现今myBatis被广泛的企业所采用。MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)

    二、Mybatis入门Demo(基于MySQL)

      Mybatis程序的运行流程大概如下:

      (1)通过Reader对象读取src目录下的mybatis.xml配置文件(该文件名称可自定义,主要用来配置数据源,类型别名以及mapper文件的总配置文件)

      (2)通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象

      (3)从当前线程,即ThreadLocal中获取SqlSession对象
      (4)开启事务(默认开启)
      (5)通过SqlSession对象读取对应Mapper.xml映射文件中的操作编号,从而读取sql语句
      (6)提交或回滚事务
      (7)关闭SqlSession对象,并且分开当前线程与SqlSession对象,让GC尽早回收

      基于上述步骤开始Mybatis入门Demo案例的编写:

      步骤1.引入Mybatis所需jar包依赖

           <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.3.0</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.38</version>
            </dependency>
    
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.12</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.12</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency> 

      步骤2.准备数据源db.properties并配置mybatis.xml文件

    mysql.driver=com.mysql.jdbc.Driver
    mysql.url=jdbc:mysql://localhost:3306/aa
    mysql.username=root
    mysql.password=123456
    <?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>
    
        <!-- 加载类路径下的属性文件 -->
        <properties resource="db.properties">
        </properties>
        
        <!-- 设置实体类的类型别名 -->
        <typeAliases>
            <typeAlias type="com.jyk.mybatis.Student" alias="student"/>
        </typeAliases>
    
        <!-- 设置一个默认的连接环境信息,支持多数据源 -->
        <environments default="mysql_env">
            <!-- 连接环境信息,取一个唯一的编号 -->
            <environment id="mysql_env">
                <!-- mybatis使用的jdbc事务管理方式 -->
                <transactionManager type="jdbc">
                </transactionManager>
                
                <!-- mybatis使用连接池方式来获取链接 -->
                <dataSource type="pooled">
                    <!-- 配置与数据库交互的四个属性 -->
                    <property name="driver" value="${mysql.driver}"/>
                    <property name="url" value="${mysql.url}"/>
                    <property name="username" value="${mysql.username}"/>
                    <property name="password" value="${mysql.password}"/>
                </dataSource>
            </environment>
        </environments>
        
    <mappers> <mapper resource="com/jyk/mybatis/StudentMapper.xml"/> </mappers> </configuration>

      步骤3.编写需要操作的实体类com.jyk.mybatis.Student记录学生信息

    package com.jyk.mybatis;
    
    public class Student {
    
        private String id;
        private String name;
        private String age;
        private String sex;
        
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getAge() {
            return age;
        }
        public void setAge(String age) {
            this.age = age;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        
        public Student(String id, String name, String age, String sex) {
            super();
            this.id = id;
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
        
        public Student() {
            super();
        }
    }

      步骤4.配置StudentMapper.xml,配置namespace,需要唯一,一般以需要操作的实体类全路径为准,也可为其他值。然后是配置实体类与实际表的映射关系resultMap,type属性:实体全路径名,可在mybatis.xml文件中统一配置,如在上述mybatis.xml中已配置<typeAlias type="com.jyk.mybatis.Student" alias="student"/>,则此处实体类全路径可用student代替

      注:当实体属性名与表字段名不一样时,此处信息必配,若一致,则此处配置可选。

    <?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 namespace="studentNamespace">
        
        <!-- 
            resultMap标签:映射实体与表,非主键属性标签
            type属性:实体全路径名,可在mybatis.xml文件中统一配置
            id属性:为实体与表的映射取一个唯一的编号
         -->
        <resultMap type="student" id="studentMap">
            <!-- 
            id标签:映射主键属性
            result标签:映射非主键属性
            property属性:实体属性名
            column属性:表的字段名
             -->
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="age" column="age"/>
            <result property="sex" column="sex"/>
        </resultMap>
        
    </mapper>

      步骤5.编写Mybatis通用工具类,通过Reader对象读取src目录下的mybatis.xml配置文件,并测试连接

    package com.jyk.mybatis.util;
    
    import java.io.IOException;
    import java.io.Reader;
    import java.sql.Connection;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    /*
     * MyBatis工具类
     */
    public class MyBatisUtil {
    
        private static ThreadLocal<SqlSession> threadLocal = new
                ThreadLocal<SqlSession>();
        private static SqlSessionFactory sqlSessionFactory;
        
        //静态块加载src目录下的mybatis配置文件
        static{
            try {
                Reader reader = Resources.getResourceAsReader("mybatis.xml");
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        /*
         * 禁止外界通过new方法创建
         */
        private MyBatisUtil(){}
        
        /*
         * 获取sqlsession
         */
        public static SqlSession getSqlSession()
        {
            //从当前线程中获取sqlSession对象
            SqlSession sqlSession = threadLocal.get();
            
            //判断SqlSession对象是否为空
            if(sqlSession==null)
            {
                //在SqlSessionFactory对象非空的情况下,获取SqlSession对象
                sqlSession = sqlSessionFactory.openSession();
                //将SqlSession对象与当前线程绑定在一起
                threadLocal.set(sqlSession);
            }
            
            return sqlSession;
        }
        
        /*
         * 关闭sqlsession与当前线程分开
         */
        public static void closeSqlSession()
        {
            //从当前线程中获取SqlSession对象
            SqlSession sqlSession = threadLocal.get();
            
            if(sqlSession != null)
            {
                //关闭SqlSession对象
                sqlSession.close();
                //分开当前线程与SqlSession对象的关系,目的是尽早进行垃圾回收
                threadLocal.remove();
            }        
        }
        
        /*
         * 测试方法
         */
        public static void main(String[] args) {
            Connection conn = MyBatisUtil.getSqlSession().getConnection();
            if(conn==null)
            {
                System.out.println("连接为空");
            }
            else
            {
                System.out.println("连接不为空");
            }
        }
    }

      步骤6.编写CRUD语句,在mapper文件中编写,此处编写在上述已经配置好实体类映射的StudentMapper.xml文件中

    <?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 namespace="studentNamespace">
        
        <!-- 
            resultMap标签:映射实体与表
            type属性:实体全路径名
            id属性:为实体与表的映射取一个唯一的编号
         -->
        <resultMap type="student" id="studentMap">
            <!-- 
            id标签:映射主键属性
            result标签:映射非主键属性
            property属性:实体属性名
            column属性:表的字段名
             -->
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="age" column="age"/>
            <result property="sex" column="sex"/>
        </resultMap>
        
        <!-- 
        insert标签:sql插入语句
        id属性:该sql语句的唯一标签
        parameterType:要执行的dao中的方法的参数,如果是类的话,必须使用全路径名
        #{xx}:mybatis特有语法,用来替代jdbc中的?占位符
         -->
        <insert id="add1">
        insert into student(id,name,age,sex) values("1","admin","22","男")
        </insert>
        
        <insert id="add2" parameterType="student">
        insert into student(id,name,age,sex) values(#{id},#{name},#{age},#{sex})
        </insert>
        
        <!-- <insert id="add3" parameterType="student">
        insert into student(id,name,age,sex) values(#{id},#{name},#{age},#{sex})
        </insert> -->
    </mapper>

      步骤7.编写DAO,利用上述配置完成的文件和写好的通用工具类MyBatisUtil对学生信息进行增删该查

    package com.jyk.mybatis;
    
    import org.apache.ibatis.session.SqlSession;
    
    import com.jyk.mybatis.util.MyBatisUtil;
    
    public class StudentDao {
    
        /*
         * 增加的方法1
         */
        public void add1()
        {
            SqlSession sqlSession = null;
            try{
                sqlSession = MyBatisUtil.getSqlSession();
                //事务开始(默认)
                
                //读取StudentMapper.xml配置文件中的sql语句,对应的sql语句由{名称空间.sql的id指定}
                int i = sqlSession.insert("studentNamespace.add1");
                System.out.println("本次操作影响了"+i+"行数据");
                
                //事务提交
                sqlSession.commit();
            }catch(Exception e){
                e.printStackTrace();
                //事务回滚
                sqlSession.rollback();
                throw e;
            }finally{
                MyBatisUtil.closeSqlSession();
            }
        }
        
        /*
         * 增加的方法2
         */
        public void add2(Student stu)
        {
            SqlSession sqlSession = null;
            try{
                sqlSession = MyBatisUtil.getSqlSession();
                //事务开始(默认)
                
                //读取StudentMapper.xml配置文件中的sql语句
                int i = sqlSession.insert("studentNamespace.add2",stu);
                System.out.println("本次操作影响了"+i+"行数据");
                
                //事务提交
                sqlSession.commit();
            }catch(Exception e){
                e.printStackTrace();
                //事务回滚
                sqlSession.rollback();
                throw e;
            }finally{
                MyBatisUtil.closeSqlSession();
            }
        }
        
        /*
         * 增加的方法3
         * 往数据库添加记录必须要添加事务,没有事务添加不进去
         */
        public void add3(Student stu)
        {
            SqlSession sqlSession = null;
            try{
                sqlSession = MyBatisUtil.getSqlSession();
                //事务开始(默认)
                
                //读取StudentMapper.xml配置文件中的sql语句
                int i = sqlSession.insert("studentNamespace.add3",stu);
                System.out.println("本次操作影响了"+i+"行数据");
                sqlSession.commit();
            }catch(Exception e){
                e.printStackTrace();
                //事务回滚
                sqlSession.rollback();
                throw e;
            }finally{
                MyBatisUtil.closeSqlSession();
            }
        }
        
        public static void main(String[] args) {
            StudentDao sd = new StudentDao();
            sd.add1();
            sd.add2(new Student("64","kaiye","23","男"));
        }
    }
  • 相关阅读:
    Zookeeper初见
    常见一致性协议(二)
    常见一致性协议(一)
    分布式理论基础
    expose a port on a living Docker container
    tomcat远程调试参数备忘
    bash: ifconfig: command not found
    解决 :java -version出现错误:“could not open `C:Program FilesJavajre7libamd64jvm.cfg”
    centos7 安装 NVIDIA Docker
    解决: httpclient ssl 验证导致死锁问题
  • 原文地址:https://www.cnblogs.com/jiyukai/p/9440494.html
Copyright © 2011-2022 走看看