笔记52 Mybatis快速入门(三)
一、更多查询
1.模糊查询
修改Category.xml,提供listCategoryByName查询语句select * from category where name like concat('%',#{0},'%')。concat('%',#{0},'%') 这是mysql的写法,如果是oracle,写法是select * from category_ where name like '%'||#{0}||'%'。
<select id="listCategoryByName" parameterType="string" resultType="Category">
select * from category where name like concat('%',#{0},'%')
</select>
private void queryByName() throws IOException {
create();
List<Category> categories = session.selectList("listCategoryByName", "i");
for (Category category : categories) {
System.out.println(category.getName());
}
close();
}
2.多条件查询
结合前面的模糊查询,多一个限定id的条件。因为是多个参数,而selectList方法又只接受一个参数对象,所以需要把多个参数放在Map里,然后把这个Map对象作为参数传递进去。
private void queryByNameId() throws IOException {
create();
Map<String, Object> params = new HashMap<String, Object>();
params.put("id", 8);
params.put("name", "xiao");
List<Category> categories = session.selectList("listCategoryByNameId", params);
for (Category category : categories) {
System.out.println(category.getName());
}
close();
}
<select id="listCategoryByNameId" parameterType="map"
resultType="Category">
select * from category where id>#{id} and name like
concat('%',#{0},'%')
</select>
二、Mybatis的关系映射
1.一对多(一个分类对应多个产品)
<1>创建产品表以及产品表对应的实体。

package mybatis.pojo;
public class Product {
private int id;
private String name;
private float price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public String toString() {
return "Product [id=" + id + ", name=" + name + ", price=" + price + "]";
}
}
<2>修改Category实体类,提供product集合。
package mybatis.pojo;
import java.util.List;
public class Category {
private int id;
private String name;
private List<Product> products;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public String toString() {
return "Category [id=" + id + ", name=" + name + "]";
}
}
<3>修改Category.xml
通过left join关联查询,对Category和Product表进行关联查询。与前面学习的有所区别,这里不是用的resultType, 而是resultMap,通过resultMap把数据取出来放在对应的对象属性里。
注: Category的id字段和Product的id字段同名,Mybatis不知道谁是谁的,所以需要通过取别名cid,pid来区分,name字段同理。
<?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.pojo">
<resultMap type="Category" id="categoryBean">
<id column="cid" property="id" />
<result column="cname" property="name" /> <!-- 一对多关系 -->
<!-- property:指定的是集合属性的值,ofType:指的是集合中元素的类型 -->
<collection property="products" ofType="Product">
<id column="pid" property="id"></id>
<result column="pname" property="name" />
<result column="price" property="price" />
</collection>
</resultMap>
<!-- 关联查询分类和产品表 -->
<select id="listCategory" resultMap="categoryBean">
select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' from
category c left join product p on c.id = p.cid
</select>
</mapper>
<4>测试
package mybatis.test; import java.io.IOException;
import java.io.InputStream;
import java.util.List; import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; import mybatis.pojo.Category;
import mybatis.pojo.Product; public class testOneToMany { public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String resource = "mybatis-config.xml";
InputStream inputStream = org.apache.ibatis.io.Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
List<Category> categories = session.selectList("listCategory");
for (Category c : categories) {
System.out.println(c);
List<Product> products = c.getProducts();
for (Product product : products) {
System.out.println("\t" + product.toString());
}
}
session.commit();
session.close();
} }
2.多对一(多个产品对应一个分类)
<1>修改Product.java,增加category属性
package mybatis.pojo;
import java.util.List;
public class Category {
private int id;
private String name;
private List<Product> products;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public String toString() {
return "Category [id=" + id + ", name=" + name + "]";
}
}
<2>新增Product.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.pojo"> <select id="getProduct" parameterType="int" resultType="Product">
select *
from product where id= #{id}
</select> <update id="updateProduct" parameterType="map">
update product
set cid=#{cid} where id=#{pid}
</update> <update id="updateProduct2" parameterType="Product">
update product
set cid=#{category.id} where id=#{id}
</update> <resultMap type="Product" id="productBean">
<id column="pid" property="id" />
<result column="pname" property="name" />
<result column="price" property="price" /> <!-- 多对一关系 -->
<!-- property:指定的是集合属性的值,ofType:指的是集合中元素的类型 -->
<association property="category" javaType="Category">
<id column="cid" property="id" />
<result column="cname" property="name" />
</association>
</resultMap>
<!-- 关联查询分类和产品表 -->
<select id="listProduct" resultMap="productBean">
select c.*, p.*, c.id 'cid',
p.id 'pid', c.name 'cname', p.name 'pname' from
category c left join
product p on c.id = p.cid
</select>
</mapper>
通过listProduct配置关联查询的sql语句。然后通过resultMap ,进行字段和属性的对应。使用association 进行多对一关系关联,指定表字段名称与对象属性名称的一一对应关系。
注: Category的id 字段 和Product的id字段同名,Mybatis不知道谁是谁的,所以需要通过取别名cid,pid来区分。name字段同理。
<3>在mybatis-config.xml中增加对于Product.xml的映射
<mapper resource="mybatis/pojo/Product.xml" />
<4>测试
package mybatis.test; import java.io.IOException;
import java.io.InputStream;
import java.util.List; import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; import mybatis.pojo.Category;
import mybatis.pojo.Product; public class testManyToOne { public static void update() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = org.apache.ibatis.io.Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession(); Category category = session.selectOne("getCategory", 1);
Product product = session.selectOne("getProduct", 6);
product.setCategory(category);
session.update("updateProduct2", product); // Map<String, Integer> params = new HashMap<String, Integer>();
// params.put("cid", category.getId());
// params.put("pid", product.getId());
//
// session.update("updateProduct", params); session.commit();
session.close();
} public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
update();
String resource = "mybatis-config.xml";
InputStream inputStream = org.apache.ibatis.io.Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession(); List<Product> products = session.selectList("listProduct");
for (Product product : products) {
System.out.println(product + "\t对应的分类是:" + product.getCategory()); } session.commit();
session.close(); } }
练习:修改product(id=5)对应的类别为category(id=1)
两种解决思路
<1>首先查询id=5的product,再查询id=1的category,然后调用setCategory方法设置类别,然后对product进行更新操作。
<2>首先查询id=5的product,然后直接设置参数对product进行修改。
①先准备必要的sql语句。
Product.xml中
在updateProduct2中,因为product的成员变量中包含catergory对象,所以直接使用category.id获取类别的id。
<select id="getProduct" parameterType="int" resultType="Product">
select *
from product where id= #{id}
</select> <update id="updateProduct" parameterType="map">
update product
set cid=#{cid} where id=#{pid}
</update> <update id="updateProduct2" parameterType="Product">
update product
set cid=#{category.id} where id=#{id}
</update>
Category.xml中
<select id="getCategory" parameterType="int" resultType="Category">
select *
from category where id= #{id}
</select>
②测试
第一种思路
public static void update() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = org.apache.ibatis.io.Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
Category category = session.selectOne("getCategory", 1);
Product product = session.selectOne("getProduct", 6);
product.setCategory(category);
session.update("updateProduct2", product);
session.commit();
session.close();
}
第二种思路
public static void update() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = org.apache.ibatis.io.Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
Product product = session.selectOne("getProduct", 6);
Map<String, Integer> params = new HashMap<String, Integer>();
params.put("cid", 1);
params.put("pid", product.getId());
session.update("updateProduct", params);
session.commit();
session.close();
}
3.多对多(一张订单可以包含多种产品,一种产品可以出现在多张订单中)
为了维系多对多关系,必须要一个中间表。 在这里我们使用订单项(OrderItem)表来作为中间表。
<1>建立order表,order_item表

<2>添加数据
INSERT INTO order_ VALUES (1,'code000A');
INSERT INTO order_ VALUES (2,'code000B'); INSERT INTO order_item VALUES (null, 1, 1, 100);
INSERT INTO order_item VALUES (null, 1, 2, 100);
INSERT INTO order_item VALUES (null, 1, 3, 100);
INSERT INTO order_item VALUES (null, 2, 2, 100);
INSERT INTO order_item VALUES (null, 2, 3, 100);
INSERT INTO order_item VALUES (null, 2, 4, 100);
<3>添加实体类Order和OrderItem
①Order.java
package mybatis.pojo;
import java.util.List;
public class Order {
private int id;
private String code;
private List<OrderItem> orderItems;
public List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
②OrderItem.java
package mybatis.pojo;
public class OrderItem {
private int id;
private int number;
private Order order;
private Product product;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
}
<4>映射文件
①Order.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.pojo">
<resultMap type="Order" id="orderBean">
<id column="oid" property="id" />
<result column="code" property="code" /> <collection property="orderItems" ofType="OrderItem">
<id column="oiid" property="id" />
<result column="number" property="number" />
<association property="product" javaType="Product">
<id column="pid" property="id" />
<result column="pname" property="name" />
<result column="price" property="price" />
</association>
</collection>
</resultMap> <select id="listOrder" resultMap="orderBean">
select o.*,p.*,oi.*, o.id
'oid', p.id 'pid', oi.id 'oiid', p.name 'pname'
from order_ o
left join
order_item oi on o.id =oi.oid
left join product p on p.id = oi.pid
</select>
<select id="getOrder" resultMap="orderBean">
select o.*,p.*,oi.*, o.id 'oid', p.id 'pid', oi.id 'oiid', p.name 'pname'
from order_ o
left join order_item oi on o.id =oi.oid
left join product p on p.id = oi.pid
where o.id = #{id}
</select>
</mapper>
②Product.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.pojo"> <!--
<select id="getProduct" parameterType="int" resultType="Product">
select *
from product where id= #{id}
</select>--> <update id="updateProduct" parameterType="map">
update product
set
cid=#{cid} where id=#{pid}
</update> <update id="updateProduct2" parameterType="Product">
update product
set
cid=#{category.id} where id=#{id}
</update> <resultMap type="Product" id="productBean">
<id column="pid" property="id" />
<result column="pname" property="name" />
<result column="price" property="price" /> <!-- 多对一关系 -->
<!-- property:指定的是集合属性的值,ofType:指的是集合中元素的类型 -->
<association property="category" javaType="Category">
<id column="cid" property="id" />
<result column="cname" property="name" />
</association>
</resultMap>
<!-- 关联查询分类和产品表 -->
<select id="listProduct" resultMap="productBean">
select c.*, p.*, c.id 'cid',
p.id 'pid', c.name 'cname', p.name 'pname' from
category c left join
product p on c.id = p.cid
</select>
<select id="getProduct" resultMap="productBean">
select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname'
from category c
left join product p on c.id = p.cid
where p.id = #{id}
</select>
</mapper>
③OrderItem.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.pojo">
<insert id="addOrderItem" parameterType="OrderItem">
insert into order_item
values(null,#{order.id},#{product.id},#{number})
</insert>
<insert id="deleteOrderItem" parameterType="OrderItem">
delete from order_item
where oid = #{order.id} and pid = #{product.id}
</insert>
</mapper>
<5>修改mybatis-config.xml
<mapper resource="mybatis/pojo/Order.xml" />
<mapper resource="mybatis/pojo/OrderItem.xml" />
<6>查询操作
查询出所有的订单,然后遍历每个订单下的多条订单项,以及订单项对应的产品名称,价格,购买数量。通过Order.xml的listOrder对应的sql语句进行查询:
<select id="listOrder" resultMap="orderBean">
select o.*,p.*,oi.*, o.id
'oid', p.id 'pid', oi.id 'oiid', p.name 'pname'
from order_ o
left join
order_item oi on o.id =oi.oid
left join product p on p.id = oi.pid
</select>
联合order_, order_item_, product_ 三张表进行查询
<resultMap type="Order" id="orderBean">
<id column="oid" property="id" />
<result column="code" property="code" /> <collection property="orderItems" ofType="OrderItem">
<id column="oiid" property="id" />
<result column="number" property="number" />
<association property="product" javaType="Product">
<id column="pid" property="id" />
<result column="pname" property="name" />
<result column="price" property="price" />
</association>
</collection>
</resultMap>
private static void listOrder(SqlSession session) {
List<Order> orders = session.selectList("listOrder");
for (Order order : orders) {
System.out.println(order.getCode());
List<OrderItem> orderItems = order.getOrderItems();
for (OrderItem orderItem : orderItems) {
System.out.format("\t%s\t%f\t%d\n", orderItem.getProduct().getName(), orderItem.getProduct().getPrice(),
orderItem.getNumber());
}
}
}

<7>建立关系
建立了让订单000A和产品z建立了关系。首先通过id分别获取Ordre对象和Product对象,然后创建一个新的OrderItem对象,接着设置Order,设置Product,设置数量,最后调用"addOrderItem" 对应的sql语句插入数据。
private static void addOrderItem(SqlSession session) {
Order order = session.selectOne("getOrder", 1);
Product product = session.selectOne("getProduct", 6);
OrderItem orderItem = new OrderItem();
orderItem.setProduct(product);
orderItem.setOrder(order);
orderItem.setNumber(200);
session.insert("addOrderItem", orderItem);
}
addOrderItem调用insert into 语句插入一条OrderItem记录:
<insert id="addOrderItem" parameterType="OrderItem">
insert into order_item
values(null,#{order.id},#{product.id},#{number})
</insert>

<8>删除关系
删除了订单00A和产品z的关系,再次查询,就看不到产品z了。删除关系的时候,通过订单id(1)和产品id(6)进行删除。其实所谓的删除关系,就是删除掉OrderItem记录。
private static void deleteOrderItem(SqlSession session) {
Order order = session.selectOne("getOrder", 1);
Product product = session.selectOne("getProduct", 6);
OrderItem orderItem = new OrderItem();
orderItem.setProduct(product);
orderItem.setOrder(order);
session.delete("deleteOrderItem", orderItem);
}
练习:删除订单A,那么就应该删除订单A在订单项里所对应的数据。
通过Mybatis执行多条sql语句需要增加一个参数:allowMultiQueries,多条语句之间用分号隔开。
<property name="url" value="jdbc:mysql://localhost:3306/test2?characterEncoding=UTF-8&allowMultiQueries=true" />
<delete id="deleteOrder" parameterType="Order">
delete from
order_ where code = #{code};
delete from
order_item
where oid = #{id}
</delete>
private static void deleteOrder(SqlSession session) {
Order order = session.selectOne("getOrder", 1);
session.delete("deleteOrder", order);
}
笔记52 Mybatis快速入门(三)的更多相关文章
- MyBatis学习笔记(一)——MyBatis快速入门
转自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/4261895.html 一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优 ...
- 笔记50 Mybatis快速入门(一)
一.Mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...
- 笔记56 Mybatis快速入门(七)
相关概念介绍(二) 6.一级缓存 <1>在一个session里查询相同id的数据 package mybatis.annotation; import java.io.IOExceptio ...
- 笔记53 Mybatis快速入门(四)
动态SQL 1.if 假设需要对Product执行两条sql语句,一个是查询所有,一个是根据名称模糊查询.那么按照现在的方式,必须提供两条sql语句:listProduct和listProductBy ...
- 笔记55 Mybatis快速入门(六)
相关概念介绍(一) 1.日志 有时候需要打印日志,知道mybatis执行了什么样的SQL语句,以便进行调试.这时,就需要开启日志,而mybatis自身是没有带日志的,使用的都是第三方日志,这里介绍如何 ...
- 笔记54 Mybatis快速入门(五)
Mybatis中注解的使用 1.XML方式的CRUD 新增加接口CategoryMapper ,并在接口中声明的方法上,加上注解对比配置文件Category.xml,其实就是把SQL语句从XML挪到了 ...
- 笔记51 Mybatis快速入门(二)
Mybatis的CRUD 1.修改配置文件Category.xml,提供CRUD对应的sql语句. <?xml version="1.0" encoding="UT ...
- MyBatis学习总结(一)——MyBatis快速入门
一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...
- MyBatis快速入门
一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...
随机推荐
- PAT 乙级练习题1001 害死人不偿命的(3n+1)猜想 (15)
1001. 害死人不偿命的(3n+1)猜想 (15) 卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去, ...
- JNI intArray
JNIDemo.java public class JNIDemo { static { /* 1. load */ System.loadLibrary("native"); / ...
- Centos7系统安装笔记
Centos 7安装步骤 对应参数,可修改 1.一台主机对应一个服务器,需要先安装Centos 7(内网)2.F12 boot 进入boot模式3.选择安装方式:USE或其他4.根据底部文字提示,点击 ...
- Java创建线程后,调用start()方法和run()的区别
1) start方法: 用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码.通过调用Thread类的start()方法来启动一个线程,这时此 ...
- 【TJOI2018】教科书般的亵渎
题面 题目描述 小豆喜欢玩游戏,现在他在玩一个游戏遇到这样的场面,每个怪的血量为\(a_i\),且每个怪物血量均不相同,小豆手里有无限张"亵渎".亵渎的效果是对所有的怪造成11点伤 ...
- spring中后台接收参数总结
@RequestParam注解用于将指定的请求参数赋值给方法的参数 @RequestMapping(“/login”) public void login(@RequestParam(name=“lo ...
- 二进制搭建一个完整的K8S集群部署文档
服务器规划 角色 IP 组件 k8s-master1 192.168.31.63 kube-apiserver kube-controller-manager kube-scheduler etcd ...
- Ubuntu 图形桌面死机重启(机器不重启)
Ubuntu的图形界面容易死机,如果正在跑程序的话又不能重启.这时候可以通过终端来_重启_图形界面. 首先按Alt+Ctrl+F1进入终端界面.查看图形界面的进程: ps -t tty7 查看到名为X ...
- 如何设置和使用MacOS上的Microsoft Office套件
自30年前首次发布以来,Microsoft Office已成为全球最受欢迎的生产力套件之一.借助Word和Excel for Mac之类的程序,毫无疑问,MS Office套件在任何计算机上都是必须下 ...
- 页面background不随滚动条填充颜色
这我又遇到了个问题,这问题我连问都不知道该怎么问,先搁在这儿,如果有办法了,再来补充. 原因:因为颜色板块是100%宽度,和页面保持同宽,所以拖动滚动条,右侧就大于了页面宽度. bug: 我写页面的 ...