MyBatis框架一

一、mybatis的概述

1、orm框架

  • ORM

    • Object:对象

    • R:关系

    • M:映射

    • 概述:ORM,即Object-Relational Mapping(对象关系映射)

  • ORM作用

    • 以对象的行为,操作数据库表

2、mybatis框架是什么?

  • mybatis这是一个半自动化的ORM框架

    • 它还是以对象的行为操作数据库表,但要编写sql语句

  • 支持定制sql(动态sql)

    • 什么动态sql

      • 直到运行时刻才决定sql语句的实现

  • 灵活性强

  • 底层还是依赖原生jdbc实现

  • 要实现pojo对象,要实现xml映射文件/以注解方式实现,能够支持以对象的行为操作数据表

  • 轻量级框架

3、mybatis特点

  • sql语句与代码分离,存放于Dao.xml配置文件中

  • 用逻辑标签控制动态SQL的拼接

  • 查询的结果集与java对象自动映射

 

编写原声SQL

二、编写第一个mybatis程序

1、导入库

 

2、编写全局配置文件

 

 

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <!-- 指定 MyBatis 所用日志的具体实现 -->
 7     <settings>
 8         <setting name="logImpl" value="LOG4J"/>
 9     </settings>
10     <environments default="mysql">
11         <!-- 环境配置,即连接的数据库。 -->
12         <environment id="mysql">
13             <!--  指定事务管理类型,type="JDBC"指直接简单使用了JDBC的提交和回滚设置 -->
14             <transactionManager type="JDBC"/>
15             <!--  dataSource指数据源配置,POOLED是JDBC连接对象的数据源连接池的实现。 -->
16             <dataSource type="POOLED">
17                 <property name="driver" value="com.mysql.jdbc.Driver"/>
18                 <property name="url" value="jdbc:mysql://127.0.0.1:3306/gecdb"/>
19                 <property name="username" value="root"/>
20                 <property name="password" value="1111"/>
21             </dataSource>
22         </environment>
23     </environments>
24     <!-- mappers告诉了MyBatis去哪里找持久化类的映射文件 -->
25     <mappers>
26         <mapper resource="com/gec/mapper/UserMapper.xml"/>
27     </mappers>
28 </configuration>

3、根据数据表,编写实体类

 

 

数据表

 

 

1     create TABLE tb_user
2     (
3         ID int(11) primary key auto_increment,
4         NAME varchar(18) default null,
5         SEX char(2) default null,
6         AGE int(11) default null
7     );

实体类

 

 

 1 package com.gec.domain;
 2 
 3 /*    create TABLE tb_user
 4     (
 5         ID int(11) primary key auto_increment,
 6         NAME varchar(18) default null,
 7         SEX char(2) default null,
 8         AGE int(11) default null
 9     );*/
10 
11 public class User {
12 
13     private Integer id;
14     private String name;
15     private String sex;
16     private Integer age;
17 
18     public Integer getId() {
19         return id;
20     }
21 
22     public void setId(Integer id) {
23         this.id = id;
24     }
25 
26     public String getName() {
27         return name;
28     }
29 
30     public void setName(String name) {
31         this.name = name;
32     }
33 
34     public String getSex() {
35         return sex;
36     }
37 
38     public void setSex(String sex) {
39         this.sex = sex;
40     }
41 
42     public Integer getAge() {
43         return age;
44     }
45 
46     public void setAge(Integer age) {
47         this.age = age;
48     }
49 
50     @Override
51     public String toString() {
52         return "User{" +
53                 "id=" + id +
54                 ", name='" + name + '\'' +
55                 ", sex='" + sex + '\'' +
56                 ", age=" + age +
57                 '}';
58     }
59 }

4、mapper文件

新建com.gec.mapper包,编写mapper xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 <!--
 5 命名空间:此命名空间就是此映射文件的唯一标识
 6 -->
 7 <mapper namespace="com.gec.mapper.UserMapper">
 8 
 9     <!--实现添加功能-->
10     <insert id="insertUser" parameterType="com.gec.domain.User">
11         insert into tb_user(NAME,SEX,AGE) values(#{name},#{sex},#{age})
12     </insert>
13 
14 
15 </mapper>

5、测试类,实现数据表操作

 1 package com.gec.test;
 2 
 3 import com.gec.domain.User;
 4 import org.apache.ibatis.io.Resources;
 5 import org.apache.ibatis.session.SqlSession;
 6 import org.apache.ibatis.session.SqlSessionFactory;
 7 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 8 
 9 import java.io.IOException;
10 import java.io.InputStream;
11 
12 public class MainTest {
13 
14     public static void main(String[] args) throws IOException {
15 
16         //读取mybatis-config.xml全局配置文件
17         InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
18         SqlSessionFactory sf=new SqlSessionFactoryBuilder().build(inputStream);
19 
20         SqlSession session=sf.openSession();
21 
22         //创建用户对象
23         User user=new User();
24         user.setName("李四");
25         user.setAge(37);
26         user.setSex("男");
27         //将对象数据添加到数据表
28         session.insert("com.gec.mapper.UserMapper.insertUser",user);
29 
30         //提交事务
31         session.commit();
32         //关闭会话对象
33         session.close();
34 
35 
36     }
37 }

三、实现mybatis最基本的操作

1、简介

  • 实现添加、删除、查询、修改等功能

2、实现添加功能

  • 编写定制sql,在mapper.xml文件实现

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 <!--
 5 命名空间:此命名空间就是此映射文件的唯一标识
 6 -->
 7 <mapper namespace="com.gec.mapper.UserMapper">
 8 
 9     <!--实现添加功能-->
10     <insert id="insertUser" parameterType="com.gec.domain.User">
11         insert into tb_user(NAME,SEX,AGE) values(#{name},#{sex},#{age})
12     </insert>
13 
14 
15 </mapper>

实现添加操作方法

 1  SqlSession session= MybatisSessionUtils.openSqlSession();
 2         //创建用户对象
 3         User user=new User();
 4         user.setName("李四");
 5         user.setAge(37);
 6         user.setSex("男");
 7         //将对象数据添加到数据表
 8         session.insert("com.gec.mapper.UserMapper.insertUser",user);
 9         //提交事务
10         session.commit();
11         //关闭会话对象
12         session.close();

3、实现删除功能

  • 编写定制sql语句,在mapper.xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 <!--
 5 命名空间:此命名空间就是此映射文件的唯一标识
 6 -->
 7 <mapper namespace="com.gec.mapper.UserMapper">
 8 
 9 
10     <!--实现删除功能-->
11     <delete id="deleteUser" parameterType="int">
12         delete from tb_user where ID=#{id}
13     </delete>
14 
15 
16 </mapper>

实现删除功能方法

 1 //实现删除功能
 2     public static void delete()
 3     {
 4         //获取SqlSession对象
 5         SqlSession sqlSession=MybatisSessionUtils.openSqlSession();
 6 
 7         //参数一:标记调用那个sql方法,此sql方法采用id值=命名空间+sql方法id组成
 8         //delete from tb_user where id=2
 9         sqlSession.delete("com.gec.mapper.UserMapper.deleteUser",2);
10 
11         //提交事务
12         sqlSession.commit();
13         //关闭会话
14         sqlSession.close();
15     }

4、实现更新功能

  • 编写定制sql,在mapper.xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 <!--
 5 命名空间:此命名空间就是此映射文件的唯一标识
 6 -->
 7 <mapper namespace="com.gec.mapper.UserMapper">
 8 
 9     <!--实现修改功能-->
10     <update id="updateUser" parameterType="com.gec.domain.User">
11         update tb_user set name=#{name},age=#{age},sex=#{sex} where id=#{id}
12     </update>
13 
14 
15 </mapper>

操作更新方法

 1     public static void update()
 2     {
 3         SqlSession sqlSession=MybatisSessionUtils.openSqlSession();
 4 
 5         //根据id,获取对应的user对象
 6         //select * from tb_user where id=2
 7         User user=sqlSession.selectOne("com.gec.mapper.UserMapper.findUserById",3);
 8         //传入修改后的User对象
 9         user.setName("周杰伦");
10         user.setAge(38);
11 
12         //update tb_user set xxx where id=2
13         sqlSession.update("com.gec.mapper.UserMapper.updateUser",user);
14 
15         sqlSession.commit();
16         sqlSession.close();
17     }

5、实现查询功能

  • 定义sql方法,在mapper文件

1     <!--实现查询功能-->
2     <select id="queryUser" resultType="com.gec.domain.User">
3         select * from tb_user;
4     </select>

实现查询操作方法

 1 /*
 2     * 实现查询功能
 3     * */
 4     public static void query()
 5     {
 6         SqlSession sqlSession=MybatisSessionUtils.openSqlSession();
 7 
 8        /* List<User> userList=sqlSession.selectList("com.gec.mapper.UserMapper.queryUser");
 9 
10         for (User user : userList) {
11             System.out.println(user);
12         }*/
13 
14         Cursor<User> userCursor=sqlSession.selectCursor("com.gec.mapper.UserMapper.queryUser");
15 
16         for (User user : userCursor) {
17 
18             System.out.println(user);
19 
20         }
21 
22 
23         sqlSession.commit();
24         sqlSession.close();
25     }

四、通过接口描述mapper文件

1、简介

  • 简化mapper文件sql方法的调用,不需要依赖sqlSession对象提供的方法操作mapper文件的sql方法

2、如何实现接口描述mapper文件

  • 根据mapper文件写接口

    • 接口全限定名必须与对应的mapper文件的命名空间要一致

    • 方法名必须与mapper文件里面定义的sql方法的id要一致

  • 代码如下

 1 package com.gec.mapper;
 2 
 3 import com.gec.domain.User;
 4 
 5 import java.util.List;
 6 
 7 /*
 8 * 1、接口全限定名必须与对应的mapper文件的命名空间要一致
 9 * 2、方法名必须与mapper文件里面定义的sql方法的id要一致
10 * */
11 public interface UserMapper {
12 
13     public int insertUser(User user);
14     public int deleteUser(int id);
15     public int updateUser(User user);
16     public User findUserById(int id);
17     public List<User> queryUser();
18 }

3、实现根据接口操作

 1 package com.gec.utils;
 2 
 3 import org.apache.ibatis.io.Resources;
 4 import org.apache.ibatis.session.SqlSession;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 7 
 8 import java.io.IOException;
 9 import java.io.InputStream;
10 
11 /*
12 * 定义获取Session的工具类
13 * */
14 public class MybatisSessionUtils {
15 
16     //全局对象(一个数据库连接分配一个SqlSessionFactory对象)
17     private static SqlSessionFactory sf=null;
18 
19     static {
20         //读取mybatis-config.xml全局配置文件
21         InputStream inputStream= null;
22         try {
23             inputStream = Resources.getResourceAsStream("mybatis-config.xml");
24             sf=new SqlSessionFactoryBuilder().build(inputStream);
25         } catch (IOException e) {
26             e.printStackTrace();
27         }
28     }
29 
30 
31     public static SqlSession openSqlSession()
32     {
33         return sf.openSession();
34     }
35 
36 
37 
38 }
 1 package com.gec.test;
 2 
 3 import com.gec.domain.User;
 4 import com.gec.mapper.UserMapper;
 5 import com.gec.utils.MybatisSessionUtils;
 6 import org.apache.ibatis.session.SqlSession;
 7 
 8 import java.util.List;
 9 
10 public class MainTest2 {
11 
12     public static void main(String[] args) {
13 
14         //insert();
15         //delete();
16        //update();
17         query();
18 
19     }
20 
21     public static void insert()
22     {
23         //SqlSession对象
24         SqlSession sqlSession= MybatisSessionUtils.openSqlSession();
25 
26         //获取接口对象
27         UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
28 
29         User user=new User();
30         user.setName("小强");
31         user.setAge(24);
32         user.setSex("男");
33         userMapper.insertUser(user);
34 
35         sqlSession.commit();
36         sqlSession.close();
37     }
38 
39     public static void delete()
40     {
41         //SqlSession对象
42         SqlSession sqlSession= MybatisSessionUtils.openSqlSession();
43 
44         UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
45         userMapper.deleteUser(4);
46 
47         sqlSession.commit();
48         sqlSession.close();
49 
50     }
51 
52     public static void update()
53     {
54         SqlSession sqlSession=MybatisSessionUtils.openSqlSession();
55 
56         UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
57         User user=userMapper.findUserById(3);
58         user.setName("张学友");
59         userMapper.updateUser(user);
60 
61         sqlSession.commit();
62         sqlSession.close();
63 
64     }
65 
66     public static void query()
67     {
68         SqlSession sqlSession=MybatisSessionUtils.openSqlSession();
69         UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
70 
71         List<User> userList=userMapper.queryUser();
72 
73         for (User user : userList) {
74             System.out.println(user);
75         }
76     }
77 }

五、数据表关系之一:一对一

1、一对一简介

  • 所谓一对一,其实就是通过唯一外键约束,一个数据只能所属一个唯一的数据匹配,例如公民与身份证的关系,一个公民只能分配一张身份证,一张身份证只能所属一个公民

2、创建数据表

  • 身份证数据表

1 /*卡表*/
2 CREATE TABLE tb_card(
3     id INT PRIMARY KEY AUTO_INCREMENT,
4     CODE VARCHAR(18)
5 );
6 
7 INSERT INTO tb_card(CODE) VALUES('432801198009191038');

公民数据表

 1 /*人表*/
 2 CREATE TABLE tb_person
 3 (
 4     id INT PRIMARY KEY AUTO_INCREMENT,
 5     NAME VARCHAR(18),
 6     sex VARCHAR(18),
 7     age INT,
 8     card_id INT UNIQUE,
 9     FOREIGN KEY (card_id) REFERENCES tb_card(id)
10 );
11 
12 INSERT INTO tb_person(NAME,sex,age,card_id) VALUES('jack','',23,1);

3、如何实现1对1映射

a、嵌套查询

  • 简介

    • 查询从表的内容,根据从表的外键,查询主键的内容,有多少外键,执行多少条查询主表的sql语句

  • 实现步骤

    • 实现pojo

      • 实现Card对象

 1 package com.gec.domain;
 2 
 3 public class Card {
 4 
 5     private Integer id;
 6     private String code;
 7 
 8     public Integer getId() {
 9         return id;
10     }
11 
12     public void setId(Integer id) {
13         this.id = id;
14     }
15 
16     public String getCode() {
17         return code;
18     }
19 
20     public void setCode(String code) {
21         this.code = code;
22     }
23 
24     @Override
25     public String toString() {
26         return "Card{" +
27                 "id=" + id +
28                 ", code='" + code + '\'' +
29                 '}';
30     }
31 }

实现Person对象

 1 package com.gec.domain;
 2 
 3 /*
 4 CREATE TABLE tb_person
 5         (
 6         id INT PRIMARY KEY AUTO_INCREMENT,
 7         NAME VARCHAR(18),
 8         sex VARCHAR(18),
 9         age INT,
10         card_id INT UNIQUE,
11         FOREIGN KEY (card_id) REFERENCES tb_card(id)
12         );
13  */
14 public class Person {
15 
16     private Integer id;
17     private String name;
18     private String sex;
19     private Integer age;
20 
21     //体现1 vs 1的关系,此属性记录公民分配卡数据
22     private Card card;
23 
24     public Integer getId() {
25         return id;
26     }
27 
28     public void setId(Integer id) {
29         this.id = id;
30     }
31 
32     public String getName() {
33         return name;
34     }
35 
36     public void setName(String name) {
37         this.name = name;
38     }
39 
40     public String getSex() {
41         return sex;
42     }
43 
44     public void setSex(String sex) {
45         this.sex = sex;
46     }
47 
48     public Integer getAge() {
49         return age;
50     }
51 
52     public void setAge(Integer age) {
53         this.age = age;
54     }
55 
56     public Card getCard() {
57         return card;
58     }
59 
60     public void setCard(Card card) {
61         this.card = card;
62     }
63 
64     @Override
65     public String toString() {
66         return "Person{" +
67                 "id=" + id +
68                 ", name='" + name + '\'' +
69                 ", sex='" + sex + '\'' +
70                 ", age=" + age +
71                 ", card=" + card +
72                 '}';
73     }
74 }

编写mapper文件

  • 编写CardMapper.xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 
 5 <mapper namespace="com.gec.mapper.CardMapper">
 6 
 7     <!--根据id,获取card数据-->
 8     <select id="findCardById" parameterType="int" resultType="com.gec.domain.Card" >
 9         select * from tb_card where id=#{id}
10     </select>
11 
12 </mapper>

编写PersonMapper.xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 <mapper namespace="com.gec.mapper.PersonMapper">
 5 
 6     <!--
 7     resultMap:字段数据与pojo实体类属性的映射关系
 8     -->
 9     <select id="findPersonById" parameterType="int" resultMap="personResultMap">
10         select * from tb_person where id=#{id}
11     </select>
12 
13     <resultMap id="personResultMap" type="com.gec.domain.Person">
14         <id property="id" column="id"/>
15         <id property="name" column="name"/>
16         <id property="sex" column="sex"/>
17         <id property="age" column="age"/>
18 
19         <!--如何实现针对Card属性对象,实现数据映射,体现1 对 1 关系
20         property:属性名
21         column:指明外键字段
22         javaType:属性所属的类名
23         select:调用sql方法
24         -->
25         <association
26                 property="card"
27                 column="card_id"
28                 javaType="com.gec.domain.Card"
29                 select="com.gec.mapper.CardMapper.findCardById"
30                 />
31 
32     </resultMap>
33 
34 </mapper>

编写Mapper接口

  • 编写Person的mapper接口

1 package com.gec.mapper;
2 
3 import com.gec.domain.Person;
4 
5 public interface PersonMapper {
6 
7     public Person findPersonById(int id);
8 }

测试类

 1 package com.gec.test;
 2 
 3 import com.gec.domain.Person;
 4 import com.gec.mapper.PersonMapper;
 5 import com.gec.utils.MybatisSessionUtils;
 6 import org.apache.ibatis.session.SqlSession;
 7 
 8 public class MainTest {
 9 
10     public static void main(String[] args) {
11 
12         SqlSession sqlSession= MybatisSessionUtils.openSqlSession();
13 
14         PersonMapper personMapper=sqlSession.getMapper(PersonMapper.class);
15 
16         Person person=personMapper.findPersonById(1);
17 
18         System.out.println(person);
19 
20         sqlSession.commit();
21         sqlSession.close();
22 
23     }
24 }

 

只要不是第一次接触,应该都不会很头痛,我是觉得MyBatis绕来绕去的,可能是我生疏的缘故,多用就好!

 

posted @ 2020-10-22 21:36  蓝景钊  阅读(115)  评论(0)    收藏  举报