目录
一、知识点
1、配置文件元素
二、概述
1、项目结构
2、描述
三、实例
1、mybatis-config.xml
2、db.properties
3、log4j.properties
4、mapper
(1)、IdCardMapper.xml
(2)、OrdersMapper.xml
(3)、PersonMapper.xml
(4)、ProductMapper.xml
(5)、UserMapper.xml
5、po
(1)、IdCard
(2)、Orders
(3)、Person
(4)、Product
(5)、User
6、test
(1)、MybatisAssociatedTest
7、utils
(1)、MybatisUtils
一、知识点
1、配置文件元素
<properties> |
该元素通常用于将内部的配置外化,即通过外部的配置来动态地替换内部定义。 |
|
<settings> |
cacheEnabled, |
该配置影响所有映射器中配置的缓存全局开关,true/false,默认false. |
lazyLoadingEnabled, |
延迟加载的全局开关,开启时,所有关联对象都会延迟加载,特定关联关系中可以通过设置fetchType属性来覆盖该项开关状态。默认false. |
aggressiveLazyLoading, |
关联对象属性的延迟加载开关,当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载,反之,每种属性都会按需加载。默认true. |
multipleResultSetsEnabled |
是否允许单一语句返回多结果集(需要兼容驱动)默认true. |
useColumnLable |
使用列标签代替列明。默认true. |
useGeneratedKeys |
允许jdbc支持自动生成主键,需要驱动兼容。默认false. |
autoMappingBehavior |
指定mybatis应如何自动映射列到字段或属性。NONE表示取消自动映射。PARTIAL只会自动映射没有定义嵌套结果集;FULL会自动映射任意复杂的结果集(无论是否嵌套)。 |
defaultExecutorType |
配置默认的执行器。SIMPLE就是普通的执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新。 |
defaultStatementTimeout |
设置超时时间,它决定驱动等待数据库响应的秒数。当没有设置的时候,它取的就是驱动默认的时间。 |
mapUnderscoreToCamelCase |
是否开启自动驼峰命名规则(camel case)映射 |
jdbcTypeForNull |
当没有为参数提供特定的JDBC类型时,为空值指定JDBC类型。某些驱动需要指定列的JDBC类型,多数情况直接用一般类型即可,比如:NULL,VARCHAR,OTHER.默认OTHER |
<typeAliases> |
用于为配置文件中的JAVA类型设置一个简短的名字。即设置别名,别名的设置与XML配置相关,其使用意义在于减少全限定类名的冗余。 |
<typeAliases><typeAlias alias="user" type="com.po.User"></typeAliases>。默认小写。 |
<typeHandler> |
javaType与jdbcType的转换。 |
<typeHandler><typeHandler handler="com.type.CustomtypeHandler"></typeHandler>,注册一个类的类型处理器。 |
<objectFactory> |
实例化目标类。默认构造方法实例化,有参构造方法实例化。 |
<plugins> |
插件拦截 |
<enviroments> |
配置数据源,数据库。 |
UNPOOLED |
driver |
JDBC驱动的JAVA类的完全限定名。 |
url |
URL地址 |
username |
用户名 |
password |
登录数据库的密码 |
defaultTransactionlationLevel |
默认的连接事务隔离级别。 |
POOLED |
此数据源利用“池”的概念将JDBC连接对象组织起来。 |
|
poolMaximumActiveConnections |
在任意时间可以存在的活动。连接数量。默认值:10 |
poolMaximumConnections |
任意时间可能存在的空闲连接数 |
poolMaximumCheckoutTime |
在被强制返回前,池中连接被检出时间默认值20秒。 |
poolTimeToWait |
连接超时,重新尝试获取。默认时间20秒 |
poolPingQuery |
用于检测连接是否在正常工作秩序。 |
poolPingEnabled |
配置。侦测查询,必须使用一个可执行SQL语句设置poolPingQuery属性(最好是一个非常快的SQL ) |
poolPingConnectionsNotUsedFor |
poolPingQuery的使用调度,可以设置超时时间,避免不要的侦测,默认值:0。poolPingEnabled为true时适用。 |
JNDI |
可以在EJB或应用服务器容器中使用,容器可以集中或在外部配置数据源。然后放置一个JDNI上下文引用。 |
<mappers> |
用于指定MyBatis映射文件的位置,四种方式:<mappers><mapper resource="com.stx.UserMapper.xml"><mapper url="file:///D:/com/stx/UserMapper.xml"><mapper class="com.stx.UserMapper"><packge name="com.stx.mapper"></mappers> |
<select> |
id |
表示命名空间的唯一标识,常与命名空间组合起来使用。组合后如果不唯一,mybatis会抛出异常。 |
parameterType |
该属性表示传入SQL语句的参数类的全限定名或者别名。它是一个可选属性,因为MyBatis可以通过TypeHandler推断出具体传入语句的参数,其默认值是unset(依赖于驱动)。 |
resultType |
从SQL语句中返回的类型的类的全限定名或者别名,(从SQL返回类的别名),如果是集合类型,那么返回的是集合可以包含的类型,而不是集合本身。返回时可以使用resultType或resultMap之一。 |
resultMap |
表示外部的命名引用。返回时可以使用resultType或resultMap之一。 |
flushCache |
在调用SQL之后,是否需要MyBatis清空之前查询的本地缓存和二级缓存。其值为布尔,默认值false.调用就会被清空。 |
useCache |
控制二级缓存的开启和关闭。布尔,默认true,查询结果存入二级缓存。 |
timeout |
超时参数,超时抛出异常。 |
fetchSize |
获取记录总条数,超时抛出异常。 |
statementType |
用于设置MyBatis使用那个JDBC的Statement工作,其值STATEMENT,PREPARED,CALLABLE,分别对应JDBC中的statement,PreparedStatement和CallableStatement。 |
resultSetType |
表示结果集的类型,其值可设置为FORWARD_ONLY,SCROLL_SENSITIVE或SCROLL_INSENSITIVE,他的默认值unset(依赖于驱动) |
<insert> |
keyProperty |
(仅对insert和update有用)插入,更新,返回值赋值给PO类的某个属性。通常会设置主键对应的属性。联合主键,多个值逗号隔开。 |
keyColumn |
用于设置第几列是主键,不是第一列就设置,多个就用逗号隔开。 |
useGeneratedKeys |
此属性会使用MyBatis使用JDBC的getGeneratedKeys()方法来获取由数据库内部生产的主键,如MySql和SQL Server等自动递增字段,默认值false。 |
<update>和<delete> |
|
|
<sql> |
|
|
<resultMap> |
表示结果集映射(这个很重要) |
|
二、概述
1、项目结构
2、描述
(1)映射就是把数据库的表映射到实体类上面,这是一对一的映射。但是随着业务的复杂度提高,关系的复杂性使得,一对一的映射关系不能满足。所以诞生了更多是关系。就出现一对多,多对多。
(2)直观:就是把mapper设置到mabatis核心配置。mapper里面的查询结果可能包括多个表,因此需要用到resultmap里面。
三、实例
1、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">
<configuration>
<!-- 引入数据库连接配置文件 -->
<properties resource="db.properties" />
<settings>
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 将积极加载改为消息加载,即按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--使用扫描包的形式定义别名 -->
<typeAliases>
<package name="com.itheima.po" />
</typeAliases>
<!--配置环境 ,默认的环境id为mysql -->
<environments default="mysql">
<!-- 配置id为mysql的数据库环境 -->
<environment id="mysql">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<!--数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!--配置Mapper的位置 -->
<mappers>
<mapper resource="com/itheima/mapper/IdCardMapper.xml" />
<mapper resource="com/itheima/mapper/PersonMapper.xml" />
<mapper resource="com/itheima/mapper/UserMapper.xml" />
<mapper resource="com/itheima/mapper/OrdersMapper.xml" />
<mapper resource="com/itheima/mapper/ProductMapper.xml" />
</mappers>
</configuration>
2、db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456
3、log4j.properties
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.itheima=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
4、mapper
(1)、IdCardMapper.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="com.itheima.mapper.IdCardMapper">
<!-- 根据id查询证件信息 -->
<select id="findCodeById" parameterType="Integer" resultType="IdCard">
SELECT * from tb_idcard where id=#{id}
</select>
</mapper>
(2)、OrdersMapper.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="com.itheima.mapper.OrdersMapper">
<!-- 多对多嵌套查询:通过执行另外一条SQL映射语句来返回预期的特殊类型 -->
<select id="findOrdersWithPorduct" parameterType="Integer"
resultMap="OrdersWithProductResult">
select * from tb_orders WHERE id=#{id}
</select>
<resultMap type="Orders" id="OrdersWithProductResult">
<id property="id" column="id" />
<result property="number" column="number" />
<collection property="productList" column="id" ofType="Product"
select="com.itheima.mapper.ProductMapper.findProductById">
</collection>
</resultMap>
<!-- 多对多嵌套结果查询:查询某订单及其关联的商品详情 -->
<select id="findOrdersWithPorduct2" parameterType="Integer"
resultMap="OrdersWithPorductResult2">
select o.*,p.id as pid,p.name,p.price
from tb_orders o,tb_product p,tb_ordersitem oi
WHERE oi.orders_id=o.id
and oi.product_id=p.id
and o.id=#{id}
</select>
<!-- 自定义手动映射类型 -->
<resultMap type="Orders" id="OrdersWithPorductResult2">
<id property="id" column="id" />
<result property="number" column="number" />
<!-- 多对多关联映射:collection -->
<collection property="productList" ofType="Product">
<id property="id" column="pid" />
<result property="name" column="name" />
<result property="price" column="price" />
</collection>
</resultMap>
</mapper>
(3)、PersonMapper.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="com.itheima.mapper.PersonMapper">
<!-- 嵌套查询:通过执行另外一条SQL映射语句来返回预期的特殊类型 -->
<select id="findPersonById" parameterType="Integer"
resultMap="IdCardWithPersonResult">
SELECT * from tb_person where id=#{id}
</select>
<resultMap type="Person" id="IdCardWithPersonResult">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="age" column="age" />
<result property="sex" column="sex" />
<!-- 一对一:association使用select属性引入另外一条SQL语句 -->
<association property="card" column="card_id" javaType="IdCard"
select="com.itheima.mapper.IdCardMapper.findCodeById" />
</resultMap>
<!-- 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集 -->
<select id="findPersonById2" parameterType="Integer"
resultMap="IdCardWithPersonResult2">
SELECT p.*,idcard.code
from tb_person p,tb_idcard idcard
where p.card_id=idcard.id
and p.id= #{id}
</select>
<resultMap type="Person" id="IdCardWithPersonResult2">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="age" column="age" />
<result property="sex" column="sex" />
<association property="card" javaType="IdCard">
<id property="id" column="card_id" />
<result property="code" column="code" />
</association>
</resultMap>
</mapper>
(4)、ProductMapper.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="com.itheima.mapper.ProductMapper">
<select id="findProductById" parameterType="Integer"
resultType="Product">
SELECT * from tb_product where id IN(
SELECT product_id FROM tb_ordersitem WHERE orders_id = #{id}
)
</select>
</mapper>
(5)、UserMapper.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表示命名空间 -->
<mapper namespace="com.itheima.mapper.UserMapper">
<!-- 一对多:查看某一用户及其关联的订单信息
注意:当关联查询出的列名相同,则需要使用别名区分 -->
<select id="findUserWithOrders" parameterType="Integer"
resultMap="UserWithOrdersResult">
SELECT u.*,o.id as orders_id,o.number
from tb_user u,tb_orders o
WHERE u.id=o.user_id
and u.id=#{id}
</select>
<resultMap type="User" id="UserWithOrdersResult">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
<!-- 一对多关联映射:collection
ofType表示属性集合中元素的类型,List<Orders>属性即Orders类 -->
<collection property="ordersList" ofType="Orders">
<id property="id" column="orders_id"/>
<result property="number" column="number"/>
</collection>
</resultMap>
</mapper>
5、po
(1)、IdCard
package com.itheima.po;
/**
* 证件持久化类
*/
public class IdCard {
private Integer id;
private String code;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "IdCard [id=" + id + ", code=" + code + "]";
}
}
(2)、Orders
package com.itheima.po;
/**
* 证件持久化类
*/
public class IdCard {
private Integer id;
private String code;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "IdCard [id=" + id + ", code=" + code + "]";
}
}
(3)、Person
package com.itheima.po;
/**
* 个人持久化类
*/
public class Person {
private Integer id;
private String name;
private Integer age;
private String sex;
private IdCard card; //个人关联的证件
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public IdCard getCard() {
return card;
}
public void setCard(IdCard card) {
this.card = card;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", "
+ "age=" + age + ", sex=" + sex + ", card=" + card + "]";
}
}
(4)、Product
package com.itheima.po;
import java.util.List;
/**
* 商品持久化类
*/
public class Product {
private Integer id; //商品id
private String name; //商品名称
private Double price;//商品单价
private List<Orders> orders; //与订单的关联属性
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 Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public List<Orders> getOrders() {
return orders;
}
public void setOrders(List<Orders> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "Product [id=" + id + ", name=" + name
+ ", price=" + price + "]";
}
}
(5)、User
package com.itheima.po;
import java.util.List;
/**
* 用户持久化类
*/
public class User {
private Integer id; // 用户编号
private String username; // 用户姓名
private String address; // 用户地址
private List<Orders> ordersList; //用户关联的订单
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Orders> getOrdersList() {
return ordersList;
}
public void setOrdersList(List<Orders> ordersList) {
this.ordersList = ordersList;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", address="
+ address + ", ordersList=" + ordersList + "]";
}
}
6、test
(1)、MybatisAssociatedTest
package com.itheima.test;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.itheima.po.Orders;
import com.itheima.po.Person;
import com.itheima.po.User;
import com.itheima.utils.MybatisUtils;
/**
* Mybatis关联查询映射测试类
*/
public class MybatisAssociatedTest {
/**
* 嵌套查询
*/
@Test
public void findPersonByIdTest() {
// 1、通过工具类生成SqlSession对象
SqlSession session = MybatisUtils.getSession();
// 2.使用MyBatis嵌套查询的方式查询id为1的人的信息
Person person = session.selectOne("com.itheima.mapper."
+ "PersonMapper.findPersonById", 1);
// 3、输出查询结果信息
System.out.println(person);
// 4、关闭SqlSession
session.close();
}
/**
* 嵌套结果
*/
@Test
public void findPersonByIdTest2() {
// 1、通过工具类生成SqlSession对象
SqlSession session = MybatisUtils.getSession();
// 2.使用MyBatis嵌套结果的方法查询id为1的人的信息
Person person = session.selectOne("com.itheima.mapper."
+ "PersonMapper.findPersonById2", 1);
// 3、输出查询结果信息
System.out.println(person);
// 4、关闭SqlSession
session.close();
}
/**
* 一对多
*/
@Test
public void findUserTest() {
// 1、通过工具类生成SqlSession对象
SqlSession session = MybatisUtils.getSession();
// 2、查询id为1的用户信息
User user = session.selectOne("com.itheima.mapper."
+ "UserMapper.findUserWithOrders", 1);
// 3、输出查询结果信息
System.out.println(user);
// 4、关闭SqlSession
session.close();
}
/**
* 多对多
*/
@Test
public void findOrdersTest(){
// 1、通过工具类生成SqlSession对象
SqlSession session = MybatisUtils.getSession();
// 2、查询id为1的订单中的商品信息
Orders orders = session.selectOne("com.itheima.mapper."
+ "OrdersMapper.findOrdersWithPorduct", 1);
// 3、输出查询结果信息
System.out.println(orders);
// 4、关闭SqlSession
session.close();
}
}
7、utils
(1)、MybatisUtils
package com.itheima.utils;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* 工具类
*/
public class MybatisUtils {
public static SqlSessionFactory sqlSessionFactory = null;
// 初始化SqlSessionFactory对象
static{
try {
//使用MyBatis提供的Resources类加载mybatis的配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
//构建sqlSession的工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取SqlSession对象的静态方法
public static SqlSession getSession(){
return sqlSessionFactory.openSession();
}
}