zoukankan      html  css  js  c++  java
  • Mybatis

    Mybatis

    1、mybatis介绍

    mybatis是sqlmap技术,对jdbc进行封装,将大量的sql语句外部化。

    2、体验mybatis

    1. 准备数据库和表

      mysql>create table users(id int primary key auto_increment , 
                               name varchar(20) , 
                               age int) ;
      
    2. 创建模块引入maven依赖

      [pom.xml]

      <?xml version="1.0" encoding="UTF-8"?>
      <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.oldboy</groupId>
        <artifactId>mybatis</artifactId>
        <version>1.0-SNAPSHOT</version>
      
        <dependencies>
          <!-- mysql驱动 -->
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.17</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.1</version>
          </dependency>
        </dependencies>
      </project>
      
    3. 创建javabean

      /**
       * User类
       */
      public class User {
        private Integer id;
        private String name ;
        private int age ;
      
        //get//set
      }
      
    4. 创建映射文件

      [resources/UserMapper.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="users">
        <!-- 定义insert语句 ,获得生成的id字段-->
        <insert id="insert" >
          insert into users(name,age) values(#{name},#{age})
        </insert>
      </mapper>
      
    5. 创建配置文件

      [resources/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>
        <properties>
          <property name="driver" value="com.mysql.jdbc.Driver"/>
          <property name="url" value="jdbc:mysql://localhost:3306/big12"/>
          <property name="username" value="root"/>
          <property name="password" value="root"/>
        </properties>
        <environments default="development">
          <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
              <property name="driver" value="${driver}"/>
              <property name="url" value="${url}"/>
              <property name="username" value="${username}"/>
              <property name="password" value="${password}"/>
            </dataSource>
          </environment>
        </environments>
        <mappers>
          <mapper resource="UserMapper.xml"/>
        </mappers>
      </configuration>
      
      
    6. 编写测试类,实现插入

    @Test
    public void testInsert() throws IOException {
    //加载配置文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //创建会话工厂(builder模式)
    SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
    //开启会话,相当于连接
    SqlSession sess = sf.openSession();
    
    User u = new User() ;
    u.setName("tom");
    u.setAge(12);
    //执行插入操作
    sess.insert("users.insert" , u) ;
    sess.commit();
    sess.close();
    }
    

    3、实现mybatis的基本操作

    3.1 update

    1. 在映射文件中增加update语句

      <?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="users">
        <update id="update">
          update users set name = #{name} , age = #{age} where id = #{id}
        </update>
      </mapper>
      
    2. 调用session.update方法

      ...
      User u = new User() ;
      u.setName("tomas");
      u.setAge(22);
      u.setId(1);
      sess.update("users.update" , u) ;
      

    3.2 select

    3.2.1 查询一个
    1. 映射文件增加查询语句

      [userMapper.xml]

      ...
      <select id="selectById" resultType="_User">
        select * from users where id = #{id}
      </select>
      ...
      
    2. 配置文件添加别名

      [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>
        ...
        <typeAliases>
          <typeAlias type="com.oldboy.mybatis.domain.User" alias="_User"/>
        </typeAliases>
        ...
      </configuration>
      

    3. API调用

      User u = sess.selectOne("users.selectById" , 1) ;
      
    3.2.2 查询多个
    1. 添加sql语句

      [userMapper.xml]

      ...
      <select id="selectAll" resultType="_User">
        select * from users
      </select>
      ...
      
    2. API调用

      List<User> list = sess.selectList("users.selectAll" ) ;
      

    3.3 delete

    1. 添加sql语句

      [UserMapper.xml]

      ...
      <delete id="delete">
        delete from users where id = #{id}
      </delete>
      ...
      
    2. API调用

      sess.delete("users.delete" , 1) ;
      

    4、获取数据库主键值

    1. 数据表如果主键是自动增长的话,如果要在程序插入时得到主键值可修改映射文件,具体如下:

      [UserMapper.xml]

      <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        ...
      </insert>
      

    2. 测试代码:

    User u = new User();
    sess.insert("users.insert" , u) ;
    

    5、关联关系

    5.1 多对一关联

    5.1.1 保存
    1. 创建订单表,并设置外键约束

      -- 创建表
      mysql>create table orders(id int primary key auto_increment,
                                orderno varchar(20) ,
                                price float ,
                                cid int);
      -- 添加外键约束
      mysql>alter table orders add constraint foreign key fk_cid_user_id (cid) REFERENCES users (id) ;
      
    2. 创建Order类

      /**
       * 订单类
       */
      public class Order {
        private Integer id ;
        private String orderNo ;
        private float price ;
        //建立多对一关联关系
        private User user ;
        //get/set
      }
      

    3. 创建映射文件

      [OrderMapper.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="orders">
        <insert id="insert">
          insert into orders(orderno , price , cid) values(#{orderNo} ,#{price} , 
          												#{user.id})
        </insert>
      </mapper>
      
    4. API

      User u = new User();
      u.setId(2);
      
      Order o = new Order();
      o.setOrderNo("no001");
      o.setPrice(2000);
      //设置关联关系
      o.setUser(u);
      sess.insert("orders.insert" , o) ;
      

    5.5.2 查询
    1. 修改映射文件

      [OrderMapper.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="orders">
        <insert id="insert">
          insert into orders(orderno , price , cid) values(#{orderNo} ,#{price} , #{user.id})
        </insert>
        <select id="selectOne" resultMap="rmOrder">
          select
            o.id oid , 
            o.orderno oorderno,  
            o.price oprice , 
            u.id uid ,
            u.name uname , 
            u.age uage
          from orders o
          	left outer join users u on o.cid = u.id
          where 
          	o.id = #{id}
        </select>
      
        <!-- 定义结果映射,将字段和类属性关联在一起 -->
        <resultMap id="rmOrder" type="_Order">
          <id column="oid" property="id"/>
          <result column="oorderno" property="orderNo" />
          <result column="oprice" property="price" />
          <association property="user" javaType="_User" column="uid">
            <id column="uid" property="id"/>
            <result column="uname" property="name" />
            <result column="uage" property="age" />
          </association>
        </resultMap>
      </mapper>
      

    2. API查询

      sess.selectOne("orders.selectOne" , 3) ;
      

    5.2 一对多关联

    一对多关联使用collection集合方法进行关联,表示one方有多个many实例。

    1. 修改User类,添加orders集合属性

      class User{
        ...
        private List<Order> orders = new ArrayList<Order>() ;
        //get/set
      }
      

    2. 修改UserMapper.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="users">
        <!-- 定义insert语句 ,获得生成的id字段-->
        <insert id="insert" useGeneratedKeys="true" keyProperty="id">
          insert into users(name,age) values(#{name},#{age})
        </insert>
      
        <update id="update">
          update users set name = #{name} , age = #{age} where id = #{id}
        </update>
      
        <delete id="delete">
          delete from users where id = #{id}
        </delete>
      
        <select id="selectById" resultMap="rmUser">
          SELECT
          u.id uid,
          u.name uname,
          u.age uage ,
          o.id oid ,
          o.orderno oorderno ,
          o.price oprice
          from
          users u left OUTER join orders o on o.cid = u.id
          WHERE
          u.id = #{id}
        </select>
        <select id="selectAll" resultType="_User">
          select * from users
        </select>
        <!-- 用户映射 -->
        <resultMap id="rmUser" type="_User">
          <id column="uid" property="id" />
          <result column="uname" property="name" />
          <result column="uage" property="age"/>
          <collection property="orders" ofType="_Order" column="uid">
            <id column="oid" property="id" />
            <result column="oorderno" property="orderNo" />
            <result column="oprice" property="price"/>
          </collection>
        </resultMap>
      </mapper>
      

    3. 测试用例

      sess.selectOne("users.selectById" , 2) ;
      

    5.3 三级多对一关联

    1. 引入OrderItem(订单项)类

      class OrderItem{
        private Integer id ;
        private String iname ;
        private Order order ;
        //get/set
      }
      
    2. 设置Order到OrderItem之间的关联

      class Order{
        //toOne
        private User user ;
        //toMany
        private List<OrderItem> items = new ArrayList<OrderItem>() ;
      }
      
      class User{
        ...
          private List<Order> orders = new ArrayList<Order>() ;
      }
      

    3. 编写映射文件

      • 查询Order

        [OrderMapper.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="orders">
          <insert id="insert" useGeneratedKeys="true" keyProperty="id">
            insert into orders(orderno , price , cid) values(#{orderNo} ,#{price} , #{user.id})
          </insert>
          <select id="selectOne" resultMap="rmOrder">
            select
            	o.id oid , 
            	o.orderno oorderno,
            	o.price oprice, 
            	u.id uid , 
            	u.name uname ,
            	u.age uage , 
            	i.id iid , 
            	i.iname iiname
            from
            	orders o
            	left outer join users u on o.cid = u.id
            	left outer join orderitems i on i.oid = o.id
            where
            	o.id = #{id}
          </select>
        
          <resultMap id="rmOrder" type="_Order">
            <id column="oid" property="id"/>
            <result column="oorderno" property="orderNo" />
            <result column="oprice" property="price" />
            <association property="user" javaType="_User" column="uid">
              <id column="uid" property="id"/>
              <result column="uname" property="name" />
              <result column="uage" property="age" />
            </association>
            <collection property="items" ofType="_Item" column="oid">
              <id column="iid" property="id" />
              <result column="iiname" property="iname" />
            </collection>
          </resultMap>
        </mapper>
        
      • 查询OrderItem

        [OrderItem.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="orderitems">
          <insert id="insert" useGeneratedKeys="true" keyProperty="id">
            insert into orderitems(iname, oid) values(#{iname} ,#{order.id})
          </insert>
        
          <select id="selectOne" resultMap="rmItem">
            select
            	o.id oid , 
            	o.orderno oorderno,
            	o.price oprice, 
            	u.id uid , 
            	u.name uname ,
            	u.age uage , 
            	i.id iid , 
            	i.iname iiname
            from
            	orderitems i
            	left outer join orders o on i.oid = o.id
            	left outer join users u on o.cid = u.id
            where 
            	i.id = #{id} ;
          </select>
          <resultMap id="rmItem" type="_Item">
            <id column="iid"  property="id" />
            <result column="iiname" property="iname"/>
            <association property="order" column="oid" javaType="_Order">
              <id column="oid"  property="id"/>
              <result column="oorderno"  property="orderNo"/>
              <result column="oprice" property="price"/>
              <association property="user" column="uid" javaType="_User">
                <id column="uid" property="id" />
                <result column="uname" property="name"/>
                <result column="uage" property="age" />
              </association>
            </association>
          </resultMap>
        </mapper>
        
      • 查询User

        [UserMapper.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="users">
          <!-- 定义insert语句 ,获得生成的id字段-->
          <insert id="insert" useGeneratedKeys="true" keyProperty="id">
            insert into users(name,age) values(#{name},#{age})
          </insert>
        
          <update id="update">
            update users set name = #{name} , age = #{age} where id = #{id}
          </update>
        
          <delete id="delete">
            delete from users where id = #{id}
          </delete>
        
          <select id="selectById" resultMap="rmUser">
            select
            	o.id oid , 
            	o.orderno oorderno,
            	o.price oprice, 
            	u.id uid , 
            	u.name uname ,
            	u.age uage , 
            	i.id iid , 
            	i.iname iiname
            from
            	users u
           	 	left outer join orders o on o.cid = u.id
            	left outer join orderitems i on i.oid = o.id
            where 
            	u.id = #{id}
          </select>
          <select id="selectAll" resultType="_User">
            select * from users
          </select>
          <!-- 用户映射 -->
          <resultMap id="rmUser" type="_User">
            <id column="uid" property="id" />
            <result column="uname" property="name" />
            <result column="uage" property="age"/>
            <collection property="orders" ofType="_Order" column="uid">
              <id column="oid" property="id" />
              <result column="oorderno" property="orderNo" />
              <result column="oprice" property="price"/>
              <collection property="items" ofType="_Item" column="oid">
                <id column="iid" property="id"/>
                <result column="iiname" property="iname" />
              </collection>
            </collection>
          </resultMap>
        </mapper>
        

    5.4 多对一自关联

    区域信息时典型的自关联信息,自己和自己进行关联。

    5.4.1 表结构
    id areaname parentid
    1 全国 NULL
    2 河北 1
    3 河南 1
    4 保定 2
    5.4.2 类设计
    public class Area {
      private Integer id ;
      private String areaName ;
      private Area parentArea ;
      private List<Area> children = new ArrayList<Area>();
      //get/set
    }
    
    5.4.3 映射方式
    <?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="areas">
      <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into areas(areaname, pid) values(#{areaName} , #{parentArea.id})
      </insert>
    
      <select id="selectOne" resultMap="rmArea">
        select
          a.id aid ,
          a.areaname aareaname ,
          b.id bid ,
          b.areaname bareaname ,
          c.id cid ,
          c.areaname careaname
        from
          areas a
          left OUTER  join areas b on b.pid = a.id
          left OUTER  join areas c on c.pid = b.id
        WHERE
          a.id = #{id}
      </select>
    
      <resultMap id="rmArea" type="_Area">
        <id column="aid" property="id"/>
        <result column="aareaname" property="areaName" />
        <collection property="children" ofType="_Area" column="aid">
          <id column="bid" property="id" />
          <result column="bareaname" property="areaName"/>
          <collection property="children" ofType="_Area" column="bid">
            <id column="cid" property="id" />
            <result column="careaname" property="areaName" />
          </collection>
        </collection>
      </resultMap>
    </mapper>
    

    5.5 一对一关联

    5.5.1 主键关联

    主键关联是一张表的主键和另一张表保持一致,因从属表的主键也是外键。

    1. 表结构

      [husbands_pk]

      id(主键) name ...
      1 tom .
      2 tomas .
      3 tomasLee .

      [wifes_pk]

      id(主键,外键) name ...
      1 jerry .
      2 jerry2 .
      3 jerry3 .
    2. 类设计

      public class Husband {
        private Integer id ;
        private String hname ;
        private Wife wife ;
      }
      
      public class Wife {
        private Husband husband ;
        private String wname ;
      }
      

    3. 映射方式

      [HusbandPKMapper.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="husbands">
        <insert id="insert" useGeneratedKeys="true" keyProperty="id">
          insert into husbands(hname) values(#{hname})
        </insert>
      
        <select id="selectOne" resultMap="rmHusband">
          select
            h.id hid ,
            h.hname hhname ,
            w.wname wwname
          from
          	husbands h left OUTER  join wifes w on w.hid = h.id 
          WHERE 
      		h.id = #{id}
        </select>
        <resultMap id="rmHusband" type="_Husband">
          <id column="hid" property="id" />
          <result column="hhname" property="hname"/>
          <association property="wife" javaType="_Wife" column="hid">
            <result column="wwname" property="wname" />
            <association property="husband" column="hid" javaType="_Husband">
              <id column="hid" property="id" />
              <result column="hhname" property="hname"/>
            </association>
          </association>
        </resultMap>
      </mapper>
      

      [WifePKMapper.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="wifes">
        <insert id="insert">
          insert into wifes(hid, wname) values(#{husband.id} , #{wname})
        </insert>
      </mapper>
      

    5.5.2 外键关联
    1. 表结构

      [husbands_fk]

      id(主键) name ..
      1 tom .
      2
      3

      [wifes_fk]

      id(主键) name hid(外键,唯一约束)
      1 1
      2 2
      3 3

    2. 类设计

      public class HusbandFK {
        private  Integer id ;
        private String hname ;
        private WifeFK wife ;
      }
      public class WifeFK {
        private Integer id ;
        private String wname ;
        private HusbandFK husband ;
      }
      

    3. 映射关系

      [HusbandFKMapper.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="husbands_fk">
        <insert id="insert" useGeneratedKeys="true" keyProperty="id">
          insert into husbands_fk(hname) values(#{hname})
        </insert>
      </mapper>
      

      [WifeFKMapper.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="wifes_fk">
        <insert id="insert" useGeneratedKeys="true" keyProperty="id">
          insert into wifes_fk(wname, hid) values(#{wname} , #{husband.id})
        </insert>
      </mapper>
      

    5.6 多对多关系

    多对多关系需要引入中间表,使用联合主键分别和两端的表进行关联,典型是师生表。

    1. 准备表结构

      -- 教师表
      create table teas(id int primary key auto_increment, tname varchar(20)) ;
      -- 学生表
      create table stus(id int primary key auto_increment, sname varchar(20)) ;
      -- 关联表,联合主键,双外键引用
      create table links(tid int , sid int , primary key (tid,sid) , foreign key (tid) references teas (id) , foreign key (sid) references stus (id)) ;
      
    2. 类设计

      public class Teacher {
        private Integer id ;
        private String tname ;
        private List<Student> stus = new ArrayList<Student>() ;
      }
      public class Student {
        private Integer id ;
        private String sname ;
        private List<Teacher> teas = new ArrayList<Teacher>() ;
      }
      

    3. 映射方式

      插入数据需要包含循环操作,且要设置运行执行多条语句。

      • TeacherMapper.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="teas">
          <insert id="insert" useGeneratedKeys="true" keyProperty="id">
            insert into teas(tname) values(#{tname})
          </insert>
        
          <!-- 循环插入关系表 -->
          <insert id="insertLink">
            <foreach collection="stus" item="s">
              insert into links(tid,sid) values(#{id} , #{s.id}) ;
            </foreach>
          </insert>
        
          <select id="selectOne" resultMap="rmTeacher">
            select
            	t.id tid , t.tname ttname , s.id sid , s.sname ssname
            from
            	teas t
           		left outer join links l on l.tid = t.id
            	left outer join stus s on l.sid = s.id
            WHERE
            	t.id = #{id}
          </select>
          <resultMap id="rmTeacher" type="_Teacher">
            <id column="tid" property="id"/>
            <result column="ttname"  property="tname"/>
            <collection property="stus" ofType="_Student" column="tid">
              <id column="sid" property="id" />
              <result column="ssname" property="sname"/>
            </collection>
          </resultMap>
        </mapper>
        

      • 配置执行多条语句

        [mybatis-config.xml]

        ...
        <property name="url" value="jdbc:mysql://localhost:3306/big12?allowMultiQueries=true"/>
        ...
        
  • 相关阅读:
    20199327 2019-2020-2 《网络攻防实践》第二周作业
    20199327 2019-2020-2《网络攻防实践》第一周作业
    20199327 《网络攻防实践》假期作业
    笔记
    20199327《Linux内核原理与分析》第十二周作业
    20199327《Linux内核原理与分析》第十一周作业
    第二周 测试
    DOS攻击——ICMP报文洪水攻击
    阅读《供应链的可信溯源査询在区块链上的实现》总结 (硕士论文)��
    阅读《基于区块链和用户信用度的访问控制模型 》总结
  • 原文地址:https://www.cnblogs.com/xupccc/p/9655343.html
Copyright © 2011-2022 走看看