ok了家人们书接上文,我们继续学习mybatis框架
五.数据输出
5.7 属性和字段的映射
5.7.1 别名映射
将数据库表的字段别名设置成和实体类属性一致。
<!-- 给每一个字段设置一个别名,让别名和Java实体类中
属性名一致 -->
<select id="findAll"
resultType="com.lzw.pojo.Employee">
select emp_id empId,emp_name
empName,emp_salary empSalary from t_emp
</select>
5.7.2 全局配置自动识别驼峰式命名规则
在Mybatis全局配置文件加入如下配置:
<!-- 使用settings对Mybatis全局进行设置 -->
<settings>
<!-- 将xxx_xxx这样的列名自动映射到xxXxx这样驼峰式命
名的属性名 -->
<setting name="mapUnderscoreToCamelCase"
value="true"/>
</settings>
SQL
语句中可以不使用别名
<select id="findAll" resultType="Employee">
select emp_id,emp_name,emp_salary from
t_emp
</select>
5.7.3 使用resultMap
使用
resultMap
标签定义对应关系,然后引用这个对应关系
//根据员工ID查询员工信息
public Employee findEmpById(Integer empId);
<!--
使用resultMap标签进行数据的封装
id属性:当前resultMap的唯一标识
type属性:最终稿封装的类型,一般写全限定名
-->
<resultMap id="empResultMap"
type="Employee">
<!--id标签维护主键列,property写Java实体的属
性名,column写数据库表的字段名-->
<id property="empId" column="emp_id">
</id>
<!--result标签维护普通列,property写Java实体
的属性名,column写数据库表的字段名-->
<result property="empName"
column="emp_name"></result>
<result property="empSalary"
column="emp_salary"></result>
</resultMap>
<!--resultMap="empResultMap" 引用上面的
resultMap-->
<select id="findEmpById"
resultMap="empResultMap">
select * from t_emp where emp_id = #
{empId}
</select>
@Test
public void testFindById() throws
IOException {
SqlSession sqlSession =
SqlSessionUtil.openSession();
//4.获取接口的实现类对象
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//5.基于多态调用方法
Employee employee =
employeeMapper.findEmpById(1);
//6.释放资源
sqlSession.close();
//7.打印
System.out.println(employee);
}
六.MyBatis多表映射
6.1 数据准备
表与表之间的关系:一对一、一对多、多对多
CREATE TABLE t_customer(
customer_id INT NOT NULL AUTO_INCREMENT,
customer_name CHAR(100),
PRIMARY KEY (customer_id)
);
CREATE TABLE t_order (
order_id INT NOT NULL AUTO_INCREMENT,
order_name CHAR(100),
customer_id INT,
PRIMARY KEY (order_id)
);
INSERT INTO t_customer (customer_name) VALUES
('张三');
INSERT INTO t_order (order_name, customer_id)
VALUES ('101', '1');
INSERT INTO t_order (order_name, customer_id)
VALUES ('102', '1');
INSERT INTO t_order (order_name, customer_id)
VALUES ('103', '1');
-- 创建讲师表
CREATE TABLE t_teacher (
t_id INT PRIMARY KEY,
t_name VARCHAR(50)
);
-- 创建学生表
CREATE TABLE t_student (
s_id INT PRIMARY KEY,
s_name VARCHAR(50)
);
-- 创建中间表
CREATE TABLE t_inner (
t_id INT,
s_id INT,
PRIMARY KEY (t_id, s_id)
);
-- 向讲师表中插入测试数据
INSERT INTO t_teacher VALUES (1, '张三');
INSERT INTO t_teacher VALUES (2, '李四');
INSERT INTO t_teacher VALUES (3, '王五');
一对一查询的语句:
-- 向学生表中插入测试数据
INSERT INTO t_student VALUES (1, '小明');
INSERT INTO t_student VALUES (2, '小红');
INSERT INTO t_student VALUES (3, '小刚');
-- 向中间表中插入测试数据
INSERT INTO t_inner VALUES (1, 1);
INSERT INTO t_inner VALUES (1, 3);
INSERT INTO t_inner VALUES (2, 2);
INSERT INTO t_inner VALUES (3, 1);
INSERT INTO t_inner VALUES (3, 3);
6.2 一对一查询
6.2.1 一对一查询的模型和SQL语句
用户表和订单表的关系为,一个用户有多个订单,一个订单只
从属于一个用户
一对一查询的需求:查询一个订单,与此同时查询出该订单所
属的用户
一对一查询的语句:
select
o.order_id,o.order_name,c.customer_id,c.customer
_name
from t_order o,t_customer c
where o.customer_id=c.customer_id
and o.order_id=1
6.2.2 创建Customer和Order实体
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
private Integer customerId;
private String customerName;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
private Integer orderId;
private String orderName;
//代表当前订单从属于哪一个客户
private Customer customer;
}
6.2.3 创建OrderMapper接口
public interface OrderMapper {
public Order findOrderById(Integer orderId);
}
6.2.4 配置OrderMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper
3.0//EN"
"https://mybatis.org/dtd/mybatis-3-
mapper.dtd">
<mapper namespace="com.lzw.mapper.OrderMapper">
<resultMap id="oderAndCustomerMap"
type="Order">
<id property="orderId"
column="order_id"></id>
<result property="orderName"
column="order_name"></result>
<!--
association标签维护一对一的关系
property属性:最终要封装的对象中的属性名
javaType属性:该属性的类型,可以是类的全限
定名或者别名
-->
<association property="customer"
javaType="Customer">
<id property="customerId"
column="customer_id"></id>
<result property="customerName"
column="customer_name"></result>
</association>
</resultMap>
<!--resultType:是自动封装,且只能封装一个对象-->
<select id="findOrderById"
resultMap="oderAndCustomerMap">
select
o.order_id,o.order_name,c.customer_id,c.customer
_name
from t_order o,t_customer c
where o.customer_id=c.customer_id
and o.order_id= #{orderId}
</select>
</mapper>
6.2.5 测试结果
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
OrderMapper orderMapper =
sqlSession.getMapper(OrderMapper.class);
//通过多态调用方法
Order order =
orderMapper.findOrderById(1);
//输出结果
System.out.println(order);
//释放资源
sqlSession.close();
}
6.3 一对多查询
6.3.1 一对多查询的模型和SQL语句
用户表和订单表的关系为,一个用户有多个订单,一个订单只
从属于一个用户
一对多查询的需求:查询一个用户,与此同时查询出该用户具
有的订单
一对多查询语句:
select
c.customer_id,c.customer_name,o.order_id,o.order
_name
from t_customer c,t_order o
where c.customer_id = o.customer_id
and c.customer_id = 1
6.3.2 创建Customer和Order实体
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
private Integer customerId;
private String customerName;
//表示当前用户有哪些订单
public List<Order> orderList;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
private Integer orderId;
private String orderName;
//代表当前订单从属于哪一个客户
private Customer customer;
}
6.3.3 创建CustomerMapper接口
public interface CustomerMapper {
public Customer findCustomerById(Integer
customerId);
}
6.3.4 配置CustomerMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper
3.0//EN"
"https://mybatis.org/dtd/mybatis-3-
mapper.dtd">
<mapper
namespace="com.lzw.mapper.CustomerMapper">
<resultMap id="customerAndOrderMap"
type="Customer">
<id property="customerId"
column="customer_id"></id>
<result property="customerName"
column="customer_name"></result>
<!--
collection标签:映射一对多的关联关系
property属性:实体类对象的属性名
ofType属性:集合属性中元素的类型
-->
<collection property="orderList"
ofType="Order">
<id property="orderId"
column="order_id"></id>
<result property="orderName"
column="order_name"></result>
</collection>
</resultMap>
<select id="findCustomerById"
parameterType="int"
resultMap="customerAndOrderMap">
select
c.customer_id,c.customer_name,o.order_id,o.order
_name
from t_customer c,t_order o
where c.customer_id = o.customer_id
and c.customer_id = #{customerId}
</select>
</mapper>
6.3.5 测试结果
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
CustomerMapper customerMapper =
sqlSession.getMapper(CustomerMapper.class);
//通过多态调用方法
Customer customer =
customerMapper.findCustomerById(1);
//输出结果
System.out.println(customer);
//释放资源
sqlSession.close();
}
6.4 多对多查询
6.4.1 多对多查询的模型和SQL语句
学生表和老师表的关系为,一个老师教过多个学生,一个学生
被多个老师教过
多对多查询的需求:查询老师同时查询出该老师教过哪些学生
select t.t_id,t.t_name,s.s_id,s_name
from t_teacher t,t_inner i,t_student s
where t.t_id=i.t_id and i.s_id=s.s_id and t.t_id
=1
select s.s_id,s_name,t.t_id,t.t_name
from t_student s,t_inner i,t_teacher t
where s.s_id=i.s_id and i.t_id=t.t_id and s.s_id
=1
6.4.2 创建Teacher和Student实体
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
private Integer tId;
private String tName;
//表示一个老师教过多个学生
private List<Student> studentList;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer sId;
private String sName;
//表示一个学生被多个老师教过
private List<Teacher> teacherList;
}
6.4.3 创建TeacherMapper和 StudentMapper接口
public interface TeacherMapper {
//根据ID查询老师信息
public Teacher findTeacherById(Integer tId);
}
public interface StudentMapper {
//根据ID查询学生信息
public Student findStudentById(Integer sId);
}
6.4.4 配置TeacherMapper.xml和 StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper
3.0//EN"
"https://mybatis.org/dtd/mybatis-3-
mapper.dtd">
<mapper
namespace="com.lzw.mapper.TeacherMapper">
<resultMap id="teacherResultMap"
type="Teacher">
<id property="tId" column="t_id"></id>
<result property="tName" column="t_name">
</result>
<collection property="studentList"
ofType="Student">
<id property="sId" column="s_id"></id>
<result property="sName"
column="s_name"></result>
</collection>
</resultMap>
<select id="findTeacherById"
parameterType="int"
resultMap="teacherResultMap">
select t.t_id,t.t_name,s.s_id,s_name
from t_teacher t,t_inner i,t_student s
where t.t_id=i.t_id and i.s_id=s.s_id and
t.t_id =#{tId}
</select>
</mapper>
------------------------------------------------
------------------------------------
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper
3.0//EN"
"https://mybatis.org/dtd/mybatis-3-
mapper.dtd">
<mapper
namespace="com.lzw.mapper.StudentMapper">
<resultMap id="studentResultMap"
type="Student">
<id property="sId" column="s_id"></id>
<result property="sName" column="s_name">
</result>
<collection property="teacherList"
ofType="Teacher">
<id property="tId" column="t_id"></id>
<result property="tName"
column="t_name"></result>
</collection>
</resultMap>
<select id="findStudentById"
parameterType="int"
resultMap="studentResultMap">
select s.s_id,s_name,t.t_id,t.t_name
from t_student s,t_inner i,t_teacher t
where s.s_id=i.s_id and i.t_id=t.t_id and
s.s_id =#{sId}
</select>
</mapper>
6.4.5 测试结果
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
TeacherMapper teacherMapper =
sqlSession.getMapper(TeacherMapper.class);
StudentMapper studentMapper =
sqlSession.getMapper(StudentMapper.class);
//通过多态调用方法
Teacher teacher =
teacherMapper.findTeacherById(1);
Student student =
studentMapper.findStudentById(1);
//输出结果
System.out.println(teacher);
System.out.println(student);
//释放资源
sqlSession.close();
}
七.MyBatis动态SQL
7.1 动态SQL需求和简介
经常遇到很多按照很多查询条件进行查询的情况,比如京东的
商品搜索等。其中经常出现很多条件不取值的情况,在后台应
该如何完成最终的
SQL
语句呢?
动态 SQL
是
MyBatis
的强大特性之一。如果你使用过
JDBC
或其它类似的框架,你应该能理解根据不同条件拼接
SQL
语
句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还
要注意去掉列表最后一个列名的逗号。利用动态
SQL
,可以
彻底摆脱这种痛苦。
7.2 动态SQL之和标签
7.2.1 编写接口方法
public interface EmployeeMapper {
//根据条件查询用户信息
public List<Employee>
findByCondition(Map<String,Object> map);
}
7.2.2 编写映射配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper
3.0//EN"
"https://mybatis.org/dtd/mybatis-3-
mapper.dtd">
<mapper
namespace="com.lzw.mapper.EmployeeMapper">
<!--
if标签:判断这个SQL语句片段是否要加入整个SQL语
句
true加入整个SQL语句中
false不加入整个SQL语句中
where标签:判断是否追加where关键字,会自动去除
多余的 and or关键字
-->
<select id="findByCondition"
resultType="Employee">
select * from t_emp
<where>
<if test="empName !=null">
emp_name = #{empName}
</if>
<if test="empSalary !=null">
and emp_salary = #{empSalary}
</if>
</where>
</select>
</mapper>
7.2.3 编写测试代码
@Test
public void testDemo(){
//使用工具类获取SqlSession对象
SqlSession sqlSession =
SqlSessionUtil.openSession();
//基于接口获取实现类对象(代理对象)
EmployeeMapper employeeMapper =
sqlSession.getMapper(EmployeeMapper.class);
//通过多态调用方法
Map<String,Object> map=new HashMap<>();
//map.put("empName","张三");
//map.put("empSalary",200.33);
List<Employee> employeeList =
employeeMapper.findByCondition(map);
//输出结果
System.out.println(employeeList);
//释放资源
sqlSession.close();
}
ok了家人们,明天见