什么是 MyBatis?

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录

教程

MyBatis教程01 MyBatis教程02

增删改注意

增加删除修改需要提交事务

session.commit();//提交事务
session.close();//关闭

依赖

--MyBatis依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>

--mysql依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>

Java配置文件

resources下创建 jdbc.properties 和 mybatis-config.xml

image

jdbc.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/cctv?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
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>
<properties resource="jdbc.properties"/>
<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="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>

解释:

<properties resource="数据库连接的配置文件"/>
<property name="..." value="${对应数据库配置文件的每个变量}"/>

image

sql映射

–sql语句映射路径 这个是mybatis.config.xml的mappers的节点
–resource=“sql语句配置文件的映射路径”

在resources下创建一个文件夹 mapper mapper下创建ProjectMapper.xml

ProjectMapper.xml 这个文件名可以随便取

image

ProjectMapper.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.dao.AutosDao">
<!-- ID:就是接口方法的name resultType:返回到那个类 实体类名 namespace:接口路径-->
<select id="selectautos" resultType="com.entity.Autos">
select * from autos
</select>
</mapper>

ProjectMapper.xml解释

namespace=“接口路径”

image

id=“接口的某个方法 名字一致”

image

resultType=“实体类路径” 已sql语句返回结果为标准

image

><select>sql语句</select>

image

在mybatis.config.xml配置sql映射路径

image

测试

package com.test;
import com.dao.AutosDao;
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.InputStream;
import java.util.List;
/**
* @author 羡羡
*/
public class AutosMain {
public static void main(String[] args) throws IOException {
//mybatis-config.xml路径
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
//dao层
AutosDao audao=session.getMapper(AutosDao.class);
List lis=audao.seallinfo();
System.out.println(lis);
}
}

image

SQL语句有条件查询配置

字段名=#{dao层的传值的变量名}

image

image

实体类别名

mybatis-config.xml

-- 对某个包进行取别名  包下面的类名就是别名
<typeAliases>
<package name="com.entity"/>
</typeAliases>

image

AutosMapper.xml

因为取了别名所有resultType=“实体类的名字”

image

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:

<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。

查询案列

AutosMapper.xml

<!--查询-->
<select id="seallinfo" resultType="com.entity.Autos">
select * from autos
</select>
<!--查询-->
<select id="secolo" resultType="Autos">
select * from autos where ccolor=#{color}
</select>

dao层

public List seallinfo();

public List secolo(String color);

测试

package com.test;
import com.dao.AutosDao;
import com.entity.Autos;
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.InputStream;
import java.util.List;
/**
* @author 羡羡
*/
public class AutosMain {
public static void main(String[] args) throws IOException {
//查询
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
AutosDao audao=session.getMapper(AutosDao.class);
List lis=audao.seallinfo();
System.out.println(lis);
List pinkautos=audao.secolo("粉色");
System.out.println(pinkautos);
}
}

增加案列

AutosMapper.xml

<!--增加-->
<insert id="addautos" parameterType="com.entity.Autos">
insert into autos(cname,cnumber,ccolor) values (#{cname},#{cnumber},#{ccolor})
</insert>

dao层

public int addautos(Autos au);

测试

package com.test;
import com.dao.AutosDao;
import com.entity.Autos;
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.InputStream;
/**
* @author 羡羡
*/
public class AutosAdd {
public static void main(String[] args) throws IOException {
//添加
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
AutosDao audao=session.getMapper(AutosDao.class);
Autos auts=new Autos();
auts.setCname("解放牌101");
auts.setCnumber("湘J09K12");
auts.setCcolor("绿色");
int adsu=audao.addautos(auts);
if(adsu>0){
session.commit();
System.out.println("添加成功!");
}else{
System.out.println("添加失败!");
}
}
}

删除案列

AutosMapper.xml

<!--删除-->
<delete id="deautos" parameterType="int">
delete from autos where id=#{id}
</delete>

---这样也可以
<!--删除-->
<delete id="deautos">
delete from autos where id=#{id}
</delete>

dao层

public int deautos(int id);

测试

package com.test;
import com.dao.AutosDao;
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.InputStream;
/**
* @author 羡羡
*/
public class AutosDele {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
AutosDao audao=session.getMapper(AutosDao.class);

int desu=audao.deautos(2119);
if(desu>0){
session.commit();
System.out.println("删除成功!");
}else{
System.out.println("删除失败!");
}
}
}

更新案列

AutosMapper.xml

<!--更新-->
<update id="autoup" parameterType="com.entity.Autos">
update autos set cname=#{cname},cnumber=#{cnumber},ccolor=#{ccolor} where id=#{id}
</update>

dao层

public int autoup(Autos au);

测试

package com.test;
import com.dao.AutosDao;
import com.entity.Autos;
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.InputStream;
public class AutosUpdate {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
AutosDao audao=session.getMapper(AutosDao.class);
Autos au=new Autos(5,"兰博基尼4","琼E45J78","黑色");
int upsu=audao.autoup(au);
if(upsu>0){
session.commit();
System.out.println("更新成功!");
}else{
System.out.println("更新失败!");
}
}
}

统计总条数

AutoMapper.xml

<!--统计总数!-->
<select id="secount" resultType="int">
select count(*) from autos
</select>

dao

public int secount();

测试

package com.test;
import com.dao.AutosDao;
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.InputStream;
public class AutonCount {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
AutosDao audao=session.getMapper(AutosDao.class);
int count=audao.secount();
System.out.println("总条数:"+count);
}
}

模糊查询

AutosMapper.xml

<!--模糊查询  ${value}   也可以在sql语句中不要加 %  在获取值的时候加-->
<select id="selike" resultType="com.entity.Autos">
select * from autos where cname like '%${value}%'
</select>

dao层

public List selike(String carname);

测试

package com.test;

import com.dao.AutosDao;
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.InputStream;
import java.util.List;

public class AutosLike {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession session=sqlSessionFactory.openSession();
AutosDao audao=session.getMapper(AutosDao.class);

List lis=audao.selike("解放");
System.out.println(lis);
}
}

settings属性

settings配置在mybatis-config.xml里面 在起别名的前面

mybatis-config.xml

<!--设置属性-->
<settings>
<!--开启驼峰命名法 数据库表一般字段名是 表名_字段名 驼峰命名法后 去掉下划线 下划线后面第一个字母大写-->
<!--name就是下面的设置名-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

设置(settings)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。

设置名描述有效值默认值
cacheEnabled全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。true | falsetrue
lazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。true | falsefalse
aggressiveLazyLoading开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods)。true | falsefalse (在 3.4.1 及之前的版本中默认为 true)
multipleResultSetsEnabled是否允许单个语句返回多结果集(需要数据库驱动支持)。true | falsetrue
useColumnLabel使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。true | falsetrue
useGeneratedKeys允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。true | falseFalse
autoMappingBehavior指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。NONE, PARTIAL, FULLPARTIAL
NONE: 不做任何反应一个配置完整的 settings 元素的示例如下:
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" 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="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

HashMap参数

ClassMapper.xml

#{clid} 和 #{tid} 中的 clid 和 tid是HashMap的键 传多个值的时候用HashMap传值

<select id="seinf" parameterType="hashmap" resultType="com.entity.Class">
select * from class where classid>#{clid} or classworkid>#{tid}
</select>

image

dao

public List seinf(HashMap hash);

测试

package com.test;
import com.dao.ClassDao;
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.InputStream;
import java.util.HashMap;
import java.util.List;
public class SeHashMapTest {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
ClassDao cl=session.getMapper(ClassDao.class);
//Map传参数
HashMap ha=new HashMap();
//clid跟ClassMapper.xml中的clid需要相对应
ha.put("clid",3216);
//clid跟ClassMapper.xml中的tid需要相对应
ha.put("tid",2009);
List lis=cl.seinf(ha);
System.out.println(lis);
}
}

结果类型HashMap

两表查询返回HashMap

ClassMapper.xml

<!--返回值为HashMap-->
<select id="rehash" resultType="hashmap">
select * from class as a inner join teach as b on a.classworkid=b.classworkid;
</select>

dao层

public List rehash();

测试

package com.test;
import com.dao.ClassDao;
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.InputStream;
import java.util.HashMap;
import java.util.List;
public class ResultHashMap {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
ClassDao cl=session.getMapper(ClassDao.class);
List<HashMap> lis=cl.rehash();
System.out.println(lis);
for(HashMap mp:lis){
//键就是字段名
int clas= (int) mp.get("classid");
String name= (String) mp.get("tename");
System.out.println(clas+" "+name);
}
}
}

添加得到主键

说明:当一个表有主键自动生成时 一添加就要得到添加的那条数据的主键生成的ID

ClassMapper.xml

<!--得到主键的ID-->
<insert id="inclas" useGeneratedKeys="true" keyProperty="classid" parameterType="com.entity.Class">
insert into class values(null,#{classname},#{classcreate},#{classremark},#{classworkid},#{tecteacherid});
</insert>

解释:

useGenerateKeys=“true” 是开启生成主键 没有这个没有效果
还可以配置全局生成主键在mybatis-config.xml的settings里设置全局开启主键

image

dao层

public int inclas(Class cla);

测试

package com.test;

import com.dao.ClassDao;
import com.entity.Class;
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.InputStream;
import java.util.Date;

/**
* @author 羡羡
*/
public class FindKey {
public static void main(String[] args) throws IOException {

//添加数据时得到注解的ID
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession session=sqlSessionFactory.openSession();

ClassDao cla=session.getMapper(ClassDao.class);

Class cl=new Class("C19017",new Date(),"20级垃圾版",2004,2021);
int csu=cla.inclas(cl);
if(csu>0){
session.commit();
session.close();
System.out.println(cl);
}else{
System.out.println("添加失败!");
}
}
}

image

HashMap参数分页

AutosMapper.xml

<!--分页-->
<select id="findpage" parameterType="hashmap" resultType="com.entity.Autos">
select * from autos limit #{currpage},#{pagecount};
</select>

dao

public List findpage(HashMap hash);

测试

package com.test;
import com.dao.AutosDao;
import com.entity.Autos;
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.InputStream;
import java.util.HashMap;
import java.util.List;
/**
* @author 羡羡
*/
public class AutosFindPage {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
AutosDao au=session.getMapper(AutosDao.class);
HashMap hasp=new HashMap();
hasp.put("currpage",0);//当前页
hasp.put("pagecount",10);//每页数量
List lis=au.findpage(hasp);
System.out.println(lis);
}
}

结果集映射

只有一个时用 association
多个时用 collection

resultMap 元素有很多子元素和一个值得深入探讨的结构。 下面是resultMap 元素的概念视图。

结果映射(resultMap)

  • constructor - 用于在实例化类时,注入结果到构造方法中
    • idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
    • arg - 将被注入到构造方法的一个普通结果
  • id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
  • result – 注入到字段或 JavaBean 属性的普通结果
  • association – 一个复杂类型的关联;许多结果将包装成这种类型
    • 嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用
  • collection – 一个复杂类型的集合
    • 嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用
  • discriminator – 使用结果值来决定使用哪个 resultMap
    • case – 基于某些值的结果映射
      • 嵌套结果映射 – case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射
        属性描述
        id当前命名空间中的一个唯一标识,用于标识一个结果映射。
        type类的完全限定名, 或者一个类型别名(关于内置的类型别名,可以参考上面的表格)。
        autoMapping如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射。 这个属性会覆盖全局的属性 autoMappingBehavior。默认值:未设置(unset)。

最佳实践 最好逐步建立结果映射。单元测试可以在这个过程中起到很大帮助。 如果你尝试一次性创建像上面示例那么巨大的结果映射,不仅容易出错,难度也会直线上升。 所以,从最简单的形态开始,逐步迭代。而且别忘了单元测试! 有时候,框架的行为像是一个黑盒子(无论是否开源)。因此,为了确保实现的行为与你的期望相一致,最好编写单元测试。 并且单元测试在提交 bug 时也能起到很大的作用。

下一部分将详细说明每个元素。

id & result

<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>

这些元素是结果映射的基础。id 和 result 元素都将一个列的值映射到一个简单数据类型(String, int, double, Date 等)的属性或字段。
这两者之间的唯一不同是,id 元素对应的属性会被标记为对象的标识符,在比较对象实例时使用。 这样可以提高整体的性能,尤其是进行缓存和嵌套结果映射(也就是连接映射)的时候。

两个元素都有一些属性:

属性描述
property映射到列结果的字段或属性。如果 JavaBean 有这个名字的属性(property),会先使用该属性。否则 MyBatis 将会寻找给定名称的字段(field)。 无论是哪一种情形,你都可以使用常见的点式分隔形式进行复杂属性导航。 比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。
column数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName) 方法的参数一样。
javaType一个 Java 类的全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。
jdbcTypeJDBC 类型,所支持的 JDBC 类型参见这个表格之后的“支持的 JDBC 类型”。 只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可以为空值的列指定这个类型。
typeHandler我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。 这个属性值是一个类型处理器实现类的全限定名,或者是类型别名。

如果存在名称和类型相同的属性,那么可以省略 javaType 。

剩余的属性和规则和普通的 id 和 result 元素是一样的。

属性描述
column数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName) 方法的参数一样。
javaType一个 Java 类的完全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。
jdbcTypeJDBC 类型,所支持的 JDBC 类型参见这个表格之前的“支持的 JDBC 类型”。 只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可能存在空值的列指定这个类型。
typeHandler我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。 这个属性值是一个类型处理器实现类的完全限定名,或者是类型别名。
select用于加载复杂类型属性的映射语句的 ID,它会从 column 属性中指定的列检索数据,作为参数传递给此 select 语句。具体请参考关联元素。
resultMap结果映射的 ID,可以将嵌套的结果集映射到一个合适的对象树中。 它可以作为使用额外 select 语句的替代方案。它可以将多表连接操作的结果映射成一个单一的 ResultSet。这样的 ResultSet 将会将包含重复或部分数据重复的结果集。为了将结果集正确地映射到嵌套的对象树中,MyBatis 允许你 “串联”结果映射,以便解决嵌套结果集的问题。想了解更多内容,请参考下面的关联元素。
name构造方法形参的名字。从 3.4.3 版本开始,通过指定具体的参数名,你可以以任意顺序写入 arg 元素。参看上面的解释。

多对一

多表连接

列如:多个学生对应一个班级

创建2个实体类 一个是Student.java 一个是Class.java

Class.java

package com.entity;
import java.util.Date;
public class Class {
public int classid;
public String classname;
public Date classcreate;
public String classremark;
public int classworkid;
public int tecteacherid;
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public Date getClasscreate() {
return classcreate;
}
public void setClasscreate(Date classcreate) {
this.classcreate = classcreate;
}
public String getClassremark() {
return classremark;
}
public void setClassremark(String classremark) {
this.classremark = classremark;
}
public int getClassworkid() {
return classworkid;
}
public void setClassworkid(int classworkid) {
this.classworkid = classworkid;
}
public int getTecteacherid() {
return tecteacherid;
}
public void setTecteacherid(int tecteacherid) {
this.tecteacherid = tecteacherid;
}

public Class() {
}
public Class(String classname, Date classcreate, String classremark, int classworkid, int tecteacherid) {
this.classname = classname;
this.classcreate = classcreate;
this.classremark = classremark;
this.classworkid = classworkid;
this.tecteacherid = tecteacherid;
}
public Class(int classid, String classname, Date classcreate, String classremark, int classworkid, int tecteacherid) {
this.classid = classid;
this.classname = classname;
this.classcreate = classcreate;
this.classremark = classremark;
this.classworkid = classworkid;
this.tecteacherid = tecteacherid;
}
@Override
public String toString() {
return "Class{" +
"classid=" + classid +
", classname='" + classname + '\'' +
", classcreate=" + classcreate +
", classremark='" + classremark + '\'' +
", classworkid=" + classworkid +
", tecteacherid=" + tecteacherid +
'}';
}
}

Student.java
里面的字段和数据库里的字段名不同

package com.entity;
/**
* @author 羡羡
*/
public class Student {
/**
* 用户ID
*/
public int id;
/**
* 真实姓名
*/
public String name;
/**
* 性别
*/
public String stex;
/**
* 电话
*/
public String stel;
/**
* 班级实体类
*/
Class ben;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStex() {
return stex;
}
public void setStex(String stex) {
this.stex = stex;
}
public String getStel() {
return stel;
}
public void setStel(String stel) {
this.stel = stel;
}
public Class getBen() {
return ben;
}
public void setBen(Class ben) {
this.ben = ben;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", stex='" + stex + '\'' +
", stel='" + stel + '\'' +
", ben=" + ben +
'}';
}
}

配置

<!--解决字段名与数据库字段名不一致    当字段名不一致时查询不是resulttype 应该改成resultMap-->
<resultMap id="stud" type="com.entity.Student">
<!--id字段为主键 只有主键为ID column="数据库字段名"-->
<id property="id" column="ID"></id>
<!--result property="实体类的字段名" column="对应数据库的字段名"-->
<result property="name" column="usname"></result>
<result property="stex" column="sex"></result>
<result property="stel" column="tel"></result>
<!--property="在实体类中定义的名称" javaType="实体类路径"-->
<association property="ben" javaType="com.entity.Class">
<id property="classid" column="classid"/>
<result property="classname" column="classname"/>
<result property="classcreate" column="classcreate"/>
<result property="classremark" column="classremark"/>
<result property="classworkid" column="classworkid"/>
<result property="tecteacherid" column="tecteacherid"/>
</association>
</resultMap>
<select id="getsStudentinfo" resultMap="stud">
select * from student as a inner join class as b on a.classid=b.classid where ID=#{stid}
</select>

字段解释

<select resultMap="上面定义的resultMap的ID"></select

image

<resultMap id="随便起" type="实体类路径">
//主键用ID 其他用result
<id property="实体类主键字段名" colum="数据库字段名"></id>
<result property="实体类字段名"></result>
<result property="实体类字段名"></result>
<result property="实体类字段名"></result>

<association property="在上一节点的type属性的实体类中的名字" javaType="那实体类的属性字段">
//主键用ID 其他用result
<id property="实体类主键字段名" colum="数据库字段名"></id>
<result property="实体类字段名"></result>
<result property="实体类字段名"></result>
<result property="实体类字段名"></result>
</association>
</resultMap>

image

测试

package com.test;
import com.dao.StudentDao;
import com.entity.Student;
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.InputStream;
/**
* @author 羡羡
*/
public class TwoTableQueryStudent {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
StudentDao stud=session.getMapper(StudentDao.class);
Student st=stud.getsStudentinfo(3012);
System.out.println(st);
}
}

一对多

比如:一个班级有多个学生 查询班级

Class02.java

package com.entity;
import java.util.Date;
import java.util.List;
/**
* @author 羡羡
*/
public class Class02 {
public int classid;
public String classname;
public Date classcreate;
public String classremark;
public int classworkid;
public int tecteacherid;
public List<Student02> stud;
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public Date getClasscreate() {
return classcreate;
}
public void setClasscreate(Date classcreate) {
this.classcreate = classcreate;
}
public String getClassremark() {
return classremark;
}
public void setClassremark(String classremark) {
this.classremark = classremark;
}
public int getClassworkid() {
return classworkid;
}
public void setClassworkid(int classworkid) {
this.classworkid = classworkid;
}
public int getTecteacherid() {
return tecteacherid;
}
public void setTecteacherid(int tecteacherid) {
this.tecteacherid = tecteacherid;
}
public List getStud() {
return stud;
}
public void setStud(List stud) {
this.stud = stud;
}
@Override
public String toString() {
return "Class02{" +
"classid=" + classid +
", classname='" + classname + '\'' +
", classcreate=" + classcreate +
", classremark='" + classremark + '\'' +
", classworkid=" + classworkid +
", tecteacherid=" + tecteacherid +
", stud=" + stud +
'}';
}
}

Student02.java

package com.entity;
public class Student02 {
/**
* 用户ID
*/
public int id;
/**
* 真实姓名
*/
public String name;
/**
* 性别
*/
public String stex;
/**
* 电话
*/
public String stel;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStex() {
return stex;
}
public void setStex(String stex) {
this.stex = stex;
}
public String getStel() {
return stel;
}
public void setStel(String stel) {
this.stel = stel;
}
@Override
public String toString() {
return "Student02{" +
"id=" + id +
", name='" + name + '\'' +
", stex='" + stex + '\'' +
", stel='" + stel + '\'' +
'}';
}
}

配置

<resultMap id="mycalss" type="com.entity.Class02">
<id property="classid" column="classid"/>
<result property="classname" column="classname"/>
<result property="classcreate" column="classcreate"/>
<result property="classremark" column="classremark"/>
<result property="classworkid" column="classworkid"/>
<result property="tecteacherid" column="tecteacherid"/>
<collection property="stud" ofType="com.entity.Student02">
<id property="id" column="ID"></id>
<!--result property="实体类的字段名" column="对应数据库的字段名"-->
<result property="name" column="usname"></result>
<result property="stex" column="sex"></result>
<result property="stel" column="tel"></result>
</collection>
</resultMap>
<select id="getclass02" resultMap="mycalss">
select * from student as a inner join class as b on a.classid=b.classid where a.classid=#{classid}
</select>

字段解释

<!---
<collection property="在上一实体类中的变量字段" ofType="实体类">
其他主键用ID
其他用result
........
</collection>
--->
<collection property="stud" ofType="com.entity.Student02">
<id property="id" column="ID"></id>
<!--result property="实体类的字段名" column="对应数据库的字段名"-->
<result property="name" column="usname"></result>
<result property="stex" column="sex"></result>
<result property="stel" column="tel"></result>
</collection>

image

测试

package com.test;

import com.dao.StudentDao;
import com.entity.Class02;
import com.entity.Student02;
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.InputStream;
import java.util.List;

/**
* @author 羡羡
*/
public class OneToManyClass {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession session=sqlSessionFactory.openSession();
StudentDao stud=session.getMapper(StudentDao.class);
Class02 clas3=stud.getclass02(3209);
System.out.println(clas3);
}
}

嵌套结果集

例:类似博客 一个用户有一个博客 一个博客下面有多篇文章 文章下面有多个评论

实体大概过程:

用户实体{
用户的各种属性
}

博客实体{
博客的各种属性
用户实体
文章实体
}

文章实体{
文章属性
评论实体
}

评论实体{
评论的各种属性
}

用户实体

package com.entity;
public class User {
public int userid;
public String name;
public String pass;
public String imgurl;

public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getImgurl() {
return imgurl;
}
public void setImgurl(String imgurl) {
this.imgurl = imgurl;
}
@Override
public String toString() {
return "User{" +
"userid=" + userid +
", name='" + name + '\'' +
", pass='" + pass + '\'' +
", imgurl='" + imgurl + '\'' +
'}';
}
}

博客实体

package com.entity;
import java.util.Date;
import java.util.List;
/**
* @author 羡羡
*/
public class Blog {
public int wbid;
public int yhid;
public String wbtitle;
public Date wbcreate;
//用户
User use;
//list文章
List<Article> artl;
public int getWbid() {
return wbid;
}
public void setWbid(int wbid) {
this.wbid = wbid;
}
public int getYhid() {
return yhid;
}
public void setYhid(int yhid) {
this.yhid = yhid;
}
public String getWbtitle() {
return wbtitle;
}
public void setWbtitle(String wbtitle) {
this.wbtitle = wbtitle;
}
public Date getWbcreate() {
return wbcreate;
}
public void setWbcreate(Date wbcreate) {
this.wbcreate = wbcreate;
}
public User getUse() {
return use;
}
public void setUse(User use) {
this.use = use;
}
public List<Article> getArtl() {
return artl;
}
public void setArtl(List<Article> artl) {
this.artl = artl;
}
@Override
public String toString() {
return "Blog{" +
"wbid=" + wbid +
", yhid=" + yhid +
", wbtitle='" + wbtitle + '\'' +
", wbcreate=" + wbcreate +
", use=" + use +
", artl=" + artl +
'}';
}
}

文章实体

package com.entity;
import java.util.List;
public class Article {
public int wzid;
public String wztitle;
public String wzcontext;
public int wbid;
List<Comments> coms;
public int getWzid() {
return wzid;
}
public void setWzid(int wzid) {
this.wzid = wzid;
}
public String getWztitle() {
return wztitle;
}
public void setWztitle(String wztitle) {
this.wztitle = wztitle;
}
public String getWzcontext() {
return wzcontext;
}
public void setWzcontext(String wzcontext) {
this.wzcontext = wzcontext;
}
public int getWbid() {
return wbid;
}
public void setWbid(int wbid) {
this.wbid = wbid;
}
public List<Comments> getComs() {
return coms;
}
public void setComs(List<Comments> coms) {
this.coms = coms;
}
@Override
public String toString() {
return "Article{" +
"wzid=" + wzid +
", wztitle='" + wztitle + '\'' +
", wzcontext='" + wzcontext + '\'' +
", wbid=" + wbid +
", coms=" + coms +
'}';
}
}

评论实体

package com.entity;
import java.util.Date;
public class Comments {
public int plid;
public int wzid;
public String plnr;
public Date pltime;
public int userid;
public int getPlid() {
return plid;
}
public void setPlid(int plid) {
this.plid = plid;
}
public int getWzid() {
return wzid;
}
public void setWzid(int wzid) {
this.wzid = wzid;
}
public String getPlnr() {
return plnr;
}
public void setPlnr(String plnr) {
this.plnr = plnr;
}
public Date getPltime() {
return pltime;
}
public void setPltime(Date pltime) {
this.pltime = pltime;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
@Override
public String toString() {
return "Comments{" +
"plid=" + plid +
", wzid=" + wzid +
", plnr='" + plnr + '\'' +
", pltime=" + pltime +
", userid=" + userid +
'}';
}
}

dao层

package com.dao;
import com.entity.Blog;
/**
* @author 羡羡
*/
public interface BlogDao {
public Blog seblinfo(int userid);
}

配置

<?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.dao.BlogDao">
<resultMap id="bloginf" type="com.entity.Blog">
<id property="wbid" column="wbid"></id>
<result property="yhid" column="yhid"></result>
<result property="wbtitle" column="wbtitle"></result>
<result property="wbcreate" column="wbcreate"></result>
<association property="use" javaType="com.entity.User">
<id property="userid" column="userid"/>
<result property="name" column="name"/>
<result property="pass" column="pass"/>
<result property="imgurl" column="imgurl"/>
</association>
<collection property="artl" ofType="com.entity.Article">
<id property="wzid" column="wzid"></id>
<!--result property="实体类的字段名" column="对应数据库的字段名"-->
<result property="wztitle" column="wztitle"></result>
<result property="wzcontext" column="wzcontext"></result>
<result property="wbid" column="wbid"></result>
<collection property="coms" ofType="com.entity.Comments">
<id property="plid" column="plid"></id>
<result property="wzid" column="wzid"></result>
<result property="plnr" column="plnr"></result>
<result property="pltime" column="pltime"></result>
<result property="userid" column="userid"></result>
</collection>
</collection>
</resultMap>
<select id="seblinfo" resultMap="bloginf">
select a.*,b.*,c.*,d.*from wb as a left join user as b on a.yhid=b.userid inner join wz as c on a.wbid=c.wbid right join pl as d on d.wzid=c.wzid where b.userid=#{userid};
</select>
</mapper>

image

测试

package com.test;

import com.dao.BlogDao;
import com.entity.Blog;
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.InputStream;

/**
* @author 羡羡
*/
public class BlogTest {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession session=sqlSessionFactory.openSession();
BlogDao blodao=session.getMapper(BlogDao.class);
Blog bl=blodao.seblinfo(101);
System.out.println(bl);
}
}

动态SQL

mybatis 的动态sql语句是基于OGNL表达式的。可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类:

  1. if 语句 (简单的条件判断)

  2. choose (when,otherwize) ,相当于java 语言中的 switch ,与 jstl 中的choose 很类似.

  3. trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)

  4. where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or ,不必担心多余导致语法错误)

  5. set (主要用于更新时)

  6. foreach (在实现 mybatis in 语句查询时特别有用)

动态where if查询

配置

<!--when if可以多个条件同时满足-->
<select id="finde" resultType="com.entity.Heros">
select * from heros
<where>
<if test="sex != null">
AND sex=#{sex}
</if>
<if test="first != null">
AND first=#{first}
</if>
<if test="name != null">
AND name like #{name}
</if>
</where>
</select>

dao

public List finde(Heros her);

测试

package com.test;
import com.dao.AutosDao;
import com.dao.HerosDao;
import com.entity.Heros;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author 羡羡
*/
public class DynamicSQL01 {
SqlSession session;
HerosDao he;
@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session=sqlSessionFactory.openSession();
he=session.getMapper(HerosDao.class);
}
@After
public void ends(){
session.commit();
session.close();
}
@Test
public void test01(){
//if语句 通过填写的不同值来查询数据
Heros hs=new Heros();
hs.setSex(1);
hs.setFirst("辅助");
/*hs.setName("%女%");*/
List lis=he.finde(hs);
System.out.println(lis);
}
}

choose查询

配置

<!--choose 类似switch 满足一个则不会向下执行 而且只会满足一个条件-->
<select id="finde02" resultType="com.entity.Heros">
select * from heros
<where>
<choose>
<when test="sex != null">
AND sex=#{sex}
</when>
<when test="name != null">
AND name=#{name}
</when>
<otherwise>
AND first=#{first}
</otherwise>
</choose>
</where>
</select>

dao

public List finde02(Heros her);

测试

package com.test;
import com.dao.AutosDao;
import com.dao.HerosDao;
import com.entity.Heros;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author 羡羡
*/
public class DynamicSQL01 {
SqlSession session;
HerosDao he;
@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session=sqlSessionFactory.openSession();
he=session.getMapper(HerosDao.class);
}
@After
public void ends(){
session.commit();
session.close();
}
@Test
public void test02(){
//choose的用法 只会满足一个条件 这个测试只是找性别为女的 而类型辅助的这个则不会查找
Heros hs=new Heros();
hs.setSex(0);
hs.setFirst("辅助");
List lis=he.finde02(hs);
System.out.println(lis);
}
}

set更新数据

配置

<!--set if 添加数据-->
<update id="updateheros">
update heros
<set>
<if test="name!=null">name=#{name},</if>
<if test="sex!=null">sex=#{sex},</if>
<if test="nickname!=null">nickname=#{nickname},</if>
</set>
where id=#{id}
</update>

dao

public int updateheros(Heros hes);

测试

package com.test;
import com.dao.AutosDao;
import com.dao.HerosDao;
import com.entity.Heros;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author 羡羡
*/
public class DynamicSQL01 {
SqlSession session;
HerosDao he;
@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session=sqlSessionFactory.openSession();
he=session.getMapper(HerosDao.class);
}
@After
public void ends(){
session.commit();
session.close();
}

@Test
public void test03(){
//set方法(填哪个值就改哪个值) 更新语句使用 以前更新数据是一整条数据都要进行更新 使用set就是填了哪个字段就更新哪个字段 其他字段不变
Heros hs=new Heros();
hs.setSex(0);
hs.setId(1);
int uin=he.updateheros(hs);
System.out.println(uin);
}
}

foreach(查询 in 条件)

配置

<!--foreach 循环查询in条件 item="元素下标名称" collection="变量数据类型 array || list " separator=","-->
<select id="gether" resultType="com.entity.Heros">
select * from heros where id in
<foreach item="item" collection="array"
open="(" separator="," close=")">
#{item}
</foreach>
</select>

dao

public List gether(int[] ar);

测试

package com.test;
import com.dao.AutosDao;
import com.dao.HerosDao;
import com.entity.Heros;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author 羡羡
*/
public class DynamicSQL01 {
SqlSession session;
HerosDao he;
@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session=sqlSessionFactory.openSession();
he=session.getMapper(HerosDao.class);
}
@After
public void ends(){
session.commit();
session.close();
}
@Test
public void test04(){
//foreach测试 一般用户查询语句的in条件
int []nj={10,56,89,12};
List lis=he.gether(nj);
System.out.println(lis);
}

}

foreach批量添加数据

配置

<!--foreach循环批量添加-->
<insert id="addlis" parameterType="list">
insert into heros(name,nickname,sex,first)values
<foreach collection="list" separator="," item="hero">
(#{hero.name},#{hero.nickname},#{hero.sex},#{hero.first})
</foreach>
</insert>

dao

public int addlis(List<Heros> her);

测试

package com.test;
import com.dao.AutosDao;
import com.dao.HerosDao;
import com.entity.Heros;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author 羡羡
*/
public class DynamicSQL01 {
SqlSession session;
HerosDao he;
@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session=sqlSessionFactory.openSession();
he=session.getMapper(HerosDao.class);
}
@After
public void ends(){
session.commit();
session.close();
}
@Test
public void test05(){
//foreach测试 批量查询
List lis=new ArrayList();
Heros her=new Heros("非","非洲",1,"辅助");
Heros he2=new Heros("非2","非洲2",1,"打野");
Heros he3=new Heros("非3","非洲3",0,"辅助");
Heros he4=new Heros("非3","非洲3",1,"法师");
lis.add(her);
lis.add(he2);
lis.add(he3);
lis.add(he4);
int sug=he.addlis(lis);
System.out.println(sug);
}
}

分页pageHelp

导入分页依赖

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.8</version>
</dependency>

配置分页插件
在mybatis-config.xml中配置

<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

image

配置HerosMapper.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.dao.HerosDao">
<select id="seheall" resultType="com.entity.Heros">
select * from heros
</select>
</mapper>

dao层

package com.dao;
import java.util.List;
public interface HerosDao {
public List seheall();
}

测试

package com.it;
import com.dao.HerosDao;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
public class HerosTest {
SqlSession session;
HerosDao her;

@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session=sqlSessionFactory.openSession();
her=session.getMapper(HerosDao.class);
}
@After
public void ends(){
session.commit();
session.close();
}
@Test
public void sehealltest(){
PageHelper.startPage(1,5);
List seall=her.seheall();
System.out.println(seall);
PageInfo pa=new PageInfo(seall);
pa.setNavigatePages(10);
pa.setNavigateLastPage(10);
System.out.println("总页数:"+pa.getPages());
System.out.println("当前页:"+pa.getPageNum());
int [] panum=pa.getNavigatepageNums();
System.out.println("导航条:"+ Arrays.toString(panum));
System.out.println(pa);
}
}

Struts And MybatisPage

struts框架和mybatis框架 分页

依赖

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>

<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.26</version>
</dependency>

<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.5.20</version>
</dependency>

<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.8</version>
</dependency>

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="jdbc.properties"/>
<!--设置属性-->
<settings>
<!--开启驼峰命名法 数据库表一般字段名是 表名_字段名 驼峰命名法后 去掉下划线 下划线后面第一个字母大写-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="useGeneratedKeys" value="true"/>
</settings>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<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="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/HerosMapper.xml"/>
</mappers>
</configuration>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.devMode" value="true"/>
<package name="lol" extends="struts-default" namespace="/">
<global-allowed-methods>regex:.*</global-allowed-methods>
<action name="her*" class="com.action.HerosAction" method="{1}">
<result>/index.jsp</result>
</action>
</package>
</struts>

jdbc.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/heros?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
username=root
password=root

修改web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>action2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- END SNIPPET: filter -->
<filter-mapping>
<filter-name>action2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

HerosMapper.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.dao.HerosDao">
<select id="seheall" resultType="com.entity.Heros">
select * from heros
</select>
</mapper>

dao层

package com.dao;
import java.util.List;
public interface HerosDao {
public List seheall();
}

entity实体

package com.entity;
public class Heros {
public int id;
public String name;
public String nickname;
public int sex;
public String first;
public String img;
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
@Override
public String toString() {
return "Heros{" +
"id=" + id +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
", sex=" + sex +
", first='" + first + '\'' +
", img='" + img + '\'' +
'}';
}
}

SeeionReturn

方便Action中得到dao层

package com.dao;
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.InputStream;
/**
* @author 羡羡
*/
public class SeeionReturn {
public static SqlSession getsSession() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
return session;
}
}

Action

类名:HerosAction

package com.action;
import com.dao.HerosDao;
import com.dao.SeeionReturn;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.ibatis.session.SqlSession;
import java.io.IOException;
import java.util.List;
/**
* @author 羡羡
*/
public class HerosAction extends ActionSupport {
PageInfo pa;
int page=1;
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public PageInfo getPa() {
return pa;
}
public void setPa(PageInfo pa) {
this.pa = pa;
}
public String show() throws IOException {
SqlSession session=SeeionReturn.getsSession();
HerosDao herdao=session.getMapper(HerosDao.class);
PageHelper.startPage(page,10);
List seall=herdao.seheall();
pa=new PageInfo(seall);
return SUCCESS;
}
}

界面

index.jsp

<%--
Created by IntelliJ IDEA.
User: 羡羡
Date: 2021/9/15
Time: 8:46
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>英雄列表</h1>
<table border='1px' cellspacing='0px' style="width: 800px;height: 600px">
<c:forEach items="${pa.list}" var="he">
<tr>
<td>${he.name}</td>
<td>${he.nickname}</td>
<td>${he.sex}</td>
<td>${he.first}</td>
<td><img src="herosimg/${he.img}"></td>
<td><a href="">编辑</a><a href="herde?id=${he.id}">删除</a></td>
</tr>
</c:forEach>
</table>
<a href="hershow?page=1">首页</a>
<a href="hershow?page=${pa.prePage}">上一页</a>
<c:forEach items="${pa.navigatepageNums}" var="p">
<a href="hershow?page=${p}">${p}</a>
</c:forEach>
<a href="hershow?page=${pa.nextPage}">下一页</a>
<a href="hershow?page=${pa.pages}">尾页</a>
</body>
</html>

image

image

访问:/action的name属性

这个访问就是:/hershow show是该Action下的一个方法

image

image

属性配置mybatis-config.xml 驼峰命名自增别名

<!--设置属性-->
<settings>
<!--开启驼峰命名法 数据库表一般字段名是 表名_字段名 驼峰命名法后 去掉下划线 下划线后面第一个字母大写-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--获取主键自增-->
<setting name="useGeneratedKeys" value="true"/>
<!--使用列别名 替换列名-->
<setting name="useColumnLabel" value="true"/>
</settings>

返回一列

1、基本类型  :resultType=基本类型

2、List类型:   resultType=List中元素的类型

3、Map类型    单条记录:resultType =map

多条记录:resultType =Map中value的类型

列:

dao

/**
* 查询所有的年份
* @return
*/
public List<String> findyear();

xml
<select id="findyear" resultType="java.lang.String">
SELECT date_format(b.createtime, '%Y') as year from article b GROUP BY year ORDER BY year DESC;
</select>