day72
mybatis
mybatis的实现方式
三种实现方式:
纯xml方式,namespace随便写,id随便写,只要保证整个项目namespace+id唯一即可
xml+接口的方式,namespace必须是接口的全路径,id必须是接口的方法名,结合第一种方式,接口中不允许存在重载的方法
纯注解方式,注册时需要在mybatis的核心配置文件中设置mapper的class,或者mappers下面配置package
xml+接口方式
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings><!--日志实现--><setting name="logImpl" value="STDOUT_LOGGING"/></settings> <environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mi?useSSL=false&characterEncoding=UTF-8"/><property name="username" value="root"/><property name="password" value="Abc@1234"/></dataSource></environment></environments><mappers><mapper resource="com/saas/dao/ProductsMapper.xml"/> <!-- <mapper class="com.saas.dao.IProductDaoAnnotation"/>--> <!-- <package name="com.saas.dao"/>--></mappers> </configuration>在mybatis-config的核心配置文件中,设置mappers节点,里面放mapper节点,mapper标签中使用resource属性加入xml文件路径
package com.saas.pojo; import lombok.Data; @Data public class Product {private int cid ;private String title ;private String subtitle;private String wtype ;private String img ;private String cdesc ;private double oprice ;private double nprice ;private int tid ; }package com.saas.dao; import com.saas.pojo.Product; import java.util.List; public interface IProductDao { List<Product> getAllProducts(); Product getProductById(int i); int updateProduct(Product product); }<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.saas.dao.IProductDao"><select id="getAllProducts" resultType="com.saas.pojo.Product">select * from products</select> <select id="getProductById" resultType="com.saas.pojo.Product">select * from products where cid = #{cid}</select> <update id="updateProduct">update products set title = #{title}, subtitle = #{subtitle}, wtype = #{wtype} , img = #{img} ,cdesc = #{cdesc} , oprice = #{oprice}, nprice = #{nprice}, tid = #{tid} where cid = #{cid}</update> </mapper>这里要特别注意:
namespace必须是接口的全路径
id必须是接口中的每个方法的方法名
由于之前mybatis中不能存在同namespace+id的场景,所以接口中不允许存在重载方法
package com.saas.dao; import com.saas.pojo.Product; import com.saas.util.SessionUtil; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class TestProducts { private SqlSession session = null; @Testpublic void testGetAllProducts() { session = SessionUtil.getSession(); IProductDao iProductDao = session.getMapper(IProductDao.class); List<Product> list = iProductDao.getAllProducts(); for (Product p : list) {System.out.println(p);} SessionUtil.closeSession(session);} @Testpublic void testGetProductById() {session = SessionUtil.getSession();IProductDao iProductDao = session.getMapper(IProductDao.class);Product product = iProductDao.getProductById(1);System.out.println(product);SessionUtil.closeSession(session);} @Testpublic void testUpdateProduct() {session = SessionUtil.getSession();IProductDao iProductDao = session.getMapper(IProductDao.class); Product product = new Product();product.setCid(3);product.setTitle("iphone");product.setOprice(16999);product.setNprice(12999);product.setCdesc("iphone 15");product.setTid(1);product.setSubtitle("iphone15promax");product.setImg("ip15.jpg");product.setWtype("taobao"); int i = iProductDao.updateProduct(product); System.out.println(i > 0); SessionUtil.closeSession(session);} }这里注意,我们需要结束SqlSession对象的getMapper()方法,方法参数设置接口的类对象,来得到接口对象
一旦有了接口对象,则借助该接口对象调用接口中的方法即可完成所有的crud功能
测试完成其crud功能
纯注解方式
按照之前两种方式,最直接的结果是,每个crud方法最终都对应一个正确的SQL语句即可,所以注解方式更“直接”
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings><!--日志实现--><setting name="logImpl" value="STDOUT_LOGGING"/></settings> <environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mi?useSSL=false&characterEncoding=UTF-8"/><property name="username" value="root"/><property name="password" value="Abc@1234"/></dataSource></environment></environments><mappers> <!-- <mapper resource="com/saas/dao/ProductsMapper.xml"/>--><mapper class="com.saas.dao.IProductDaoAnnotation"/> <!-- <package name="com.saas.dao"/>--></mappers> </configuration>在mybatis的核心配置文件中,mappers节点放入mapper子节点,mapper标签中使用class属性来实现主责功能
或者在mappers节点中放入package子节点,里面写name为包名,那就意味着这个包下的所有dao类都可以被一次性注册到mybatis的核心工厂之上
package com.saas.dao; import java.util.List; import com.saas.pojo.Product; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; public interface IProductDaoAnnotation { @Select("select * from products")List<Product> getAllProducts(); // @Select("select * from products limit #{param1}, #{param2}") // @Select("select * from products limit #{arg0}, #{arg1}")@Select("select * from products limit #{si}, #{ps}")List<Product> getProductsByPage(@Param("si") int si, @Param("ps") int ps); @Select("select * from products where cid = #{cid}")Product getProductById(int cid); @Insert("insert into products(title,subtitle,wtype,oprice,tid,img,cdesc,nprice) " +" values(#{title},#{subtitle},#{wtype},#{oprice},#{tid},#{img},#{cdesc},#{nprice})")int saveProduct(Product product); }第三种调用方式与第二种类似
需要借助SqlSession对象的getMapper()方法,将接口的类对象传入后得到接口对象
一旦有了接口对象,则通过接口对象的crud方法完成对应的curd功能
mybatis传参
无参:SQL语句里面不写占位符
一参:SQL语句里面#{}里面写任意合法的标识符
多参:
对象传参
map传参
arg0, arg1, arg2
param1, param2, param3
@Param(“si”), @Param("si")
config配置
properties
<properties resource="db.properties"> </properties>settings
<settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="true"/> <setting name="multipleResultSetsEnabled" value="true"/> <setting name="useColumnLabel" value="true"/> <setting name="useGeneratedKeys" value="false"/> <setting name="autoMappingBehavior" value="PARTIAL"/> <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/> <setting name="defaultExecutorType" value="SIMPLE"/> <setting name="defaultStatementTimeout" value="25"/> <setting name="defaultFetchSize" value="100"/> <setting name="safeRowBoundsEnabled" value="false"/> <setting name="safeResultHandlerEnabled" value="true"/> <setting name="mapUnderscoreToCamelCase" value="false"/> <setting name="localCacheScope" value="SESSION"/> <setting name="jdbcTypeForNull" value="OTHER"/> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/> <setting name="defaultScriptingLanguage" value="org.apache.ibatis.scripting.xmltags.XMLLanguageDriver"/> <setting name="defaultEnumTypeHandler" value="org.apache.ibatis.type.EnumTypeHandler"/> <setting name="callSettersOnNulls" value="false"/> <setting name="returnInstanceForEmptyRow" value="false"/> <setting name="logPrefix" value="exampleLogPreFix_"/> <setting name="logImpl" value="SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING"/> <setting name="proxyFactory" value="CGLIB | JAVASSIST"/> <setting name="vfsImpl" value="org.mybatis.example.YourselfVfsImpl"/> <setting name="useActualParamName" value="true"/> <setting name="configurationFactory" value="org.mybatis.example.ConfigurationFactory"/> </settings>类型别名
<typeAliases><typeAlias type="com.saas.pojo.Product" alias="Product"/><package name="com.saas.pojo"/></typeAliases>环境配置
<environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${user}"/><property name="password" value="${pass}"/></dataSource></environment> </environments>其中datasource的type有三个值:
unpooled:不使用连接池
pooled:使用连接池
jndi:需要额外配置应用服务器
其中transactionManager的type值有两个:
JDBC: jdbc自身的提交或者回滚来实现事务
MANAGED:由容器自动决定事务的提交或者回滚
映射器
<mappers> <!-- <mapper resource="com/saas/dao/ProductsMapper.xml"/>--><mapper class="com.saas.dao.IProductDaoAnnotation"/> <!-- <package name="com.saas.dao"/>--></mappers>映射器的配置分为两大类
mapper子节点
resource,配置xml文件的相对路径
url: 配置xml文件的 绝对路径
class:配置映射的文件类
package子节点:该包下是所有类都会被自动映射
mapper映射
cache
– 该命名空间的缓存配置。
cache-ref
– 引用其它命名空间的缓存配置。
resultMap
– 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
parameterMap
– 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。
sql
– 可被其它语句引用的可重用语句块。
insert
– 映射插入语句。
update
– 映射更新语句。
delete
– 映射删除语句。
select
– 映射查询语句。<sql id="allPro">select * from products</sql><select id="getAllProducts" resultType="abc"><include refid="allPro"/></select><select id="getProductById" resultType="abc"><include refid="allPro"/>where cid = #{cid}</select><select id="getProductsByPage" resultType="abc"><include refid="allPro"/>limit #{si}, #{ps}</select><update id="updateProduct">update products set title = #{title}, subtitle = #{subtitle}, wtype = #{wtype} , img = #{img} ,cdesc = #{cdesc} , oprice = #{oprice}, nprice = #{nprice}, tid = #{tid} where cid = #{cid}</update>