MyBatis+PostgreSQL+IDEA学习笔记(三)

三、MyBatis映射文件

1. 数据库的增删改查

(1)在Java Bean文件中添加构造器

Employee.java

public Employee() {
    super();
}

public Employee(String id, String lastName, String gender, String email) {
    this.id = id;
    this.lastName = lastName;
    this.gender = gender;
    this.email = email;
}

(2)在DAO.Mapper文件中添加方法

(DAO = Data Access Object 这个包用于存放数据库操作相关的类)
EmployeeMapper.java

package mybatis.dao;

import mybatis.bean.Employee;

public interface EmployeeMapper {
    //查
    public Employee getEmpById(String id);
	//增
    public void addEmp(Employee employee);
	//改
    public void updateEmp(Employee employee);
	//删
    public void deleteEmpById(String id);
}

(3)在Mapper XML配置文件中添加语句

EmployeeMapper.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">
<!--
namespace:名称空间;指定为接口的全类名
id:唯一标识
resultType:返回值类型
parameterType:传入参数类型(可以不写)
#{id}:从传递过来的参数中取出id值
${}: $表示取值 {}大括号表示变量 取整型类型变量
#{}: #表示取值 {}大括号表示变量 取字符类型变量
-->
<mapper namespace="mybatis.dao.EmployeeMapper">
    <select id="getEmpById" resultType="mybatis.bean.Employee">
        select * from tb1_employee where id = #{id}
    </select>

    <insert id="addEmp" parameterType="mybatis.bean.Employee">
        insert into tb1_employee(id,last_name,gender,email)
        values(#{id},#{lastName},#{gender},#{email})
    </insert>

    <update id="updateEmp">
        update tb1_employee
        set last_name=#{lastName},gender=#{gender},email=#{email}
        where id=#{id}
    </update>

    <delete id="deleteEmpById">
        delete from tb1_employee where id=#{id}
    </delete>
</mapper>

(4)测试函数

MyBatisTest.java

    /*
    * 测试增删改查
    *1、mybatis允许增删改直接定义以下类型返回值
    *       Integer、Long、Boolean、void
    *2、我们需要手动提交数据
    *       sqlSessionFactory.openSession();===》手动提交
    *       sqlSessionFactory.openSession(true);===》自动提交
    * */
    @Test
    public void test03() throws IOException {
        SqlSessionFactory sqlSessionFactory =getSqlSessionFactory();
        //获取的SqlSession对象不会自动提交数据
        SqlSession openSession=sqlSessionFactory.openSession();
        try {
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);

            //测试添加
            Employee employee1 = new Employee("002", "Jerry", "0", "654321@gmil.com");
            mapper.addEmp(employee1);

            //测试修改
            Employee employee2 = new Employee("002", "Mark", "1", "12345678@gmil.com");
            mapper.updateEmp(employee2);

            //测试删除
            mapper.deleteEmpById("002");

            //测试查询
            Employee employee3 = mapper.getEmpById("001");
            System.out.println(employee3);
            
            //手动提交
            openSession.commit();
        }finally {
            openSession.close();
        }
    }

(5)测试结果

1)IDEA中


IDEA 增

IDEA改

IDEA删

IDEA查

2)终端中查询结果

Terminal查询

2. MyBatis参数处理

(1)单个参数

单个参数:mybatis不会做特殊处理,

#{参数名/任意名}:取出参数值。

(2)多个参数

1)原始方法

多个参数:mybatis会做特殊处理。

多个参数会被封装成 一个map,

	key:param1...paramN,或者参数的索引也可以

	value:传入的参数值

#{}就是从map中获取指定的key的值;

例:
EmployeeMapper.java

package mybatis.dao;

import mybatis.bean.Employee;

public interface EmployeeMapper {
	//传入多个参数
    public Employee getEmpByIdAndLastName(String id,String lastName);
}

EmployeeMapper.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="mybatis.dao.EmployeeMapper">
    <select id="getEmpByIdAndLastName" resultType="mybatis.bean.Employee">
        select * from tb1_employee where id = #{param1} and last_name = #{param2}
    </select>
</mapper>

MyBatisTest.java

package mybatis.test;

import mybatis.bean.Employee;
import mybatis.dao.EmployeeMapper;
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 java.io.IOException;
import java.io.InputStream;
import org.junit.Test;

public class MyBatisTest {
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

	@Test
    public void test04() throws IOException {
        SqlSessionFactory sqlSessionFactory =getSqlSessionFactory();
        //获取的SqlSession对象不会自动提交数据
        SqlSession openSession=sqlSessionFactory.openSession();
        try {
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
			
			//传入多个参数
            Employee employee = mapper.getEmpByIdAndLastName("002","Tom");
            System.out.println(employee);

            //手动提交
            openSession.commit();
        }finally {
            openSession.close();
        }
    }
}

结果
多个参数

2)命名参数
1⃣️原始方法

命名参数:明确指定封装参数时map的key;@Param(“id”)

多个参数会被封装成 一个map,

	key:使用@Param注解指定的值

	value:参数值

#{指定的key}取出对应的参数值

例:
EmployeeMapper.java

package mybatis.dao;

import mybatis.bean.Employee;
import org.apache.ibatis.annotations.Param;

public interface EmployeeMapper {
	//传入多个参数 命名参数
    public Employee getEmpByIdAndLastName(@Param("id")String id, @Param("lastName")String lastName);
}

EmployeeMapper.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="mybatis.dao.EmployeeMapper">
    <select id="getEmpByIdAndLastName" resultType="mybatis.bean.Employee">
        select * from tb1_employee where id = #{id} and last_name = #{lastName}
    </select>
</mapper>

MyBatisTest.java 测试函数 Test04( ) 同上

结果命名参数

2⃣️其他命名方法

POJO:
如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo;

#{属性名}:取出传入的pojo的属性值	

Map:
如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便,我们也可以传入map

#{key}:取出map中对应的值

TO:
如果多个参数不是业务模型中的数据,但是经常要使用,推荐来编写一个TO(Transfer Object)数据传输对象

例如:

Page{
	int index;
	int size;
}
3⃣️具体场景

1. 一个参数命名,另一个不命名

public Employee getEmp(@Param("id")Integer id,String lastName);
取值:id==>#{id/param1}   lastName==>#{param2}

2. 传入一个值和一个对象

public Employee getEmp(Integer id,@Param("e")Employee emp);
取值:id==>#{param1}    lastName===>#{param2.lastName/e.lastName}

3. 传入Collection(List、Set)类型或者是数组

如果是Collection(List、Set)类型或者是数组,也会特殊处理。把传入的list或者数组封装在map中。

key:Collection(collection),List (list),数组(array)
public Employee getEmpById(List<Integer> ids);
取值:取出第一个id的值:   #{list[0]}

(3)参数值的获取

#{}:可以获取map中的值或者pojo对象属性的值;
${}:可以获取map中的值或者pojo对象属性的值;
参数值的获取
区别:

	#{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入

	${}:取出的值直接拼装在sql语句中;会有安全问题;

	大多情况下,我们取参数的值都应该去使用#{};

原生jdbc不支持占位符的地方,可以使用${}进行取值
例如分表、排序等:

select * from ${year}_salary where xxx;
select * from tbl_employee order by ${f_name} ${order}

#{}:更丰富的用法:

可以规定参数的一些规则:

javaType、 jdbcType、 mode(存储过程)、 numericScale、

resultMap、 typeHandler、 jdbcTypeName、 expression(未来准备支持的功能);

jdbcType通常需要在某种特定的条件下被设置:

在数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理。比如Oracle、PostgreSQL,

报错:JdbcType OTHER:无效的类型

这是因为mybatis对所有的null都映射的是原生Jdbc的OTHER类型,oracle不能正确处理;

解决方案:
1、在映射文件中设置 #{id,jdbcType=NULL};
例:

<select id="getEmpById,jdbcType=NULL" resultType="mybatis.bean.Employee">
	select * from tb1_employee where id = #{id}
</select>

2、在全剧配置文件中设置 jdbcTypeForNull=NULL

<settings>
	<setting name="jdbcTypeForNull" value="NULL"/>
</settings>

3. MyBatis Select查询

(1)返回对象是列表或集合

EmployeeMapper.java

//返回对象列表
public List<Employee> getEmployeeByLastNameLike(String lastName);

EmployeeMapper.xml
注意:resultType:如果返回的是一个集合,要写集合中元素的类型

<!--返回对象列表-->
<select id="getEmployeeByLastNameLike" resultType="mybatis.bean.Employee">
	select * from tb1_employee where last_name like #{lastName}
</select>

MyBatisTest.java

@Test
public void test04() throws IOException {
	SqlSessionFactory sqlSessionFactory =getSqlSessionFactory();
    //获取的SqlSession对象不会自动提交数据
    SqlSession openSession=sqlSessionFactory.openSession();
    try {
        EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
        //查询 返回对象列表
        List<Employee> like = mapper.getEmployeeByLastNameLike("%e%");
        //打印
        for(Employee employee : like){
            System.out.println(employee);
        }
        //手动提交
        openSession.commit();
    } finally {
        openSession.close();
    }
}

测试结果
SelectListResult

(2)返回对象是map

EmployeeMapper.java

//返回一条记录的map:key是列名,值是对应的返回值
public Map<String,Object> getEmpByIdReturnMap(String id);

//多条记录封装一个map:Map<String,Employee>:键是这条记录的主键,值是记录封装后的javaBean
//@MapKey:告诉mybatis封装这个map的时候使用哪个属性作为map的key
@MapKey("id")
public Map<String, Employee> getEmpByLastNameLikeReturnMap(String lastName);

EmployeeMapper.xml

<!--返回一条记录的map:key是列名,值是对应的返回值-->
<select id="getEmpByIdReturnMap" resultType="map">
	select * from tb1_employee where id = #{id}
</select>

<!--多条记录封装一个map-->
<!--resultType:想要封装的对象的类型-->
<select id="getEmpByLastNameLikeReturnMap" resultType="mybatis.bean.Employee">
	select * from tb1_employee where last_name like #{lastName}
</select>

MyBatisTest.java

@Test
public void test04() throws IOException {
	SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
	//获取的SqlSession对象不会自动提交数据
	SqlSession openSession=sqlSessionFactory.openSession();
	try {
		EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
		//查询 返回单条记录map
		Map<String, Object> map = mapper.getEmpByIdReturnMap("001");
		System.out.println(map);

		//查询 返回多条记录封装一个map
 		Map<String, Employee> map = mapper.getEmpByLastNameLikeReturnMap("%y%");
		System.out.println(map);

		//手动提交
		openSession.commit();
	} finally {
		openSession.close();
	}
}

测试结果:

  1. map是单条对象
    单条Map
  2. map是多条对象
    多条Map

4. ResultMap标签

resultMap可以实现将查询结果映射为复杂类型的pojo,可以通过ResultMap实现一对多的查询。
例1:指定封装规则

<!--自定义某个javaBean的封装规则
	type:自定义规则的Java类型
	id:唯一id方便引用
	  -->
    <resultMap id="MySimpleEmp" type="mybatis.bean.Employee">
        <!--指定主键列的封装规则
        id定义主键会底层有优化;
        column:指定哪一列
        property:指定对应的javaBean属性
          -->
        <id column="id" property="id"/>
        <!-- 定义普通列封装规则 -->
        <result column="last_name" property="lastName"/>
        <!-- 其他不指定的列会自动封装:我们只要写resultMap就把全部的映射规则都写上。 -->
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </resultMap>

    <!-- resultMap:自定义结果集映射规则;  -->
    <select id="getEmpById" resultMap="MySimpleEmp">
        select * from tb1_employee where id=#{id}
    </select>

例2: 联合查询

<!--
		联合查询:级联属性封装结果集
	  -->
    <resultMap type="mybatis.bean.Employee" id="MyDifEmp">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="did" property="dept.id"/>
        <result column="dept_name" property="dept.departmentName"/>
    </resultMap>

    <select id="getEmpAndDept" resultType="mybatis.bean.Employee">
        select e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,d.dept_name dept_name
        from tb1_employee e,tb1_dept d
        where d.id=e.d_id and e.id = '001';
    </select>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值