mybatis
使用到的依赖(gradle)
//mybatis依赖
compile group: 'org.mybatis', name: 'mybatis', version: '3.5.6'
// mysql
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.22'
// mybatis分页插件
compile group: 'com.github.pagehelper', name: 'pagehelper', version: '5.2.0'
接口类
{
/**
* 查询所有
*
* @return
*/
List<School> findSchools();
/**
* 条件查询方式1
*
* @param jj
* @return
*/
List<School> findSchool(@Param("age") int jj);
/**
* 条件查询方式2
* 对象传参
* 返回其他类型
*
* @param s
* @return
*/
int findSchoolBySchool(School s);
/**
* 使用占位符的方式
*
* @param name
* @return
*/
List<School> findSchoolByPlaceholder(String name);
/**
* 使用map传参
*
* @param map
* @return
*/
List<School> findSchoolByMap(Map<String, Object> map);
/**
* 返回一个map类型
*
* @param name
* @return
*/
List<Map<Object, Object>> findSchoolReturnMap(@Param("name") String name);
/**
* 解决返回值名称 和类的属性名不匹配问题
*
* @param name
* @return
*/
List<School> findSchoolResolveNameMismatch(@Param("name") String name);
/**
* 插入数据
*
* @param school
* @return
*/
int insertOne(School school);
/**
* 模糊查询
* 方式1: 使用java拼接
*
* @param s
* @return
*/
List<School> findSchoolByLike1(@Param("name") String s);
/**
* 模糊查询
* 方式2:在mapper.xml中配置拼接
*
* @param s
* @return
*/
List<School> findSchoolByLike2(@Param("name") String s);
/**
* if标签的使用
*
* @param map
* @return
*/
List<School> findSchoolToIf(Map<String, Object> map);
/**
* where标签的使用
*
* @param map
* @return
*/
List<School> findSchoolToWhere(Map<String, Object> map);
/**
* foreach标签的使用
*
* @param list
* @return
*/
List<School> findSchoolToForeach(List<Integer> list);
}
配置文件
mpaaer.xml
每一个DAO类对应一个Mapper.xml(每一个表的查询方法对应一个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="Mybatis.Dao.SchoolDAO">
<!-- 代码片段 高复用的sql语句可以使用-->
<sql id="school">
select * from school
</sql>
<!-- 查询全部-->
<select id="findSchools" resultType="Mybatis.bean.School">
select * from school
</select>
<!-- 设置参数形式 参数名为@param(value="")中value的值-->
<!-- 使用到了代码的复用 include标签-->
<select id="findSchool" resultType="Mybatis.bean.School">
<include refid="school"/>
where age=#{age}
</select>
<!-- 对象传参 参数名为对象中的字段 这里要说一下resultType可以是任何java类-->
<select id="findSchoolBySchool" resultType="int">
select count(*) from school where age=#{age}
</select>
<!-- 使用占位符传参 参数名为 arg0 arg1 .... 用到了别名机制-->
<select id="findSchoolByPlaceholder" resultType="School">
select * from school where name=#{arg0}
</select>
<!--使用map传参 参数名为 map中的字段key值 用到了别名机制-->
<select id="findSchoolByMap" resultType="s">
select * from school where name=#{name}
</select>
<!--返回一个map类型-->
<select id="findSchoolReturnMap" resultType="java.util.Map">
select * from school where name=#{name}
</select>
<!-- 解决查询值和类中的值不匹配的问题 -->
<!-- 第一种声明resultMap-->
<!-- 第二种修改sql 让返回字段名和类字段名相同-->
<!--
id是定义的一个resultMap的名称
type:是类的全限定名
-->
<resultMap id="toSchool" type="Mybatis.bean.School">
<!-- 定义列名和属性名的关系 column列名 property对应属性名-->
<id column="n" property="name"/>
<id column="a" property="age"/>
</resultMap>
<!-- 这样的sql就是第二种-->
<select id="findSchoolResolveNameMismatch" resultMap="toSchool">
select name n,age a from school where name=#{name}
</select>
<!--模糊查询方式1-->
<select id="findSchoolByLike1" resultType="s">
select * from school where name like #{name}
</select>
<!-- 模糊查询方式2 % 空格 #{参数} 空格 %-->
<select id="findSchoolByLike2" resultType="s">
select * from school where name like '%' #{name} '%'
</select>
<!-- 动态Sql-->
<!--if 记得写一个恒成立的条件 防止条件都不成立时 sql语句报错-->
<select id="findSchoolToIf" resultType="s">
select * from school where 1=1
<if test="name!=null and name!=''">
and name=#{name}
</if>
<if test="age!=null and age>=0">
and age>#{age}
</if>
</select>
<!-- where 可以防止sql报错 自动拼接where条件 或者不拼接-->
<select id="findSchoolToWhere" resultType="s">
select * from school
<where>
<if test="name!=null and name!=''">
and name=#{name}
</if>
<if test="age!=null and age>=0">
and age>#{age}
</if>
</where>
</select>
<!-- foreach-->
<select id="findSchoolToForeach" resultType="s">
select * from school
<where>
<if test="list!=null">
age in
<foreach collection="list" item="i" close=")" open="(" separator=",">
#{i}
</foreach>
</if>
</where>
</select>
<!-- 插入-->
<insert id="insertOne">
insert into school value(#{name},#{age});
</insert>
</mapper>
mybatis配置文件
<?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>
<!-- 设置db配置文件的位置-->
<properties resource="db.properties"/>
<!-- 设置日志输出-->
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="useGeneratedKeys" value="true"/>
<setting name="defaultExecutorType" value="REUSE"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 别名机制-->
<typeAliases>
<!-- 第一种
type是类的全限定名
alias是类的别名
-->
<typeAlias type="Mybatis.bean.School" alias="s"/>
<!--
第二种
配置类的所在包
类的别名:是类的名字不分大小写
问题:
如果配置多个包,多个包下存在同名的类,会报错
-->
<package name="Mybatis.bean"/>
</typeAliases>
<!-- 插件配置-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
<!-- 环境配置 数据库连接信息 default表示默认数据库配置 -->
<environments default="development">
<!-- 数据库配置 id 为该配置的名称 自义定-->
<environment id="development">
<!-- 处理事务的类型
1.JDBC:底层使用的是JDBC方式 调用connection 的rollback 和commit
2.MANAGED:把 事务托管给一个容器 比如 spring
-->
<transactionManager type="JDBC"/>
<!-- 数据源 type连接方式
所有实现了 javax.sql.DataSource的数据源
1.POOLED:使用连接池,mybatis会创建一个PooledDataSource类
2.UPOOLED:不使用连接池,在每次执行sql时,先创建连接,执行sql,关闭连接
mybatis会创建一个UnPooledDataSource
3.JNDI:(知道就行) java命名和目录服务(windows注册表)
-->
<dataSource type="POOLED">
<!--读取配置文件中的信息 ${配置文件中的字段名}-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="a"/>
</dataSource>
</environment>
</environments>
<!-- 设置mapper所在位置-->
<mappers>
<!-- 第一种方式-->
<mapper resource="Mapper/SchoolDAO.xml"/>
<!-- 第二种方式
配置xml所在的包的全限定名
要求:
1.接口和mapper.xml文件同名
2.接口和mapper.xml在同一文件夹下
-->
<!-- <package name="Mapper"/>-->
</mappers>
</configuration>
创建方法(普通)
String config="mybatis.xml";
//读取这个config表示的文件
InputStream in= Resources.getResourceAsStream(config);
//创建SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//通过 builder 创建SqlSessionFactory
SqlSessionFactory factory=builder.build(in);
//创建sqlSession
SqlSession sqlSession=factory.openSession();
//设置查询语句 mapper文件中的命名空间 +. +语句id
String sqlId="xmlSpring.Dao.SchoolDAO.findSchools";
//查询
List<School> objects = sqlSession.selectList(sqlId);
sqlSession.close();
objects.forEach(System.out::println);
//读取这个config表示的文件
InputStream in= Resources.getResourceAsStream(config);
//创建SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//通过 builder 创建SqlSessionFactory
SqlSessionFactory factory=builder.build(in);
//创建sqlSession
SqlSession sqlSession=factory.openSession();
/**
* mybatis动态代理
* 要求
* mapper中的namespace是接口限定名
* SQL语句的id为方法名
*/
SchoolDAO dao=sqlSession.getMapper(SchoolDAO.class);
//查询
List<School> objects = dao.findSchools();
objects.forEach(System.out::println);
System.out.println("-=======================================");
//条件查询 使用了@param()注解 作用设置对应参数名 赋值给sql语句 建议使用
List<School> school = dao.findSchool(1);
school.forEach(System.out::println);
System.out.println("-=======================================");
//使用对象查找
int schoolBySchool = dao.findSchoolBySchool(s);
System.out.println(schoolBySchool);
System.out.println("-=======================================");
//还可以使用占位符
List<School> schoolByPlaceholder = dao.findSchoolByPlaceholder("2020-11-15");
schoolByPlaceholder.forEach(System.out::println);
System.out.println("-=======================================");
//使用map传参
Map<String, Object> map = new HashMap<>();
map.put("name", "2020-11-15");
List<School> schoolByMap = dao.findSchoolByMap(map);
schoolByPlaceholder.forEach(System.out::println);
System.out.println("-=======================================");
//返回map
List<Map<Object, Object>> schooReturnMap = dao.findSchoolReturnMap("2020-11-15");
schooReturnMap.forEach(System.out::println);
System.out.println("-=======================================");
//解决返回值名称 和类的属性名不匹配问题
List<School> SchoolResolveNameMismatch = dao.findSchoolResolveNameMismatch("2020-11-15");
schooReturnMap.forEach(System.out::println);
System.out.println("-=======================================");
//模糊查询
//方式1 在java中拼接模糊条件
List<School> SchoolByLike1 = dao.findSchoolByLike1("马%");
SchoolByLike1.forEach(System.out::println);
System.out.println("-=======================================");
//方式2 在mapper中拼接模糊条件
List<School> SchoolByLike2 = dao.findSchoolByLike2("马");
SchoolByLike2.forEach(System.out::println);
System.out.println("-=======================================");
/*
动态sql
*/
// if
Map<String, Object> map1 = new HashMap<>();
map1.put("name", "2020-11-15");
map1.put("age", 2);
List<School> schoolToIf = dao.findSchoolToIf(map1);
schoolToIf.forEach(System.out::println);
System.out.println("-=======================================");
//where
Map<String, Object> map2 = new HashMap<>();
map2.put("name", "2020-11-15");
List<School> schoolToWhere = dao.findSchoolToWhere(map2);
schoolToWhere.forEach(System.out::println);
System.out.println("-=======================================");
//foreach
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<School> schoolToForeach = dao.findSchoolToForeach(list);
schoolToForeach.forEach(System.out::println);
System.out.println("-=======================================");
//pageHelper分页插件测试
PageHelper.startPage(2,3);
List<School> schools = dao.findSchools();
schools.forEach(System.out::println);
System.out.println("-=======================================");
//插入使用对象插入
int i = dao.insertOne(s);
System.out.println("对象插入结果:" + i);
#和$的区别
- #使用 ? 在sql语句中是占位符 , 底层使用的是 preparedStatement 执行sql 效率高
- #能有效避免sql注入风险
- $不使用占位符 是字符串连接的方式 使用的是Statement 执行sql 效率低
- $有sql注入的风险
- $可以替换表名或者列名
pageHelper使用
- 静态方法,传递两个参数(当前页码,每页查询条数)
- 使用pageHelper 分页的时候,不再关注分页语句,查询全部的语句
- 自动的对PageHelper.startPage 方法下的第一个sql 查询进行分页
PageHelper.startPage(1,5);
//紧跟着的第一个select 方法会被分页
List list = countryMapper.findAll();
也就是说再Service层PageHelper.startPage(1,5);语句后一定是紧跟查询语句。
Service层示例代码
public PageInfo findPage(int page,int pageSize){
PageHelper.startPage(page,pageSize);
List<Company> List=companyDao.selectAll();
PageInfo pageInfo = new PageInfo(list);
return pageInfo;
}
返回的信息就是pageInfo对象,该类是插件里的类,这个类里面的属性还是值得看一看
public class PageInfo<T> implements Serializable {
private static final long serialVersionUID = 1L;
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//由于startRow 和endRow 不常用,这里说个具体的用法
//可以在页面中"显示startRow 到endRow 共size 条数据"
//当前页面第一个元素在数据库中的行号
private int startRow;
//当前页面最后一个元素在数据库中的行号
private int endRow;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List<T> list;
//前一页
private int prePage;
//下一页
private int nextPage;
//是否为第一页
private boolean isFirstPage = false;
//是否为最后一页
private boolean isLastPage = false;
//是否有前一页
private boolean hasPreviousPage = false;
//是否有下一页
private boolean hasNextPage = false;
//导航页码数
private int navigatePages;
传智播客——专注于Java、.Net 和Php、网页平面设计工程师的培训
北京市昌平区建材城西路金燕龙办公楼一层电话:400-618-9090
//所有导航页号
private int[] navigatepageNums;
//导航条上的第一页
private int navigateFirstPage;
//导航条上的最后一页
private int navigateLastPage;
}
设置(settings)
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
设置名 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 | true | false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 |
true | false | false |
aggressiveLazyLoading | 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods )。 |
true | false | false (在 3.4.1 及之前的版本中默认为 true) |
multipleResultSetsEnabled | 是否允许单个语句返回多结果集(需要数据库驱动支持)。 | true | false | true |
useColumnLabel | 使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。 | true | false | true |
useGeneratedKeys | 允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。 | true | false | False |
autoMappingBehavior | 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。 | NONE, PARTIAL, FULL | PARTIAL |
autoMappingUnknownColumnBehavior | 指定发现自动映射目标未知列(或未知属性类型)的行为。NONE : 不做任何反应WARNING : 输出警告日志('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN )FAILING : 映射失败 (抛出 SqlSessionException ) |
NONE, WARNING, FAILING | NONE |
defaultExecutorType | 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |