Mybatis第一天 入门
mybatis是什么
MyBatis 是一个支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。
MyBatis 消除了几乎所有的JDBC代码和手工设置参数以及结果集的检索。
MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。 SQL映射方式
学习使用
入门准备
导入相应的jar(可以去mybatis的官网下载)
准备相应的domain(需要和数据库中的表的字段名一一对应)
public class Product {
private Long id;
//商品名称
private String productName;
//品牌
private String brand;
//供应商
private String supplier;
//零售价
private BigDecimal salePrice;
//进价
private BigDecimal costPrice;
//折扣价
private Double cutoff;
//商品分类编号
private Long dir_id;
准备dao层(要有接口和实现)
接口中的相关方法
public interface IProductDAO {
/**
* 添加一个商品
*/
void save(Product p);
/**
* 更新一个商品
*/
void update(Product p);
/**
* 删除一个商品
*/
void delete(Long id);
/**
* 得到一个商品
*/
Product get(Long id);
/**
* 得到所有商品
*/
List<Product> findAll();
}
入门实现
步骤
①获取SqlSessionFactory
1 我们需要准备一个核心的Mybatis-config.xml文件
2 拿到SqlSessionFactory之前需要读取核心的xml配置文件
3 需要构造者(SqlSessionFactoryBuilder)来创建它
②映射文件准备
③通过SqlSessionFactory获取SqlSession执行映射SQL
创建核心配置文件(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.propeties文件-->
<properties resource="jdbc.properties" />
<!-- 环境们 (很多环境的意思)
default:默认使用哪一个环境(必需对应一个环境的id)
-->
<environments default="development">
<!--
一个环境 id:为这个环境取唯一一个id名称
-->
<environment id="development">
<!--
事务管理 type:JDBC(支持事务)/MANAGED(什么都不做)
-->
<transactionManager type="JDBC" />
<!-- 数据源, 连接池 type(POOLED):MyBatis自带的连接池 -->
<dataSource type="POOLED">
<!-- 连接数据库的参数 -->
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql:///mydb" />
<property name="username" value="root" />
<property name="password" value="admin" />
</dataSource>
</environment>
</environments>
<!-- 这个mappers代表的是相应的ORM映射文件 -->
<mappers>
<mapper resource="cn/itsource/domain/ProductMapper.xml" />
</mappers>
</configuration>
创建映射文件(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的主要功能就是写sql
mapper:根
namespace:命令空间 (用来确定唯一) 以前这个是可以不加的,现在必需加
namespace的值,规则的:映射文件XxxMapper.xml所在的包+domain类名+Mapper
-->
<mapper namespace="cn.itsource.mybatis.day1._1_hello.ProductMapper">
<!--
select : 这里面写查询语句
id:用来确定这条sql语句的唯一
以后我们确定唯一,也就是找sql语句 : namespace +.+ id
例: cn.itsource.mybatis.day1._1_hello.ProductMapper.get
parameterType : 传入的参数类型 long:大Long _long:小long (具体的对应请参见文档)
resultType : 结果类型(第一条数据返回的对象类型) 自己的对象一定是全限定类名 **查询必须写,增删改不要**
-->
<select id="get" parameterType="long" resultType="cn.itsource.domain.Product">
select * from product where id = #{id}
</select>
</mapper>
dao实现
@Override
public Product loadById(Long id) {
SqlSession sqlSession = null;
try {
//1 准备配置文件 ok
//2 创建SqlSessionFactory
Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//3 获取sqlSession做操作
sqlSession = sqlSessionFactory.openSession();
//表示调用那句sql(namespace+.+id)-拷贝,传入参数,接收得到返回值
return sqlSession
.selectOne("cn.itsource.mybatis._01_hello.domain.ProductMapper.loadById",id);
}catch (Exception e){
e.printStackTrace();
}finally {
if (sqlSession != null) {
sqlSession.close();
}
}
return null;
}
测试
IProductDao productDao = new ProductDaoImpl();
@Test
public void loadById() {
//obj.sout
System.out.println(productDao.loadById(1L));
}
注意: 其他的相关实现我就不在这里给大家展示出来了,步骤都跟上面的一样!
抽取工具类
有没有发现,在上面的代码中,是有很过重复的代码,所有我们需要抽取一个工具类!
使用细节
添加时拿到返回的主键
有些场景是需要你在添加的时候拿到返回的主键的!
映射文件
<!--
parameterType:需要传入我们的对象
useGeneratedKeys: 是否需要主键
keyColumn:主键所在的列
keyProperty:对象中的属性(代表主键的那个属性)
-->
<insert id="save" parameterType="cn.itsource.domain.Product"
useGeneratedKeys="true"
keyColumn="id"
keyProperty="id"
>
insert into product (productName,dir_id,salePrice,supplier,brand,cutoff,costPrice)
values (#{productName},#{dir_id},#{salePrice},#{supplier},#{brand},#{cutoff},#{costPrice})
</insert>
在mybatis中的别名
<typeAliases>
<!-- 单个配置:练习 -->
<typeAlias type="cn.itsource.mybatis.a_crud.Dept" alias="Dept" />
<!-- 包的配置:项目,添加了包之后,类名就是别名 -->
<package name="cn.itsource.mybatis.a_crud" />
</typeAliases>
*#和KaTeX parse error: Expected 'EOF', got '#' at position 8: 的区别**
*#̲{OGNL表达式*}
MyB…{OGNL表达式} 的区别
MyBatis会把这个表达式的值替换到sql中,作为sql的组成部分; 把获取到值直接拼接SQL
该方式主要用于程序拼接SQL;
如果sql中使用${OGNL},并且参数的类型是(integer,string…)那么OGNL表达式可以写成任意东西;
常用的动态SQL
为啥需要这个动态的SQL
MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。如果你有使用 JDBC 或其他
相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空
格或在列表的最后省略逗号。动态 SQL 可以彻底处理这种痛苦。
批量操作-foreach
<!-- delete from product where id in ( ? , ? ) 批量删除:
collection="list":传入的list,相当于map的key,通过list得到传入的整个集合的值;
index="index" :每次循环的索引
item="id" :每次循环的这个值
open="(" :以什么开始
separator=",":分隔符
close=")":以什么结束
-->
<delete id="deleteBatch" parameterType="java.util.List">
delete from product where id
in
<foreach collection="list" index="index" item="id" open="("
separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 批量插入:
insert into product(productName,salePrice,costPrice,cutoff,supplier,brand,dir_id)
values (?,?,?,?,?,?,?) , (?,?,?,?,?,?,?)
parameterType:传入参数是:java.util.List的类型的;
对传入的list进行foreach循环:取出值填入插入的values中:
collection="list":这个不能修改,表示传入的一个list类似于一个key是list,得到传入的list集合
index="index":每一次遍历的序号
item="item":每次遍历的这个对象别名,可以修改
separator=",":每遍历一次后的分隔符
-->
<insert id="insertBatch" parameterType="java.util.List">
insert into
product(productName,salePrice,costPrice,cutoff,supplier,brand,dir_id)
values
<foreach collection="list" index="index" item="item"
separator=",">
(#{item.productName},#{item.salePrice},#{item.costPrice},#{item.cutoff},#{item.supplier},#{item.brand},#{item.dir_id})
</foreach>
</insert>
高级查询-where if
MyBatis 的强大特性之一便是它的动态 SQL。
动态SQL通常要做的事情是有条件地包含where子句的一部分。
之前的示例中,使用了1=1这种明确为true的条件来解决应该插入where还是插入and|or的问题,而新版本的MyBatis提供了新标签(where)来使用更优雅的方式来解决这个问题
上一篇: Flutter 自定义控件之RenderObject
下一篇: while语句的使用