美文网首页
MyBatis入门

MyBatis入门

作者: 一只96年的程序猿 | 来源:发表于2018-08-28 20:13 被阅读0次

    MyBatis入门

    MyBatis是一个第一类持久性框架,支持自定义SQL,存储过程和高级映射。MyBatis几乎消除了所有JDBC代码和手动设置参数以及检索结果。MyBatis可以使用简单的XML或Annotations来配置和映射基元,Map接口和Java POJO(Plain Old Java Objects)到数据库记录。

    优势
    1. 简化了JDBC的开发

    2. 能够更好的完成ORM(对象关系映射)

      1.Mybatis原理图

    MyBatis.png
    #### 2.准备环境
    
    (1)创建mybatisdb数据库,创建user表
       Create database mybatisdb;
       Use mybatisdb;
       Create table user(
       id int primary key auto_increment,
       name varchar(100),
       addr varchar(100),
       age int);
       Insert into user values(null,'guangtouqiang','北京',28);
       Insert into user values(null,'xiongda','上海',30);
       Insert into user values(null,'xiaonger','上海',19);
    
    (2)编译器引入dtd文件

    作为xml的约束文件,没连网的情况下也可以在编写xml时可以出现提示信息。

    dtd2.jpg 引入dtd.png

    3.MyBatis入门案例( 从XML构建SqlSessionFactory)

    (1)需求

    利用MyBatis框架查询user表中的所有数据

    (2)创建mybatisDemo的Java工程,并导入jar包
    (3)创建sqlMapConfig.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>
         <!-- 配置MyBatis开发环境 -->
         <environments default="test">
              <!-- 测试环境 -->  
             <environment id="test">
                 <!-- MyBatis事务交给JDBC管理 -->
                 <transactionManager type="JDBC"></transactionManager>
                 <!-- 配置数据源(连接池) -->
                 <dataSource type="POOLED">
                 <property name="driver" value="com.mysql.jdbc.Driver"/>
                 <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb"/>
                 <property name="username" value="root"/>
                 <property name="password" value="root"/>
                 </dataSource>
             </environment>
    ​
        <!-- 开发环境 -->
    ​
         </environments>
    ​
         <!-- 引入映射文件 -->
         <mappers>
             <!-- 引入UserMapper.xml -->
             <mapper resource="com/znonline/pojo/UserMapper.xml"/>
         </mappers>
     </configuration>
    
    (4)创建log4j.properties

    用来打印日志文件(SQL语句),可以很清楚的看到执行的sql和执行sql使用的参数。

    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
    
    (5)创建pojo对象

    POJO对象的属性名字要和数据库表字段的名字保持一致否则无法封装结果集

    package com.znonline.pojo;
    /**
     * User表
     */
    public class User {
    
        // id
        private int id;
        // 用户名
        private String name;
        // 地址
        private String addr;
        // 年龄
        private int age;
    
        public User() {
        }
    
        public User(int id, String name, String addr, int age) {
            this.id = id;
            this.name = name;
            this.addr = addr;
            this.age = age;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddr() {
            return addr;
        }
    
        public void setAddr(String addr) {
            this.addr = addr;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User [id=" + id + ", name=" + name + ", addr=" + addr + ", age=" + age + "]";
        }
    
    }
    
    (6) 创建映射文件UserMapper.xml

    在User类的同级包下,创建UserMapper.xml,代表这个文件是User对象的映射文件

      <?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="userns">
         <!-- 用来查询的SQL,
              id是该SQL的唯一标识 ,resultType是结果集要封装的实体(类的全路径)-->
         <select id="all" resultType="com.znonline.pojo.User">
         select * from user
         </select>
     </mapper>
    
    (7) sqlMapConfig.xml中引入UserMapper.xml

    上面已引入

    (8)创建UserTest类
    package com.znonline.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    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 org.junit.Test;
    
    import com.znonline.pojo.User;
    
    /**
     * 测试User
     * @author zn
     */
    public class UserTest {
    
        @Test
        public void FindUserAll() throws IOException {
            //1.创建会话工厂
            InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
            SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in);
    
            //2.创建Sqlsession,执行SQL
            SqlSession session = ssf.openSession();
            //定位SQL位置  (namespace值.id值)
            List list = session.selectList("userns.all");
    
            //3.处理结果集
            for(User u:list) {
                System.out.println(u);
            }
    
            //4.释放资源
            session.close();
        }
    }
    
    mybatisDemo演示.png

    4.综合案例 - Maven工程

    实现User表的CRUD

    (1)准备pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.znonline</groupId>
        <artifactId>mybatisDemoV2.0</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
            <!--添加mysql驱动程序依赖 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.40</version>
            </dependency>
        <!--整合junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
            </dependency>
        <!--整合mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.2.8</version>
            </dependency>
        <!--整合log4j日志 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
          <!--配置JDK1.7 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    
    (2).创建sqlMapConfig.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.znonline</groupId>
        <artifactId>mybatisDemoV2.0</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
            <!--添加mysql驱动程序依赖 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.40</version>
            </dependency>
        <!--整合junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
            </dependency>
        <!--整合mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.2.8</version>
            </dependency>
        <!--整合log4j日志 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
          <!--配置JDK1.7 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    
    (3).创建log4j.properties
    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
    
    (4).创建pojo对象
    (5).主体业务
    • Select

    Map:

      <!-- 查询User表中所有数据 -->
        <select id="findAll" resultType="zn.online.pojo.User">
        select * from user
        </select>
    
        <!-- 查询User表总记录数 -->
        <select id="count" resultType="int">
        select count(*) from user
        </select>
    
        <!-- 根据id查询User -->
        <select id="findById" resultType="zn.online.pojo.User" parameterType="int">
        select * from user where id=#{userId}
        </select>
    

    Test:

    /**
     * User 的CRUD操作
     * @author zn
     */
    public class UserTest {
    
        // 声明会话工厂,线程安全
        SqlSessionFactory ssf = null;
    
        /**
         * 测试前初始化步骤
         */
        @Before
        public void init() {
            InputStream in;
            try {
                //
                in = Resources.getResourceAsStream("sqlMapConfig.xml");
                ssf = new SqlSessionFactoryBuilder().build(in);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 查询User表中所有数据
         */
        @Test
        public void findAll() {
            SqlSession session = ssf.openSession();
            List list = session.selectList("userns.findAll");
            // 3.处理结果集
            for (User u : list) {
                System.out.println(u);
            }
            session.close();
        }
    
        /**
         * 查询User表总记录数
         */
        @Test
        public void count() {
            SqlSession session = ssf.openSession();
            int count = session.selectOne("userns.count");
            System.out.println("User_Table count:"+count);
            session.close();
        }
    
        /**
         * 根据id查询User
         */
        @Test
        public void findById() {
            SqlSession session = ssf.openSession();
            int userId = 3;
            User user = session.selectOne("userns.findById", userId);
            System.out.println(user);
            session.close();
        }
    }
    

    show:


    findAll.png Usercount.png
    UserfindById.png
    • Insert

    Map:

    <!-- 在User中新增一条记录 -->
        <insert id="save" parameterType="zn.online.pojo.User">
            insert into user values(null,#{name},#{addr},#{age})
        </insert>
    

    Test:

      /**
         * 在User中新增一条记录
         */
        @Test
        public void save() {
            SqlSession session = ssf.openSession();
    
            User user = new User();
            user.setName("lisi");
            user.setAddr("上海");
            user.setAge(21);
            session.insert("userns.save", user);
    
            // MyBatis需要手动提交事务
            session.commit();
            session.close();
        }
    
    Log/show: UserInsert.png
    • Update

    Map:

    <!-- 修改指定的记录 
        动态取值: #{age} age是User中对应的属性
        -->
        <update id="updateAgeByName" parameterType="zn.online.pojo.User">
            update user set age=#{age}
                where name=#{name}
        </update>
    

    Test:

    /**
         * 修改指定User名字的年龄
         */
        @Test
        public void updateAgeByName() {
            SqlSession session = ssf.openSession();
    
            User user = new User();
            user.setAge(25);
            user.setName("zhangsan");
            session.update("userns.updateAgeByName", user);
            session.commit();
            session.close();
        }
    
    Log/Show: UserUpdateAgeByName.png
    • Delete

    Map:

    <!-- 按id删除指定User表中的数据 -->
        <delete id="deleteById">
            delete from user where id=#{id}
        </delete>
    

    Test:

      /**
         * 按id删除指定User表中数据
         */
        @Test
        public void deleteById() {
            SqlSession session = ssf.openSession();
    
            int id = 3;
            session.delete("userns.deleteById", id);
            session.commit();
            session.close();
        }
    
    Log/Show:

    5.mybatis入门总结

    MyBatis的真正力量在于Mapped Statements。这就是魔术发生的地方。尽管功能强大,但Mapper XML文件相对简单。当然,如果您将它们与等效的JDBC代码进行比较,您会立即看到节省了95%的代码。MyBatis专注于SQL,并尽力避开您的方式。

    Mapper XML文件只有几个第一类元素(按照它们应该被定义的顺序):

    • cache- 为给定命名空间配置缓存。

    • cache-ref- 从另一个命名空间引用缓存配置。

    • resultMap- 描述如何从数据库结果集加载对象的最复杂和最强大的元素。

    • parameterMap~~~~- 已弃用!老派的方式来映射参数。内联参数是首选,将来可能会删除此元素。这里没有记录。

    • sql- 可重用的SQL块,可以被其他语句引用。

    • insert- 映射的INSERT语句。

    • update- 映射的UPDATE语句。

    • delete- 映射的DELETE语句。

    • select- 映射的SELECT语句。

    接下来的部分将详细描述每个元素,从语句本身开始。

    1.查询(select)

    <figure id="ag-204" class="ag-paragraph">

    Map标签 相关描述
    id 作为该SQL的唯一标志
    paramentType 代表要执行这个select语句需要传入一个类型为long的参数,即User对象的id
    resultType 完成ORM的映射关系所在
    返回的预期类型的​​完全限定类名或别名
    对于集合,这应该是集合包含的类型,而不是集合本身的类型

    </figure>

    <figure id="ag-232" class="ag-paragraph">

    Test查询可以使用的方法 相关描述
    selectList 代表这次调用的select语句查询的结果集会有一条以上的数据
    selectOne 返回一条数据,也可以用selectList方法,返回一个指定的数据

    </figure>

    2.新增(Insert)

    <figure id="ag-259" class="ag-paragraph">

    Map标签 相关描述
    id 作为这条SQL的唯一标志
    ParameterType 指定参数类型,通常制定一个对象类型
    flushCache 将此设置为true将导致在调用此语句时刷新第2级和本地缓存。
    默认值:对于insert,update和delete语句为true。
    timeout 这将设置驱动程序在抛出异常之前等待数据库从请求返回的最大秒数。
    默认为未设置(取决于驱动程序)
    statementType STATEMENT,PREPARED或CALLABLE中的任何一个
    默认值:PREPARED。

    </figure>

    <figure id="ag-296" class="ag-paragraph">

    Test查询可以使用的方法 相关描述
    Insert(String statement) 没有参数的话,直接执行查询的sql即可
    Insert(Stringstatement,Objectparam) 需要参数的话,可以传入

    </figure>

    3.修改(update)
    
    
    4.删除(delete)

    6.扩展

    1.别名

    在sqlMapConfig.xml中,可以使用typeAliases元素来简化开发的操作

    2.SQL中有特殊字符

    当SQL中有特殊字符<,mybatis不能正常解析时,用<![CDATA[??]]>括起来就解决了

    ``

    3. #和$取值的区别

    两种方式都可以获取参数的值。

    推荐能用#不用$:

    • {}(推荐!)

      1.相当于JDBC中的PreparedStatement,是经过预编译的,是安全的。

      2.会为参数自动拼接引号。

      3.执行SQL效果:select * from user whereuserId=”1”andpwd=”2”

    • ${}:

      1.相当于JDBC中的Statement ,未经过预编译,仅仅是取变量的值,是非安全的,存在SQL注入。

      2.执行SQL效果:select * from user whereuserId=1andpwd=2

    相关文章

      网友评论

          本文标题:MyBatis入门

          本文链接:https://www.haomeiwen.com/subject/kcaqwftx.html