• MyBatis


    什么是 MyBatis ?


      MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

    理解:基于Java持久层框架,内部封装了jdbc,开发者只需要关系sql语句本身。

       采用ORM的思想解决了实体和数据库映射的问题,对JDBC进行了封装,同时屏蔽了jdbc API底层访问细节。

      ORM:将数据库表和实体类及实体类的属性对应起来,通过操作实体类就实现数据库的操作。

          注意:实体类 的属性与数据库表 的字段名一一对应

    一,三层架构

      1,视图层:展示数据

      2,业务层:处理业务需求

      3,持久层:与数据进行交互

    二,mybatis入门

      1,步骤

        1.1,创建maven工程并导入坐标

        1.2,创建实体类和dao接口

        1.3,创建mybatis的主配置文件

            SqlMapConifg.xml

        1.4,创建映射配置文件

            IUserDao.xml

      2,注意事项:

        第一:创建IUserDao.xml和IUserDao.java时文件的路径要一致

        第二:包在创建:com.itheiam.doa是三级目录

           目录在创建时:com.itheiam.doa是一级目录·

        第三:mybatis的映射配置文件位置必须和dao接口的包结构相同

        第四:映射配置文件的mapper标签的namespace属性的取值必须是dao接口的全限定类

          

        第五,映射配置文件的操作配置(select等)id属性的取值必须是dao接口的方法名

             

        第六:满足以上要求就不用实现对应的接口

    public static void main(String[] args) throws IOException {
            //1.读取配置文件
            InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
            
            //2.创建SqlSessionFactory工厂
            SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
            SqlSessionFactory factory=builder.build(in);//创建工厂使用了构建者模式
            //3.使用工厂生产SqlSession对象
            SqlSession session=factory.openSession();//工厂模式
            //4.使用SqlSession创建Dao接口的代理对象
            IUserDao userDao=session.getMapper(IUserDao.class);//代理模式
            
            //5.使用代理对象执行方法
            List<User> users=userDao.findAll();
            for(User user:users) {
                System.out.println(user);
            }
            //6.释放资源
            session.close();
            in.close();
        }

     注意:1.读取配置文件时用的路径不要使用绝对路径,也不要使用相对路径

        使用类加载器,只能读取类路径的配置文件,或者,使用ServlerContext对象的getRealPath()

        2.构建者模式:把对象的创建细节隐藏,让使用者直接调用方法即可拿到对象。

        3.工厂模式:优势:解耦降低类之间的依赖关系

        4.代理模式:优势:不修改源码的基础上对已有的方法增强

    三,解析mybatis框架的原理

     核心:创建代理对象,实现查询所有。

     实例一

      1.主配置文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2  <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
     3 
     4  <!-- mybatis的主配置文件 -->
     5  <configuration>
     6      <environments default="mysql">
     7      <!-- 配置mysql的环境 -->
     8         <environment id="mysql">
     9               <transactionManager type="JDBC" >
    10               </transactionManager>
    11               <dataSource type="POOLED">
    12                   <property name="driver" value="com.mysql.jdbc.Driver" />
    13                 <property name="url" value="jdbc:mysql://localhost:3306/db_java" />
    14                 <property name="username" value="root" />
    15                  <property name="password" value="" />
    16              </dataSource>
    17         </environment>
    18      </environments> 
    19      <!-- 指定映射配置文件,即每个dao独立的配置 -->
    20      <mappers>
    21          <mapper resource="com/dao/IUserDao.xml"/>
    22      </mappers>
    23     
    24  </configuration>
    SqlMapConfig.xml

      2,mapper文件。注意:要与对应的dao接口文件的路径对应

    IUserDao.xml

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE mapper
     3   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     4   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     5 <mapper namespace="com.dao.IUserDao">
     6     <!-- 配置查询所有  -->
     7         <select id="findAll" resultType="com.model.User">
     8 <!-- 返回值也要写全限定的类名  -->
     9                 select * from user;
    10         </select>
    11         
    12     <!-- 保存操作 -->
    13         <insert id="saveUser" parameterType="com.model.User">
    14 <!-- 参数类型也要写全限定的类名  -->
    15             insert into user (name) values(#{name});
    16 <!--#{}中的变量是对应的model中的User类的属性的getter方法的名称,但是省略了get,同时是小写  -->
    17         </insert>
    18 </mapper>

    3.com.dao.IUserDao.java

     1 package com.dao;
     2 
     3 import java.util.List;
     4 
     5 import com.model.User;
     6 
     7 public interface IUserDao {
     8     public List<User> findAll();
     9     void saveUser(User user);
    10 }
    View Code

    4,com.model.User.java

     1 package com.model;
     2 
     3 import java.io.Serializable;
     4 
     5 public class User implements Serializable{
     6     private Integer id;
     7     private String name;
     8     public Integer getId() {
     9         return id;
    10     }
    11     public void setId(Integer id) {
    12         this.id = id;
    13     }
    14     public String getName() {
    15         return name;
    16     }
    17     public void setName(String name) {
    18         this.name = name;
    19     }
    20     @Override
    21     public String toString() {
    22         return "User [id=" + id + ", name=" + name + "]";
    23     }
    24     
    25 }
    User.java

    注意: 要继承Serializable接口

    5.pom.xml

     1 <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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     2   <modelVersion>4.0.0</modelVersion>
     3   <groupId>mybatis</groupId>
     4   <artifactId>com</artifactId>
     5   <version>0.0.1-SNAPSHOT</version>
     6   <name>day1</name>
     7   
     8   <dependencies>
     9     <dependency>
    10         <!--一般情况下,maven是通过groupId、artifactId、version这三个元素值(俗称坐标)来检索该构件, 然后引入你的工程。如果别人想引用你现在开发的这个项目(前提是已开发完毕并发布到了远程仓库),-->   
    11            <!--就需要在他的pom文件中新建一个dependency节点,将本项目的groupId、artifactId、version写入, maven就会把你上传的jar包下载到他的本地 -->  
    12             <groupId>org.mybatis</groupId>
    13             <artifactId>mybatis</artifactId>
    14             <version>3.4.5</version>
    15         </dependency>
    16         <dependency>
    17             <groupId>mysql</groupId>
    18             <artifactId>mysql-connector-java</artifactId>
    19             <version>5.1.6</version>
    20         </dependency>
    21         <dependency>
    22             <groupId>log4j</groupId>
    23             <artifactId>log4j</artifactId>
    24             <version>1.2.12</version>
    25         </dependency>
    26         <dependency>
    27             <groupId>junit</groupId>
    28             <artifactId>junit</artifactId>
    29             <version>4.10</version>
    30         </dependency>
    31 
    32     
    33     
    34     
    35     </dependencies>
    36   
    37 </project>
    pom.xml

    6.test对应的代码com.test.java

            com.dao.test

     1 package com.dao.test;
     2 
     3 import java.io.IOException;
     4 import java.io.InputStream;
     5 import java.util.List;
     6 
     7 import org.apache.ibatis.io.Resources;
     8 import org.apache.ibatis.session.SqlSession;
     9 import org.apache.ibatis.session.SqlSessionFactory;
    10 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    11 import org.junit.After;
    12 import org.junit.Before;
    13 import org.junit.Test;
    14 import org.junit.experimental.theories.suppliers.TestedOn;
    15 
    16 import com.dao.IUserDao;
    17 import com.model.User;
    18 
    19 public class MybatisTest {
    20     private InputStream in;
    21     private SqlSession sqlSession;
    22     private IUserDao userDao;
    23     
    24     @Before //用于在测试方法之前执行
    25     public  void init() throws IOException {
    26         //1.读取配置文件
    27                  in=Resources.getResourceAsStream("SqlMapConfig.xml");
    28                 
    29                 //2.创建SqlSessionFactory工厂
    30                 SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
    31                 SqlSessionFactory factory=builder.build(in);
    32                 //3.使用工厂生产SqlSession对象
    33                  sqlSession=factory.openSession();
    34                 //4.使用SqlSession创建Dao接口的代理对象
    35                  userDao=sqlSession.getMapper(IUserDao.class);
    36                 
    37                 
    38                 
    39             }
    40     
    41     @After    //用于在测试之后
    42     public void destory() throws IOException {
    43         //提交事务
    44                 sqlSession.commit();
    45         //6.释放资源
    46         sqlSession.close();
    47         in.close();
    48     }
    49     
    50     @Test
    51     public  void findAll() throws IOException {
    52         //1.读取配置文件
    53         /*
    54          * InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
    55          * 
    56          * //2.创建SqlSessionFactory工厂 SqlSessionFactoryBuilder builder=new
    57          * SqlSessionFactoryBuilder(); SqlSessionFactory factory=builder.build(in);
    58          * //3.使用工厂生产SqlSession对象 SqlSession session=factory.openSession();
    59          * //4.使用SqlSession创建Dao接口的代理对象 IUserDao
    60          * userDao=session.getMapper(IUserDao.class);
    61          */
    62         
    63         //5.使用代理对象执行方法
    64         List<User> users=userDao.findAll();
    65         for(User user:users) {
    66             System.out.println(user);
    67         }
    68 
    69     /*
    70      * //6.释放资源 session.close(); in.close(); }
    71      */
    72     }
    73     @Test
    74     public void testSaveAll() {
    75         User user=new User();
    76         user.setName("仙女");
    77         
    78         //执行保存方法
    79         userDao.saveUser(user);
    80         
    81     }
    82     
    83 }
    MybatisTest.java

    注意:1,在测试的时候的init方法和destory方法中要用@before和@after修饰

       分别表示:@before:在测试之前

            @after:在测试之后

       2,增加,修改,删除均要提交事务

        

          //提交事务
            sqlSession.commit();

     示例二:模糊查询

    <select id="findUserByName" parameterType="string" resultType="com.model.User">
                    select * from user where name like #{name};
                    <!-- prepateStatement的参数占位符 -->
                    <!--注意这里的vale的名称不能改变
                    字符窜拼接,可能字符串注入
                    select * from user where name like '%${value}%';
                      -->
                    
                    
            </select>

    注意:用未带%%的方式,传递参数时要自带%%号

    //测试模糊查询
            @Test
            public void testfindUserByName() {
                
            List<User>    users=userDao.findUserByName("%o%");
            for(User user:users) {
                System.out.println(user);
            }
            }

    示例三:获取刚插入的id

     1     
     2     <!-- 保存操作 -->
     3         <insert id="saveUser" parameterType="com.model.User">
     4         <!-- 配置插入操作后,获取插入数据的id -->
     5         <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
     6         select last_insert_id();
     7         
     8         </selectKey>
     9             insert into user (name) values(#{name});
    10         </insert>

    OGNL表达式

     object graphic navigation language(对象 图 导航 语言)


    它是通过对象的取值方法来获取数据,在写法上把get省略了

      比如:类中获取:user.getUsername()

          OGNL:user.username

     mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值未pojo属性名称

    pojo:就是一个java bean实体对象

    实例:

     1 public class QueryVo {
     2     private User user;
     3 
     4     public User getUser() {
     5         return user;
     6     }
     7 
     8     public void setUser(User user) {
     9         this.user = user;
    10     }
    11 }
    queryVo.java
    <!-- 根据queryvo的条件查询用户 -->
            <select id="fingUserByVo" parameterType="com.model.QueryVo" resultType="com.model.User">
            select * from user where name like #{user.name};
            </select>
     1 //测式使用queryvo
     2         @Test
     3         public void testfindUserByQueryVo() {
     4             QueryVo vo=new QueryVo();
     5             User user=new User();
     6             user.setName("%o%");
     7             vo.setUser(user);
     8         List<User>    users=userDao.findUserByVo(vo);
     9         for(User u:users) {
    10             System.out.println(u);
    11         }
    12         }

    1,实体类的属性与数据库表的字段名称不同时:

    注意:windows操作系统中的MySQL数据库不区分大小写,Linux系统区分大小写。

      即username与userName等价

      解决方法:sql语句中使用别名的方法,效率高

            配置查询结果集的列名和实体类的属性名的对应关系,更加方便

     1 public class TUser {
     2     @Override
     3     public String toString() {
     4         return "TUser [name=" + name + ", id=" +userId + ", pwd=" + pwd + ", userSchool=" + userSchool + "]";
     5     }
     6     String name;
     7     int userId;
     8     
     9     String pwd;
    10     String userSchool;
    11     
    12     public int getUserId() {
    13         return userId;
    14     }
    15     public void setUserId(int userId) {
    16         this.userId = userId;
    17     }
    18     public String getName() {
    19         return name;
    20     }
    21     public void setName(String name) {
    22         this.name = name;
    23     }
    24     
    25     public String getPwd() {
    26         return pwd;
    27     }
    28     public void setPwd(String pwd) {
    29         this.pwd = pwd;
    30     }
    31     public String getUserSchool() {
    32         return userSchool;
    33     }
    34     public void setUserSchool(String userSchool) {
    35         this.userSchool = userSchool;
    36     }
    37 }
    tUser.java

    对应的表结构:

    id  username password school

    <!-- 配置查询结果的列名给实体类的属性名的对应关系 -->
            <resultMap id="userMap" type="com.model.TUser">
            <!-- 主键对应的字段 -->
            <id property="userId" column="id"></id>
            <!-- 非主键对应的字段
            property=java类中的属性名    column=对应表的字段名
             -->
            <result property="name" column="username" ></result>
            <result property="pwd" column="password" ></result>
            <result property="userSchool" column="school" ></result>
            </resultMap>
            
            <!-- 查询所有 -->
            <select id="findTUsersAll" resultMap="userMap">
            select * from tb_user;
            </select>
  • 相关阅读:
    stylish——一键为网页换肤,改变字体大小,去除广告
    css3实现可以计算的自适应布局——calc()
    用一个div模拟textarea并实现高度自适应
    关于background定位
    CSS3 :nth-of-type() 选择器
    css3圣诞雪景球
    ie6、7、8兼容部分css3
    html5 录制mp3音频,支持采样率和比特率设置
    html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器
    grunt配置太复杂?使用Qbuild进行文件合并、压缩、格式化等处理
  • 原文地址:https://www.cnblogs.com/gjx1212/p/14666059.html
Copyright © 2020-2023  润新知