商品和品牌之间的一对多与多对一
<dependencies>
<!-- mybatis核心依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!-- mysql连接依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- log4j日志依赖 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
log4j.properties
### 设置###
# debug 日志级别,常用的4个日志级别:ERROR、WARN、 INFO、DEBUG
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
jdbc.properties
注意mybatis版本>=6.0使用如下驱动,如果<6.0使用com.mysql.jdbc.Driver
#driver=com.mysql.cj.jdbc.Driver
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day200720?useUnicode=true&characterEncoding=UTF-8&&serverTimezone=Hongkong&useSSL=false
username=root
password=root
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>
<!--引入jdbc属性配置-->
<properties resource="jdbc.properties"></properties>
<settings>
<!--开启驼峰规则映射-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 设置别名,在mapper.xml中指定类型时可以简化书写-->
<!--
resultType="com.czxy.mybatis.model.User"
简化为
resultType="user"
-->
<typeAliases>
<!--给某一个类取别名-->
<typeAlias type="com.czxy.bean.User" alias="user"></typeAlias>
<!--扫描某一个包下的类,指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean-->
<!--这样有10个或者100个类不用一个个取指定别名-->
<package name="com.czxy.bean"/>
<package name="com.czxy.dao"/>
</typeAliases>
<!--mybatis的核心环境配置-->
<environments default="development">
<environment id="development">
<!--
在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]"):
JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施
MANAGED – 这个配置几乎没做什么
-->
<transactionManager type="JDBC"/>
<!--type可选值:UNPOOLED 不使用连接池
POOLED使用连接池
JNDI 从配置好的JNDI数据源获取连接池-->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--映射器-->
<mappers>
<!--添加映射文件-->
<!--xml配置文件使用-->
<mapper resource="mapper\BrandMapperInterFace.xml"/>
<mapper resource="mapper\ProductMapperInterFace.xml"/>
</mappers>
</configuration>
在resource目录下新建mapper目录,存放BrandMapperInterFace.xml、ProductMapperInterFace.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.czxy.dao.BrandMapper">
<!--
id:sql片段的唯一标识,同一个mapper文件中不能重复
parameterType:参数类型
resultType:返回值类型
-->
<resultMap id="selectProductsByBrandId" type="Brand" >
<id property="brandId" column="brand_id"/>
<result property="brandName" column="brand_name"/>
<result property="brandImg" column="brand_img"/>
<collection property="products" select="com.czxy.dao.ProductMapper.selectProByBrandId" column="brand_Id"/>
</resultMap>
<select id="selectBrandByBrandId" resultMap="selectProductsByBrandId">
SELECT
brand_id,
brand_name,
brand_img
FROM brands
WHERE brand_id = #{brandId}
</select>
<select id="selectBrByBrandId" resultType="Brand">
SELECT
brand_id,
brand_name,
brand_img
FROM brands
WHERE brand_id = #{brandId}
</select>
</mapper>
<?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.czxy.dao.ProductMapper">
<!--
id:sql片段的唯一标识,同一个mapper文件中不能重复
parameterType:参数类型
resultType:返回值类型
-->
<select id="selectProByBrandId" resultType="Product">
SELECT
product_id,
product_img,
product_name,
product_sale,
stock,
product_price,
brandid
FROM product
WHERE brandid = #{brandId}
</select>
<resultMap id="selectProductAndBrandByProductId" type="Product">
<id property="productId" column="product_id"/>
<result property="productImg" column="product_img"/>
<result property="productName" column="product_name"/>
<result property="productSale" column="product_sale"/>
<result property="stock" column="stock"/>
<result property="productPrice" column="product_price"/>
<result property="brandId" column="brandid"/>
<collection property="brand" select="com.czxy.dao.BrandMapper.selectBrByBrandId" column="brandid"/>
</resultMap>
<select id="selectProductByProductId" resultMap="selectProductAndBrandByProductId">
SELECT
product_id,
product_img,
product_name,
product_sale,
stock,
product_price,
brandid
FROM product
WHERE product_id = #{productId}
</select>
</mapper>
package com.czxy.dao;
import com.czxy.bean.Product;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ProductMapper {
List<Product> selectProByBrandId(@Param("brandId") String brandId);
List<Product> selectProductByProductId(@Param("productId") String productId);
}
package com.czxy.dao;
import com.czxy.bean.Brand;
import org.apache.ibatis.annotations.Param;
public interface BrandMapper {
Brand selectBrandByBrandId(Brand brand);
Brand selectBrByBrandId(@Param("brandId") String brandId);
}
创建sqlSessionFactory和获取sqlSession的方式是固定的,sqlSessionFactory只需要创建一次即可,因此使用工具类MyBatisUtils来封装相关操作,简化书写,后续SSM整合之后,这些对象的创建就交给spring容器管理了,不需要我们自己管理了。
package com.czxy.utils;
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.Reader;
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
/**
* 创建本地线程变量,为每一个线程独立管理一个session对象 每一个线程只有且仅有单独且唯一的一个session对象
* 使用ThreadLocal对session进行管理,可以保证线程安全,避免多实例同时调用同一个session对象
*/
private static ThreadLocal<SqlSession> threadlocal = new ThreadLocal<SqlSession>();
// 创建sessionFactory对象,因为整个应用程序只需要一个实例对象,故用静态代码块
static {
try {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 新建session会话,并把session放在线程变量中
*/
private static void newSession() {
// 打开一个session会话
SqlSession session = sqlSessionFactory.openSession();
SqlSession sqlSession = threadlocal.get();
// 将session会话保存在本线程变量中
threadlocal.set(session);
}
/**
* 返回session对象
* @return session
*/
public static SqlSession getSession(){
//优先从线程变量中取session对象
SqlSession session = threadlocal.get();
//如果线程变量中的session为null,
if(session==null){
//新建session会话,并把session放在线程变量中
newSession();
//再次从线程变量中取session对象
session = threadlocal.get();
}
return session;
}
/**
* 关闭session对象,并从线程变量中删除
*/
public static void closeSession(){
//读取出线程变量中session对象
SqlSession session = threadlocal.get();
//如果session对象不为空,关闭sessoin对象,并清空线程变量
if(session!=null){
//关闭资源
session.close();
//从threadlocal中移除session
threadlocal.set(null);
}
}
/**
* 提交并关闭资源
*/
public static void commitAndclose() {
//获取连接
SqlSession openSession = getSession();
//非空判断
if(openSession!=null) {
//提交
openSession.commit();
//关闭资源
openSession.close();
//从threadlocal中移除session
threadlocal.remove();
}
}
}
@Test
public void selectBrandAndProductByBrandId() {
SqlSession session = MyBatisUtils.getSession();
BrandMapper brandMapper = session.getMapper(BrandMapper.class);
Brand b = new Brand();
b.setBrandId("2");
Brand brand = brandMapper.selectBrandByBrandId(b);
System.out.println(brand);
MyBatisUtils.closeSession();
}
@Test
public void selectProductByProductId(){
SqlSession sqlSession = MyBatisUtils.getSession();
ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
List<Product> products = productMapper.selectProductByProductId("p01");
for (Product product : products) {
System.out.println(product);
}
MyBatisUtils.closeSession();
}
mybatis 入门案例