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>

 

posted on 2021-04-17 11:50  居一雪  阅读(95)  评论(0编辑  收藏  举报

导航