zoukankan      html  css  js  c++  java
  • MyBatis快速入门(第一天)

    一、MyBatis快速入门

    (一)开发步骤介绍

    1、创建MyBatis_db数据库和person

    2、创建java项目,引入MyBatis坐标

    3、创建User实体类

    4、编写映射文件PersonMapper.xml

    5、编写配置文件SqlMapConfig.xml

    6、编写测试类

    (二) 代码实现

    1、创建对应的数据库的表 person

      create table person(

           id int primary key auto_increment,

           name varchar(32),

           bir date ,

           address varcahr(32)

    );

    2、导入MyBatis框架依赖

     <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>

    </dependencies>

    <build>

        <!--规定  java包下的配置文件 编译之后照样生效-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>

    </build>

     

    3、创建数据模型

    public class Person implements Serializable {

     private int id;

     private String name;

     private Date bir;

     private String address; 

      //提供set和get方法部分省略

    }

     

    4、创建接口对应映射文件PersonMapper.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">

      <mapper namespace="PersonMapper">   

         <select id="findAll" resultType="com.offcn.bean.Person">

              select * from  person

         </select>      

    </mapper>

     

    5、在src下创建MyBatis的核心配置文件 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>

    <!--环境配置-->

    <environments default="MySQL">

    <!--使用MySQL环境-->

    <environment id="MySQL">

    <!--使用JDBC类型事务管理器-->

    <transactionManager type="JDBC"></transactionManager>

    <!--使用连接池-->

    <dataSource type="POOLED">

    <property name="driver" value="com.MySQL.jdbc.Driver"></property>

    <property name="url" value="jdbc:MySQL://localhost:3306/0423dbs"/>  

    <property name="username" value="root"></property>

    <property name="password" value="root"></property>

    </dataSource>

    </environment>

    </environments>

    <!--加载映射配置-->

    <mappers>

    <mapper resource="com/offcn/mapper/PersonMapper.xml"></mapper>

    </mappers>

    </configuration>

     

    6、编码测试

    @Test

    public void testFindAll() throws Exception {

    // 加载核心配置文件

    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    // 获取SqlSessionFactory工厂对象

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    // 获取SqlSession会话对象

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 执行sql

    List<User> list = sqlSession.selectList("PersonMapper.findAll");

    for (Person person: list) {

     System.out.println(person);

     }

    // 释放资源

    sqlSession.close();

    }

    (三) 配置文件概述    

    1SqlMapConfig.xml配置文件

       这个配置文件是整个Mybatis的核心配置文件,在这个配置文件中我们主要进行了整个数据库交互的整体配置,例如数据库的连接,事务的管理,映射文件的加载,这个配置文件我们只需要操作一次即可,不需要频繁改动。

     

    2PersonMapper.xml配置文件

     <mapper namespace="PersonMapper">   

         <select id="findAll" resultType="com.offcn.bean.Person">

              select * from  person

         </select>      

    </mapper>

    namespace属性:属性的值我们可以任意定义的一个字符串(做到见名知意),用来作为映射sql的一个部分,

    id:我们sql语句的唯一标记

    resultType:我们查询数据的结果类型。

    二、MyBatis增删改查

    (一) 使用MyBatis完成增删改操作

    1、新增操作

     

    编写映射文件PersonMapper.xml

    <mapper namespace="PersonMapper">

    <!--新增-->

    <insert id="insert" parameterType="com.offcn.bean.Person">

    insert into user(name,bir,address) values(#{name},#{bir},#{address})

    </insert>

    </mapper>

     

    编写测试类

    @Test

    public void save() throws Exception {

    // 加载核心配置文件

    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    // 获取SqlSessionFactory工厂对象

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    // 获取SqlSession会话对象

    SqlSession sqlSession = sqlSessionFactory.();

    Person person = new Person();

    person.setName(“张三”);

    person.setBir(new java.util.Date());

    person.setAddress(“上海”);

    // 执行sql

    sqlSession.insert("PersonMapper.insert", person);

    //提交事务

    sqlSession.commit();

    // 释放资源

    sqlSession.close();

    }

    2、更新操作

    <mapper namespace="PersonMapper">

    <!--修改-->

     <update id="update" parameterType="com.offcn.bean.Person">

    update person set name= #{name},bir= #{bir},address = #{address} where id = #{id}

     </update>

     </mapper>

     

    编写测试类

    @Test

    public void updateInfo() throws Exception {

    // 加载核心配置文件

    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    // 获取SqlSessionFactory工厂对象

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    // 获取SqlSession会话对象

    SqlSession sqlSession = sqlSessionFactory.();

    Person person = new Person();

    person.setName(“李四”);

    person.setBir(new java.util.Date());

    person.setAddress(“北京”);

    // 执行sql

    sqlSession.update("PersonMapper.update", person);

    //提交事务

    sqlSession.commit();

    // 释放资源

    sqlSession.close();

    }

     

    3、删除操作

    <mapper namespace="PersonMapper">

    <!--删除--> <delete id="delete" parameterType="java.lang.Integer">

        delete from person where id = #{id}

    </delete>

    </mapper>

     

    编写测试类

    @Test

    public void updateInfo() throws Exception {

    // 加载核心配置文件

    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    // 获取SqlSessionFactory工厂对象

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    // 获取SqlSession会话对象

    SqlSession sqlSession = sqlSessionFactory.();

    // 执行sql

    sqlSession.delete("PersonMapper.delete", 50);

    //提交事务

    sqlSession.commit();

    // 释放资源

    sqlSession.close();

    }

    (二)使用抽取的工具类完成操作

    1、制作统一的工具类

    public class MyBatisUtils {

    private static SqlSessionFactory sqlSessionFactory = null;

    static {

    try {

    // 加载核心配置文件

    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    // 获取SqlSessionFactory工厂对象

    sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    } catch (IOException e) {

     throw new RuntimeException("加载Mybatis配置文件失败");

    }

    }

    // 获取SqlSession会话对象

    public static SqlSession openSession() {

    return sqlSessionFactory.openSession();

    }

    }

    2、抽取测试类代码基类

    public class TestBaseMapper {

    protected SqlSession sqlSession = null;

     

    @Before

     public void before() {

    sqlSession = MyBatisUtils.openSession();

    }

    @After

    public void after() {

    sqlSession.commit();

    sqlSession.close();

    }

    }

    3、使用工具类完成操作

    public class UserTest extends TestBaseMapper {

    @Test public void testFindAll() throws Exception {

    // 执行

    sql List<User> list = sqlSession.selectList("PersonMapper.findAll");

    for (User user : list) {

    System.out.println(user);

    }

    }

     }

    (三) MyBatis核心配置文件详解

    1MyBatis核心配置文件层级关系

     

    2environments标签

    数据库环境的配置,支持多环境配置

     

    (1) 其中,事务管理器(transactionManager)类型有两种:

    * JDBC: 这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。

    * MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。 例如:mybatisSpring整合后,事务交给Spring容器管理。

    (2) 其中,数据源(dataSource)类型有三种:

    * UNPOOLED: 这个数据源的实现只是每次被请求时打开和关闭连接。

    * POOLED:这种数据源的实现利用的概念将 JDBC 连接对象组织起来。

    * JNDI: 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据 源,然后 放置一个 JNDI 上下文的引用

     

    3mappers标签

    该标签的作用是加载映射的,加载方式有如下几种:

    (1) 使用相对于类路径的资源引用,

    例如: <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>

    (2) 使用完全限定资源定位符(URL),

    例如: <mapper url="file:///var/mappers/AuthorMapper.xml"/>

    (3) 使用映射器接口实现类的完全限定类名,

    例如: <mapper class="org.mybatis.builder.AuthorMapper"/>

    (4) 将包内的映射器接口实现全部注册为映射器,例如:

    <package name="org.mybatis.builder"/>

     

    4properties标签

    实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties

    <properties resource="org/mybatis/example/jdbc.properties">

     

    5typeAliases标签

    类型别名是为 Java 类型设置一个短的名字。

    为了简化映射文件 Java 类型设置,mybatis框架为我们设置好的一些常用的类型的别名:

     

    原来的类型名称配置如下:

     

     

    配置typeAliases,为com.offcn.bean.Person定义别名为person,SqlMapConfig.xml配置别名:

    <typeAliases>

      <typeAlias alias="person" type="com.offcn.bean.Person"/>

    </typeAliases>

    PersonMapper.xml中使用别名:

    <select id="findAll" resultType="person">

        select * from  person

    </select>

    (四) MyBatis核心API概述

    1Resources

    加载mybatis的配置文件。

    // 加载核心配置文件

    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

     

    2SqlSessionFactoryBuilder

    利用Resources指定的资源,将配置信息加载到内存中,还会加载mybatis配置文件中指定的所有映射配置信息,并

    用特定的对象实例进行保存,从而创建SqlSessionFactory对象。

    // 构建SqlSessionFactory对象

    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(inputStream);

     

    3SqlSessionFactory

    这是一个工厂对象,对于这种创建和销毁都非常耗费资源的重量级对象,一个项目中只需要存在一个即可。 也就是说,它的生命周期跟项目的生命周期是一致的(项目不亡,我不销毁)

    它的任务是创建SqlSession

    // 默认开启一个事务,但事务不会自动提交,需要手动提交事务,DML语句才会持久化到数据库中

    SqlSession openSession();

     // 参数为是否开启自动提交,如果设置为true,那么不需要手动提交事务

    SqlSession openSession(boolean autoCommit);

     

    4SqlSession

    这是Mybatis的一个核心对象。我们基于这个对象可以实现对数据的CRUD操作。

    对于这个对象应做到每个线程独有,每次用时打开,用完关闭。

    执行语句的方法主要有:

    <T> T selectOne(String statement, Object parameter);

    <E> List<E> selectList(String statement, Object parameter);

    int insert(String statement, Object parameter);

    int update(String statement, Object parameter);

    int delete(String statement, Object parameter);

     

    (五) MyBatis的执行原理

     

    详细流程如下:

    1、加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着<select | update | delete | insert>标签项。

    2SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession

    3SqlSession对象完成和数据库的交互:

    1用户程序调用mybatis接口层api(即Mapper接口中的方法)

    2SqlSession通过调用apiStatement ID找到对应的MappedStatement对象

    3通过Executor(负责动态SQL的生成和查询缓存的维护)将MappedStatement对象进行解析,sql参数转化、动态sql拼接,生成jdbc Statement对象

    4JDBC执行sql

    5借助MappedStatement中的结果映射关系,将返回结果转化成HashMapJavaBean等存储结构并返回。

    三、MyBatis基于接口代理方式实现Dao层开发

    (一)基于接口代理方式实现Dao的开发

    1、介绍

    采用 Mybatis 的基于接口代理方式实现 持久层 的开发,这种方式是我们后面进入企业的主流。

    基于接口代理方式的开发只需要程序员编写 Mapper 接口,Mybatis 框架会为我们动态生成实现类的对象。

    这种开发方式要求我们遵循一定的规范:

    Mapper.xml映射文件中的namespacemapper接口的全限定名相同

    Mapper接口方法名和Mapper.xml映射文件中定义的每个statementid相同

    Mapper接口方法的输入参数类型和mapper.xml映射文件中定义的每个sqlparameterType的类型相同

    Mapper接口方法的输出参数类型和mapper.xml映射文件中定义的每个sqlresultType的类型相同

     

    2、实现步骤

    1) 编写接口 PersonMapper

    public interface UserMapper {

    public List<User> findAll() throws Exception;

    }

    2) 编写PersonMapper.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">

    <mapper namespace="com.offcn.mapper.PersonMapper">

       <!--查询所有-->

       <select id="findAll" resultType="person">

    select  *  from  person

       </select>

    </mapper>

    3)测试

    @Test

    public void testFindAll() throws Exception {

    // 加载核心配置文件

    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    // 获得SqlSessionFactory工厂对象

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    // 获得SqlSession会话对象

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 获得Mapper代理对象

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    // 执行查询

    List<User> list = userMapper.findAll(); for (User user : list) {

    System.out.println(user);

    }

    // 释放资源

    sqlSession.close();

    }

    3、基于代理实现的内部执行原理

    我们的持久层现在只有一个接口,而接口是不实际干活的,那么是谁在做findAll的实际工作呢?

    下面通过追踪源码看一下:

    1)通过追踪源码我们会发现,我们使用的mapper实际上是一个代理对象,是由MapperProxy代理产生的。

     

    2)追踪MapperProxyinvoke方法会发现,其最终调用了mapperMethod.execute(sqlSession, args)

     

    3)进入execute方法会发现,最终工作的还是sqlSession

     

    (二) MyBatis高级查询

    1ResultMap标签

    如果数据库结果集中的列名和要封装的javaBean的属性名有不一致的情况下,我们查询的结果中不一致的属性值会为null,这个时候我们可以使用 resultMap 标签手动的建立映射关系,很好的解决数据不对应的问题。

     

    (1) 编写接口PersonMapper

    public interface PersonMapper {

    public List<User> findAllResultMap();

    }

    (2) 编写PersonMapper.xml

    <mapper namespace="com.offcn.mapper.PersonMapper">

    <!--手动映射对象-->

    <resultMap id="personResultMap" type="person">

    <id column="id" property="id"></id>

    <result column="name" property="name"></result>

    <result column="bir" property="bir"></result>

    <result column="address" property="address"></result>

    </resultMap>

    <!--查询所有 resultMap-->

    <select id="findAllResultMap" resultMap="personResultMap">

    select id as id, name, bir, address from person

    </select>

    </mapper>

    (3) 测试

    @Test

    public void testFindAllResultMap() throws Exception {

    PersonMapper personMapper = sqlSession.getMapper(PersonMapper .class);

    List<Person> list = personMapper .findAllResultMap();

    for (Person person : list) {

      System.out.println(person);

    }

    }

    (三) MyBatis多参数处理

    MyBatis中方法中出现了多个参数的处理方式:

     

    1、第一种使用方法索引

    使用java方法的默认规范,参数是有索引,我们需要在sql中指定参数的的索引位置

    <select>

    select * from person where id=#{参数索引} and name=#{参数索引}  

    </select>

     

    2、第二种mapkey

    使用map集合的方式传入多个参数值,在sql中我们使用map中的key来映射值

    <select>

    select * from person where id=#{mapkey} and name=#{mapkey}

    </select>

     

    3、第三种使用注解

    使用MyBatis的注解 @Param("定义参数在sql中的应用名称"),在定义方法的时候声明sql中使用参数的名字

    <select>

    select * from person where id=#{ddi} and name=#{nnmae}

    </select>

     

    3、 第四种 使用自身封装的对象

    <select>

    select * from person where id=#{id} and name=#{name}

    </select>

    (四) 模糊查询

    1、占位符方式

    1)构建PersonMapper接口

    public interface PersonMapper {

    public List<Person> findByName(String name);

    }

     

    2)构建PersonMapper.xml

    <mapper namespace="com.offcn.mapper.PersonMapper">

    <select id="findByName" parameterType="string" resultType="person">

      select * from person where name like #{name}

    </select>

    </mapper>

     

    3)测试

    @Test

    public void testFindByUsername() throws Exception {

    PersonMapper personMapper= sqlSession.getMapper(PersonMapper.class);

    List<Person> list = personMapper.findByName("%%");

    for (Person person: list) {

    System.out.println(person);

    }

    }

    2、字符串拼接方式

    1)构建PersonMapper接口

    public interface PersonMapper{

    public List<Person> findByName(String name);

    }

     

    2)构建PersonMapper.xml

    <mapper namespace="com.offcn.mapper.PersonMapper">

    <!-- 不推荐使用,因为Oracle数据库 除了设置别名其余位置不能使用 双引号 -->

    <select id="findByName" parameterType="string" resultType="person">

    select * from person where name like "%"#{name}"%"

    </select>

    </mapper>

     

    3)测试

    @Test

    public void testFindByUsername() throws Exception {

    PersonMapper personMapper= sqlSession.getMapper(PersonMapper.class);

    List<Person>  list = personMapper.findByName("");

    for (Person person: list) {

    System.out.println(person);

    }

    }

    3$的拼接方式

    (3)构建PersonMapper 接口

    public interface PersonMapper {

    public List<Person> findByName(String name);

    }

     

    构建PersonMapper.xml

    <mapper namespace="com.offcn.mapper.PersonMapper ">

    <!--不推荐使用,因为会出现sql注入问题-->

    <select id="findByName" parameterType="string" resultType="person">

    select * from person where name like '%${value}%'

    </select>

    </mapper>

    测试

    @Test

    public void testFindByName() throws Exception {

    PersonMapper personMapper= sqlSession.getMapper(PersonMapper.class);

    List<Person>  list = personMapper.findByName("");

    for (Person person: list) {

    System.out.println(person);

    }

    }

    4、使用函数拼接数据

    1)构建PersonMapper 接口

    public interface PersonMapper {

    public List<Person> findByName(String name);

    }

     

    2)构建PersonMapper.xml

    <mapper namespace="com.offcn.mapper.PersonMapper">

    <!-- 推荐使用,concat() 字符串拼接函数 注意:在Oracle中,concat() 函数只能传递二次参数,我们解决方案是嵌套拼接 -->

    <select id="findByName" parameterType="string" resultType="person">

    select * from person where name like concat(concat('%',#{name}),'%');

    </select>

    </mapper>

     

    3)测试

    @Test

    public void testFindByName() throws Exception {

    PersonMapper personMapper= sqlSession.getMapper(PersonMapper.class);

    List<Person>  list = personMapper.findByName("");

    for (Person person: list) {

    System.out.println(person);

    }

    }

     

    总结:${} #{} 区别

    #{} :表示一个占位符号

    通过 #{} 可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。#{} 可以接收简单类型值或pojo属性值。

    如果parameterType传输单个简单类型值, #{} 括号中可以是value或其它名称。

     

    ${} :表示拼接sql

    通过 ${} 可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,会出现sql注入问题。

    ${} 可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值, ${} 括号中可以使任意名称

     

  • 相关阅读:
    AC自动机---病毒侵袭
    线段树或树状数组---Flowers
    AC自动机---Keywords Search
    AC自动机基础知识讲解
    线段树---Atlantis
    状态压缩DP---Hie with the Pie
    状态压缩DP--Mondriaan's Dream
    【PAT-并查集-水题】L2-007-家庭房产
    【PAT-一道看着很难的水题】L2-023. 图着色问题
    【二叉搜索树】PAT-天梯赛- L2-004. 这是二叉搜索树吗?
  • 原文地址:https://www.cnblogs.com/masterhxh/p/13806928.html
Copyright © 2011-2022 走看看