使用接口操作mybatis的开发

Mybatis接口开发的练习

–1,需求:查询car表里的所有数据
–2,开发步骤

准备表和数据


DROP TABLE IF EXISTS `car`;
CREATE TABLE `car` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(10) default NULL,
  `color` varchar(10) default NULL,
  `price` double default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `car` VALUES ('1', 'BMW', 'red', '9.9');
INSERT INTO `car` VALUES ('2', 'Audi', 'black', '0.3');


创建Car类


package cn.tedu.pojo;
//封装汽车表返回的数据 orm
public class Car {
    private Integer id;
    private String name;
    private String color;
    private Double price;

    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}


创建CarMapper接口


package cn.tedu.dao;
import cn.tedu.pojo.Car;
import java.util.List;
//用来操作car表的各种方法
public interface CarMapper {
    List<Car> selectList();//查所有数据
}


创建CarMapper.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属性用来作为mapper文件的唯一标识
    namespace属性的值是 接口的全路径
-->
<mapper namespace="cn.tedu.dao.CarMapper">
    <!--select用来标记着这是一个查询的SQL语句
        id属性是SQL的唯一标识
        id属性的值是 接口里对应的方法名
        resultType属性的值是 要把查询结果封装给哪个类的全路径
    -->
    <select id="selectList" resultType="cn.tedu.pojo.Car">
        select * from car
    </select>
</mapper>


修改mybatis-config.xml,加入映射文件


<!-- 用来引入映射文件 ,底层维护了MapperRegistry,用来存各种Mapper文件-->
    <mappers>
        <!--加入了一个新的映射文件-->
        <mapper resource="CarMapper.xml"></mapper>
        <mapper resource="UserMapper.xml"></mapper>
        <mapper resource="DeptMapper.xml"></mapper>
    </mappers>

创建测试类

package cn.tedu.mybatis;

import cn.tedu.dao.CarMapper;
import cn.tedu.pojo.Car;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestCar {
    private SqlSessionFactory factory;

    @BeforeEach //Junit5版本才支持的注解,Junit4版本用@Before
    public void init() throws IOException {
        //1,读取核心配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        //2,创建会话工厂
        factory = new SqlSessionFactoryBuilder().build(in);
    }
    @Test
    public void get(){
        //开启会话
        SqlSession session = factory.openSession();
        //获取了指定的接口
        CarMapper mapper = session.getMapper(CarMapper.class);
        //调用接口里的方法
        List<Car> list = mapper.selectList();
        //遍历打印
        for (Car c : list) {
            System.out.println(c);
        }
    }

}

二,解析SQL的参数

在这里插入图片描述

–1,需求:查询id=1 的汽车数据

修改pom.xml,添加了mybatis的jar包


 <!--添加mybatis的依赖-->
    <dependencies>
        <!--mybatis依赖包-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <!--jdbc依赖包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>
    </dependencies>


创建核心配置文件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">

<!--这个文件,是mybatis框架的核心配置文件,都配置了数据源,事务,映射文件-->
<configuration>

    <environments default="test">
        <!--配置数据源,事务-->
        <environment id="test">
            <!--配置了事务,使用jdbc提供的事务-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置了数据源,指定连接数据库的4个参数-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai" />
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

</configuration>



创建Car类


package cn.tedu.pojo;

public class Car {
    private Integer id;
    private String name;
    private String color;
    private Double price;

    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}



创建CarMapper 接口
package cn.tedu.dao;
import cn.tedu.pojo.Car;
public interface CarMapper {

    Car getById(Integer id);/**查询id=1的汽车数据*/

}


创建CarMapper.xml

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace的值是接口的全路径-->
<mapper namespace="cn.tedu.dao.CarMapper">
    <!--id的值写接口中的方法的名字-->
    <select id="getById" resultType="cn.tedu.pojo.Car">
        select * from car
        where id = ${id}   /*获取用户传入的参数,固定语法::${要获取谁的值}*/
    </select>
</mapper>


修改核心配置文件,引入mapper文件
  <!--引入mapper文件-->
    <mappers>
        <mapper resource="CarMapper.xml"></mapper>
    </mappers>

测试

package cn.tedu.test;

import cn.tedu.dao.CarMapper;
import cn.tedu.pojo.Car;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.net.CacheRequest;

public class Test1 {
    private SqlSessionFactory factory;

    //@BeforeEach在执行@Test前执行,以下两步代码重复出现,提取出来,提高代码的复用性
    @BeforeEach
    public void init() throws IOException {
        //1,读取核心配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        //2,创建会话工厂
        factory = new SqlSessionFactoryBuilder().build(in);
    }
    @Test
    public void get(){
        SqlSession session = factory.openSession();
        CarMapper mapper = session.getMapper(CarMapper.class);
        Car c = mapper.getById(1);
        System.out.println(c);
    }
}


总结

在这里插入图片描述

三,解析SQL参数的练习

–1,需求:按名字查汽车数据
修改映射文件


 <!--按名字查-->
    <select id="getByName" resultType="cn.tedu.pojo.Car">
        select * from car where
        name = #{name}
        /*$和#都可以获取参数,但是 $不会拼接字符串不安全低效,#会自动拼接字符串而且高效安全避免了SQL攻击问题*/
    </select>


修改接口文件
Car getByName(String name);/**查询name=bmw的汽车数据*/

修改测试文件

@Test
    public void get(){
        SqlSession session = factory.openSession();
        CarMapper mapper = session.getMapper(CarMapper.class);
        Car c = mapper.getById(2);//按照id查
        System.out.println(c);

        Car c2 = mapper.getByName("bmw");//按照name查
        System.out.println(c2);
    }


总结

四,动态SQL

–1,作用
让SQL更加灵活动态
1
–2,常见的标签
sql标签:用来提取SQL片段
include标签:引用指定的SQL片段
if 标签:用来做判断
where 标签:用来表示过滤条件
set 标签:用来在update语句中设置新的值
foreach 标签:用来完成循环结构

普通标签测试
'
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace的值是接口的全路径-->
<mapper namespace="cn.tedu.dao.CarMapper">
    <!--1.  动态SQL标签,用来提取共性的SQL-->
    <sql id="columns">
        id,name,color,price
    </sql>

    <!--id的值写接口中的方法的名字-->
    <select id="getById" resultType="cn.tedu.pojo.Car">
        select
        /*2. 引用了指定的SQL片段*/
         <include refid="columns"></include>
        from car
        where id = ${id}
        /*获取用户传入的参数,固定语法::${要获取谁的值}*/
    </select>

    <!--按名字查-->
    <select id="getByName" resultType="cn.tedu.pojo.Car">
        select 
        <include refid="columns"></include>
        from car
        <where> /*4, where标签*/
            /*3, if标签用来做判断,满足条件才执行SQL,test属性用来写判断条件*/
            <if test="name != null">
                name = #{name}
            </if>
        </where>
        /*$和#都可以获取参数,但是 $不会拼接字符串不安全低效,#会自动拼接字符串而且高效安全避免了SQL攻击问题*/
    </select>
</mapper>



4,foreach 标签测试

1,需求:查询id为1或者2的car的数据
2,修改映射文件,添加新的SQL


<!--查询id为1或者2的car的数据-->
    <select id="getByIds" resultType="cn.tedu.pojo.Car">
        select * from car where id
        in
        /*获取数组里的数据,collection的值是固定值array
        open是以啥开始  close是以啥结束  separator是以啥分隔 item是表示数组里的每个数据
        */
        <foreach collection="array" open="(" close=")" separator="," item="i">
            #{i}
        </foreach>
    </select>


修改接口文件,添加新方法
 List<Car> getByIds(Integer[] ids);/*查询id为1或者2的car的数据*/

修改测试文件,调用新方法

package cn.tedu.test;

import cn.tedu.dao.CarMapper;
import cn.tedu.pojo.Car;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.net.CacheRequest;
import java.util.List;

public class Test1 {
    private SqlSessionFactory factory;

    //@BeforeEach在执行@Test前执行,以下两步代码重复出现,提取出来,提高代码的复用性
    @BeforeEach
    public void init() throws IOException {
        //1,读取核心配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        //2,创建会话工厂
        factory = new SqlSessionFactoryBuilder().build(in);
    }
    @Test
    public void get(){
        SqlSession session = factory.openSession();
        CarMapper mapper = session.getMapper(CarMapper.class);
        Car c = mapper.getById(2);//按照id查
        System.out.println(c);

        Car c2 = mapper.getByName("bwm");//按照name查
        System.out.println(c2);


        Integer[] ids = {1, 2};
//        mapper.getByIds(new Integer[]{1, 2});
        //给SQL传入多个参数,SQL语句里通过foreach标签解析参数
        List<Car> list = mapper.getByIds(ids);
        for (Car cc : list) {
            System.out.println(cc);
        }

    }
}


五,resultmap
–1,作用:

**通常,如果类里的属性名 和 表里的 字段名 一致时,可以自动的ORM
**
如果,表里字段的名字 和 类里属性的名字不一样时,resultType无法完成ORM,需要使用resultMap

2,用法:

在使用多表查询是使用resultmap
把SQL标签的属性从resultType改成resultMap,另外单独处理那些 表里字段的名字 和 类里属性的名字不一样 的特殊情况

准备表和数据

create table user_info(
	id int primary key auto_increment,
	user_name varchar(100),
	user_addr varchar(200),
	user_age int);
insert into user_info values(null,'韩梅梅','上海',20);
insert into user_info values(null,'王海涛','北京',30);
insert into user_info values(null,'张慎政','河南',10);

create table user_extra(
	id int primary key auto_increment,
	user_id int,
	work varchar(100),
	salary double);
insert into user_extra values(null,'1','程序员',100000);
insert into user_extra values(null, '2','教师',1000);
insert into user_extra values(null, '3','CTO',100000);


测试:
需求:查询user_extra的所有数据

创建UserExtra 类

package cn.tedu.pojo;

public class UserExtra {
    private Integer id;
    private Integer userId; //?
    private String work;
    private Double salary;

    @Override
    public String toString() {
        return "UserExtra{" +
                "id=" + id +
                ", userId=" + userId +
                ", work='" + work + '\'' +
                ", salary=" + salary +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getWork() {
        return work;
    }

    public void setWork(String work) {
        this.work = work;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }


创建UserExtraMapper 接口

package cn.tedu.dao;
import cn.tedu.pojo.UserExtra;
import java.util.List;

public interface UserExtraMapper {
    List<UserExtra> selectList();//查所有数据
}

创建UserExtraMapper .xml映射文件
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace的值是接口的全路径-->
<mapper namespace="cn.tedu.dao.UserExtraMapper">
    
    <!--id的值,是接口里的方法名  resultType的值,是要把结果封装给哪个 类的全路径-->
    <select id="selectList" resultType="cn.tedu.pojo.UserExtra">
        select * from user_extra
    </select>
    
</mapper>


修改核心配置文件,引入新的mapper文件
<!--引入mapper文件-->
    <mappers>
        <mapper resource="CarMapper.xml"></mapper>
        <!--引入新的mapper文件-->
        <mapper resource="UserExtraMapper.xml"></mapper>
    </mappers>


测试
 @Test
    public void get2(){
        //1,开启会话
        SqlSession session = factory.openSession();
        //2,获取接口
        UserExtraMapper mapper = session.getMapper(UserExtraMapper.class);
        //3,调用方法
        List<UserExtra> list = mapper.selectList();

        for (UserExtra ue : list) {
            System.out.println(ue);
        }
    }

问题:字段名和属性名不一致的话,没有ORM

UserExtra{id=1, userId=null, work='程序员', salary=100000.0}
UserExtra{id=2, userId=null, work='教师', salary=1000.0}
UserExtra{id=3, userId=null, work='CTO', salary=100000.0}

解决方案:使用resultMap代替resultType

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace的值是接口的全路径-->
<mapper namespace="cn.tedu.dao.UserExtraMapper">

    <!--当字段名和属性名不一致时用resultMap
        id属性是,每个resultMap的唯一标识
        type属性是,要把结果ORM给哪个类的 全路径
    -->
    <resultMap id="UserERM" type="cn.tedu.pojo.UserExtra">
        <!--描述特殊的字段,column描述表里的字段名  property描述类里的属性名  -->
        <result column="user_id" property="userId"></result>
    </resultMap>

    <!--id的值,是接口里的方法名  resultType的值,是要把结果封装给哪个 类的全路径-->
    <!--<select id="selectList" resultType="cn.tedu.pojo.UserExtra"> 特殊字段没有ORM-->
    <select id="selectList" resultMap="UserERM">
        select * from user_extra
    </select>

</mapper>


测试

UserExtra{id=1, userId=1, work='程序员', salary=100000.0}
UserExtra{id=2, userId=2, work='教师', salary=1000.0}
UserExtra{id=3, userId=3, work='CTO', salary=100000.0}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值