## Mybatis入门教程 Mybatis是一个半自动化的ORM框架,是一个优秀的DAO层解决方案。 官网API文档地址:https://mybatis.net.cn/index.html ### 一、 使用MyBatis的开发步骤 #### 1.导入mybatis依赖 通过这个maven仓库去找依赖,https://mvnrepository.com/ 三个依赖:mysql、mybatis、junit ~~~xml <dependencies> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.29</version> </dependency> <!-- junit测试包 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> ~~~ #### 2.编写MyBatis核心配置文件 mybatis-config.xml,官网提供的名字。 在资源文件resources目录下,创建mybatis-config.xml,写入配置信息 ```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"> <!--mybatis的核心配置文件--> <configuration> <typeAliases> <!--<typeAlias type="cn.hxzy.pojo.User" alias="User"/>--> <package name="cn.hxzy.pojo"/> </typeAliases> <!--environments 数据库环境 1、开发环境 2、测试环境 3、生产环境--> <environments default="dev"> <environment id="dev"> <!--事务管理 采用JDBC的事务管理机制--> <transactionManager type="JDBC" /> <!--数据源配置信息--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/news_db"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!--映射器--> <mappers> <mapper resource="mapper/UserMapper.xml"></mapper> </mappers> </configuration> ``` #### 3.创建实体类-POJO、创建Dao层,编写接口文件 实体类 ~~~java package cn.hxzy.pojo; public class User { private Integer userId; private String userName; private String userPwd; private Integer userGender; public User() { } public User(Integer userId, String userName, String userPwd, Integer userGender) { this.userId = userId; this.userName = userName; this.userPwd = userPwd; this.userGender = userGender; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } public Integer getUserGender() { return userGender; } public void setUserGender(Integer userGender) { this.userGender = userGender; } } ~~~ 定义接口文件的后缀名为Mapper,UserMapper.java。 ~~~java package cn.hxzy.dao; import cn.hxzy.pojo.User; import java.util.List; /** * 用户的Mapper接口文件 */ public interface UserMapper { /** * 查询全部用户信息 * @return 用户集合 */ List<User> getUserList(); } ~~~ #### 4.编写-SQL映射文件 在resources资源目录下,创建一个专门用于mapper文件的管理目录,在mapper文件夹下,创建与接口文件保持一致的SQL映射文件 UserMapper.xml ~~~xml <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace--> <mapper namespace="cn.hxzy.dao.UserMapper"> <select id="getUserList" resultType="cn.hxzy.pojo.User"> select * from user </select> </mapper> ~~~ maven的强大体现在有个特性叫做依赖传递。 #### 5.代码测试 ~~~java @Test public void getGradeById() throws IOException { //核心配置文件的路径 String resource = "mybatis-config.xml"; //读取为字节输入流对象 InputStream is = Resources.getResourceAsStream(resource); //通过SqlSessionFactoryBuilder来构建SqlSessionFactory对象,依赖字节输入流【数据库的连接信息】 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //创建SQL的会话对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //根据指定类,通过反射得到接口的实例对象 GradeMapper gradeMapper = sqlSession.getMapper(GradeMapper.class); //调用实例对象的查询方法 Grade grade = gradeMapper.getGradeById(1); System.out.println(grade.toString()); } ~~~ ### 二、 使用lombok的步骤 #### 1.安装lombok插件 在File中找到Settings找到Pplugins,搜索Lombok,进行安装。 #### 2.下载依赖 找到maven仓库,下载依赖,添加到pom.xml文件中 ~~~xml <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> <scope>provided</scope> </dependency> ~~~ #### 3.打开实体类,加入注解 ~~~java @Data //get set @AllArgsConstructor //有参构造方法 @NoArgsConstructor //无参构造方法 @ToString //重写toString方法 ~~~ #### 4.提取MybatisUtils工具类 为了减少代码量,提高系统性能,把公共的操作封装在一起,方便代码的管理。 ~~~java public class MybatisUtils { static SqlSessionFactory sqlSessionFactory=null; static SqlSession sqlSession=null; static { String resource="mybatis-config.xml"; InputStream is = null; try { is = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); } catch (IOException e) { e.printStackTrace(); } } //执行增删改查操作的时候得到一个SqlSession对象 public static SqlSession openSqlSession(){ sqlSession = sqlSessionFactory.openSession(true); return sqlSession; } //SqlSession关闭 public static void closeSqlSessoin(){ sqlSession.close(); } } ~~~ ### 三、参数入参 - 1、适用于单个参数的情况,默认按照类型入参,默认可以不写parameterType。 - 2、多个参数入参 这种情况需要添加@Param注解,进行参数名称的标注。xml文件节点上不可以添加parameterType。 - 3、可以封装为一个实体对象进行入参 对象加上@Param注解后,sql语句传入参数的表示方式为:#{student.studentId} 如果对象不加@Param注解,sql语句传入参数的表示方式为:#{studentId} - 4、涉及到复杂数据类型传参的时候可以使用Map入参,可以加@Param("map")注解,如果添加上去后,sql语句就必须为#{map.studentId},如果没有添加 则可以直接使用map的键的名称入参 #{ }入参与${ }入参的区别: 1、#{ } 占位符,预编译的sql语句 2、${ },变量直接拼接到sql语句中,入参方式不安全。很容易被sql注入(利用sql语句,对系统进行攻击,破坏) ~~~sql SELECT COUNT(1) FROM userinfo WHERE user_name='aa' OR 1='1' AND user_pwd='bb' OR 1='1' 账号 aa' OR 1='1 密码 bb' OR 1='1 ~~~ 3、${ } 可以进行算术运算,#{ }不可以进行算术运算 ### 四、事务提交 执行增删改操作的时候,默认的自动提交是关闭的,需要进行手动提交。 方式一: ~~~java sqlSession.commit(); ~~~ 方式二: ```java public static SqlSession creatSqlSession() { return factory.openSession(true); } ``` ### 五、resultType与resultMap 返回类型别名设置: ~~~xml <typeAliases> <typeAlias alias="Grade" type="cn.hxzy.myschool"/> <typeAlias alias="Blog" type="domain.blog.Blog"/> </typeAliases> ~~~ 或者 ~~~xml <typeAliases> <package name="cn.hxzy.myschool.entity"/> </typeAliases> ~~~ 每一个在包 `domain.blog` 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 `domain.blog.Author` 的别名为 `author`;若有注解,则别名为其注解值。 resultMap:返回SQL语句映射的一个Map类型的结果集 数据库的经典命名法: Orcal与Mysql Orcal中一般字段名全部大写,如果遇到两个单词的情况,中间用下划线隔开。 mysql中一般字段名小写,如果遇到两个单词的情况,中间用下划线隔开。 resultType与resultMap不能同时存在于同一个语句块上。 ### 六、高级结果映射 #### 1. 映射方式 在实际生产环境中,对于这种多表联查,映射结果有以下几种处理办法。 6.1.做一个基于业务模块的DTO实体类,一般会把所用到的业务字段合为一个实体类进行操作 ~~~java package cn.hxzy.dto; import java.sql.Date; public class NewsDto { private Integer newsId; private Integer newsTypeId; private String newsTitle; private String newsInfo; private String newsFrom; private String newsContent; private Date createTime; private String newsimg; private String newsTypeTitle; } ~~~ 6.2.在实体类上修改字段 根据关系型数据表中,数据记录的关系,进行实体类属性的定义 #### 2. 一对一的映射 实体类 ~~~java package cn.hxzy.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.sql.Date; /* 资讯实体类 */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class News { private Integer newsId; private NewsType newsType; //把此属性改为对象 private String newsTitle; private String newsInfo; private String newsFrom; private String newsContent; private Date createTime; private String newsimg; } ~~~ Mapper.xml ~~~xml <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace 命名空间..接口的包路径--> <mapper namespace="cn.hxzy.dao.NewsMapper"> <!--对多表联查,自定义结果集--> <resultMap id="newsList" type="News"> <id property="newsId" column="newsId" /> <result property="newsTitle" column="newsTitle" /> <result property="newsInfo" column="newsInfo" /> <result property="newsFrom" column="newsFrom" /> <result property="newsContent" column="newsContent" /> <result property="createTime" column="createTime" /> <result property="newsimg" column="newsimg" /> <!-- 指代的就是一个对象--> <association property="newsType" javaType="NewsType"> <id property="newsTypeId" column="newsTypeId" /> <result property="newsTypeTitle" column="newsTypeTitle"/> </association> </resultMap> <select id="selectAll" resultMap="newsList" > SELECT * FROM news t1 LEFT OUTER JOIN newstype t2 ON t1.`newsTypeId`=t2.`newsTypeId` </select> </mapper> ~~~ 接口 ~~~java package cn.hxzy.dao; import cn.hxzy.pojo.News; import java.util.List; public interface NewsMapper { //查询全部的资讯信息 List<News> selectAll(); } ~~~ 测试 ~~~java package cn.hxzy.dao; import cn.hxzy.pojo.News; import cn.hxzy.pojo.User; import cn.hxzy.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class NewsMapperTest { @Test public void selectAll() throws Exception{ SqlSession sqlSession = MybatisUtils.creatSqlSession(); //对象 NewsMapper newsMapper = sqlSession.getMapper(NewsMapper.class); List<News> newsList = newsMapper.selectAll(); for (News news:newsList) { System.out.println(news.getNewsId()+"==="+news.getNewsTitle()+"==="+news.getNewsType().getNewsTypeTitle()); } sqlSession.close(); } } ~~~ #### 3. 一对多的映射 实体类 ~~~java package cn.hxzy.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.List; /* 资讯类别表 */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class NewsType { private Integer newsTypeId; private String newsTypeTitle; /** * 一对多 */ private List<News> newsList; //资讯集合 } ~~~ Mapper.xml ~~~xml <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace 命名空间..接口的包路径--> <mapper namespace="cn.hxzy.dao.NewsTypeMapper"> <resultMap id="userList" type="NewsType"> <id property="newsTypeId" column="newsTypeId"></id> <result property="newsTypeTitle" column="newsTypeTitle"></result> <!--collection表示的是集合属性 private List<News> newsList --> <collection property="newsList" ofType="News"> <id property="newsId" column="newsId" /> <result property="newsTitle" column="newsTitle" /> <result property="newsInfo" column="newsInfo" /> <result property="newsFrom" column="newsFrom" /> <result property="newsContent" column="newsContent" /> <result property="createTime" column="createTime" /> <result property="newsimg" column="newsimg" /> </collection> </resultMap> <select id="getNewsByType" resultMap="userList"> SELECT * FROM newsType t1 LEFT JOIN news t2 ON t1.newsTypeId=t2.newsTypeId </select> </mapper> ~~~ 接口 ~~~java package cn.hxzy.dao; import cn.hxzy.pojo.News; import cn.hxzy.pojo.NewsType; import java.util.List; public interface NewsTypeMapper { //根据资讯类别去查询所属的资讯信息 List<NewsType> getNewsByType(); } ~~~ 测试 ~~~java package cn.hxzy.dao; import cn.hxzy.pojo.News; import cn.hxzy.pojo.NewsType; import cn.hxzy.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class NewsTypeMapperTest { @Test public void getNewsByType() { SqlSession sqlSession = MybatisUtils.creatSqlSession(); //对象 NewsTypeMapper newsTypeMapper = sqlSession.getMapper(NewsTypeMapper.class); List<NewsType> newsTypeList = newsTypeMapper.getNewsByType(); for (NewsType newsType : newsTypeList) { System.out.println(newsType.getNewsTypeId() + "===" + newsType.getNewsTypeTitle()); for (News news : newsType.getNewsList()) { System.out.println(news.getNewsTitle()); } } sqlSession.close(); } } ~~~ ### 七、外部文件配置数据源 编写database.properties文件 ~~~properties jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ticket?serverTimezone=GMT%2B8&useUnicode=true&useSSL=false&characterEncoding=utf8 jdbc.username=root jdbc.password=root ~~~ ~~~properties serverTimezone=Asia/Shanghai" 或 serverTimezone=GMT%2B8 或 serverTimezone=UTC ~~~ 核心配置文件中引入 ~~~xml <!--把数据库的连接信息配置在properties文件之下--> <properties resource="database.properties"/> ~~~ 更改数据源配置信息 ~~~xml <!--数据源配置信息--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> ~~~ **映射器(mappers)** 1、使用相对于类路径的资源引用,默认会在resource资源目录下去找 ~~~xml <!-- 使用相对于类路径的资源引用 --> <mappers> <mapper resource="org/mybatis/builder/AuthorMapper.xml"/> <mapper resource="org/mybatis/builder/BlogMapper.xml"/> <mapper resource="org/mybatis/builder/PostMapper.xml"/> </mappers> ~~~ 2、使用完全限定资源定位符(URL) ~~~xml <mappers> <mapper url="file:///var/mappers/AuthorMapper.xml"/> <mapper url="file:///var/mappers/BlogMapper.xml"/> <mapper url="file:///var/mappers/PostMapper.xml"/> </mappers> ~~~ 后续再讲 3、使用映射器接口实现类的完全限定类名 ~~~xml <!-- 使用映射器接口实现类的完全限定类名 --> <mappers> <mapper class="org.mybatis.builder.AuthorMapper"/> <mapper class="org.mybatis.builder.BlogMapper"/> <mapper class="org.mybatis.builder.PostMapper"/> </mappers> ~~~ 4、将包内的映射器接口实现全部注册为映射器 ~~~xml <mappers> <package name="org.mybatis.builder"/> </mappers> ~~~ ### 八、动态SQL 编写代码的时候,写的是基本结构,当程序运行的时候,会根据条件重新拼接SQL语句,从而生成新的SQL语句。 #### 8.1 if....where语句块 ~~~xml <select id="selectBySearch" resultType="Train" parameterType="Train" > SELECT * FROM train <where> <if test="train.startStation!=null"> and startStation=#{train.startStation} </if> <if test="train.startTime!=null"> and startTime=#{train.startTime} </if> </where> </select> ~~~ #### 8.2 choose、when、otherwise 日期函数: ~~~sql SELECT * FROM train_ticket WHERE DATE_FORMAT(start_date,'%Y-%m-%d')='2022-06-22'; ~~~ map入参,注意:map写在表达式中, ~~~xml <select id="selectNewsListSearch" parameterType="java.util.Map" resultMap="newsList"> SELECT t1.*,t2.* FROM news t1 LEFT JOIN newstype t2 ON t1.`newsTypeId`=t2.`newstype_id` <where> <choose> <when test="newsTypeId!=null"> and t2.newstype_id=#{map.newsTypeId} </when> <when test="newsTypeTitle!=null"> and t2.newstype_title=#{map.newsTypeTitle} </when> <otherwise> and 1=1 </otherwise> </choose> </where> </select> ~~~ #### 8.3 自定义 trim 元素 万能牌 ~~~XML <select id="selectBySearch" resultType="Train" parameterType="Train"> <trim prefix="where" prefixOverrides="AND | OR"> <if test="train.startStation!=null"> AND startStation=#{train.startStation} </if> <if test="train.startTime!=null"> and startTime=#{train.startTime} </if> </trim> </select> ~~~ trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆 盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为trim有这样的功能,所以我们也可以非常简单的利用trim 来代替where元素的功能。 #### 8.4 set语句 一般用于更新的情况 ~~~xml <update id="update"> UPDATE train_ticket <set> <if test="trainTicket.tripsName!=null"> trips_name=#{trainTicket.tripsName}, </if> <if test="trainTicket.tripsTypeId!=0"> trips_type_id=#{trainTicket.tripsTypeId}, </if> <if test="trainTicket.departureTerminal!=null"> departure_terminal=#{trainTicket.departureTerminal}, </if> <if test="trainTicket.destination!=null"> destination=#{trainTicket.destination}, </if> <if test="trainTicket.startDate!=null"> start_date=#{trainTicket.startDate}, </if> <if test="trainTicket.endDate!=null"> end_date=#{trainTicket.endDate}, </if> <if test="trainTicket.lasted!=0.0"> lasted=#{trainTicket.lasted}, </if> </set> where ticket_id=#{trainTicket.ticketId} </update> ~~~ #### 8.5 foreach 动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如: ~~~xml <delete id="delete" parameterType="java.util.List"> DELETE FROM train_ticket WHERE ticket_id IN <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </delete> ~~~ 注意:int [] 与ArrayList不可以通用。 ### 9、分页插件 #### 9.1 步在pom.xml添加依赖 ~~~xml <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency> ~~~ #### 9.2 在Mybatis核心配置文件中设置分页插件 在setting之下添加插件配置 ~~~xml <plugins> <!--设置分页插件--> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins> ~~~ #### 9.3 测试分页功能 ~~~java /**limit index,pageSize * index:当前页的起始索引 * pageSize:每页显示的条数 * pageNum:表示当前页的页码 * index=(pageNum-1)*pageSize * @author mengshujun * @create 2021-09-05 19:14 */ @Test public void test5(){ SqlSession sqlSession = MybatisUtils.openSession(); TrainTicketMapper trainTicketMapper = sqlSession.getMapper(TrainTicketMapper.class); PageHelper.startPage(1, 3); List<TrainTicket> list = trainTicketMapper.selectAll(); for (TrainTicket trainTicket : list) { System.out.println(trainTicket.toString()); } } ~~~ ### 十、注解开发 #### 10.1 单表操作 @Insert:实现新增 @Update:实现更新 @Delete:实现删除 @Select:实现查询 然后在Mapper接口的方法上,加上特定的注解实现对数据库表的操作 例如: ```java @Select("select * from user") List<User> findAllTest(); @Select("select * from user where id = #{id}") User findByIdTest(int id); @Insert("insert into user values(#{id},#{username},#{password},#{birthday});") void saveTest(User user); @Delete("delete from user where id = #{id};") void deleteTest(@Param("id") int id); @Update("update user set username=#{username},password=#{password} where id = #{id};") void updateTest(User user); ``` #### 10.2 动态SQL ~~~java @Update({"<script>", "update news ", " <set>", " <if test='news.newsId!=0'>newsId=#{news.newsId},</if>", " <if test='news.newsTitle!=null'>newsTitle=#{news.newsTitle},</if>", " </set>", "<where>", "newsId=#{news.newsId}", "</where>", "</script>"} ) int updateNews(@Param("news") News news); ~~~ ### 十一、注解实现复杂映射开发 @Results:可以与@Result 一起使用,封装多个结果集,代替`<resultMap>` @Result:实现结果集封装 1. column:数据库的列名 2. property:需要装配的属性名 3. one:需要使用的@One 注解(@Result(one=@One)())) 4. many:需要使用的@Many 注解(@Result(many=@many)())) @One:实现一对一结果集封装,代替`<assocation>` 使用格式:@Result(column=" ",property="",one=@One(select="")) @Many:实现一对多结果集封装,代替`<collection>` 使用格式:@Result(property="",column="",many=@Many(select="")) 实体类: News实体类 ~~~java package cn.hxzy.news.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Date; @Data @NoArgsConstructor @AllArgsConstructor public class News implements Serializable { private int newsId; private String newsTitle; private String newsInfo; private String newsFrom; private String newsContent; private Date createTime; private String newsimg; private NewsType newsType; //自定义的类型使用的时候,需要创建对象(赋值是看业务)(一对一) } ~~~ NewsType实体类 ~~~java package cn.hxzy.news.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor public class NewsType implements Serializable { private int newsTypeId; private String newsTypeTitle; //一对多 private List<News> newsList; public NewsType(String newsTypeTitle) { this.newsTypeTitle = newsTypeTitle; } public NewsType(int newsTypeId, String newsTypeTitle) { this.newsTypeId = newsTypeId; this.newsTypeTitle = newsTypeTitle; } } ~~~ #### 11.1 一对一查询 当查询一个表,需要把另一个表的数据也同时查询出来时 NewsMapper接口 ~~~java public interface NewsMapper { @Select("select * from news") @Results({ @Result(id = true, column = "newsId", property = "newsId"), @Result(column = "newsTitle", property = "newsTitle"), @Result(column = "newsInfo", property = "newsInfo"), @Result(column = "newsFrom", property = "newsFrom"), @Result(column = "newsContent", property = "newsContent"), @Result(column = "createTime", property = "createTime"), @Result(column = "newsimg", property = "newsimg"), @Result(column = "newsTypeId",property = "newsType", javaType = NewsType.class, one = @One(select = "cn.hxzy.news.mapper.NewsTypeMapper.selectNewsType")) }) List<News> selectNewsList(); } ~~~ NewsTypeMapper接口 ~~~java package cn.hxzy.news.mapper; import cn.hxzy.news.entity.NewsType; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import java.util.List; public interface NewsTypeMapper { @Select("select * from newsType where newstype_id=#{newsTypeId}") @Results({ @Result(id = true,column = "newstype_id",property = "newsTypeId"), @Result(column = "newstype_title",property = "newsTypeTitle") }) NewsType selectNewsType(@Param("newsTypeId") int newsTypeId); } ~~~ #### 12.2 一对多查询 1.查询单个类别对应多个资讯的情况 NewsMapper ~~~java public interface NewsMapper { @Select("select * from news where newsTypeId=#{newsTypeId}") List<News> selectNewsListByTypeId(int newsTypeId); } ~~~ NewsTypeMapper ~~~java public interface NewsTypeMapper { @Select("select * from newsType where newstype_id=#{newsTypeId}") @Results({ @Result(id = true,column = "newstype_id",property = "newsTypeId"), @Result(column = "newstype_title",property = "newsTypeTitle"), @Result(column = "newstype_id",property = "newsList",javaType = List.class, many = @Many(select = "cn.hxzy.news.mapper.NewsMapper.selectNewsListByTypeId")) }) NewsType selectNewsType(@Param("newsTypeId") int newsTypeId); } ~~~ 2.查询多个类别对应多个资讯的情况 NewsMapper ~~~java public interface NewsMapper { @Select("select * from news where newsTypeId=#{newsTypeId}") List<News> selectNewsListByTypeId(int newsTypeId); } ~~~ NewsTypeMapper ~~~java @Select("select * from newsType") @Results({ @Result(id = true,column = "newstype_id",property = "newsTypeId"), @Result(column = "newstype_title",property = "newsTypeTitle"), @Result(column = "newstype_id",property = "newsList",javaType = List.class, many = @Many(select = "cn.hxzy.news.mapper.NewsMapper.selectNewsListByTypeId")) }) List<NewsType> selectNewsTypeList(); ~~~ ### 十二、SQL语句块 ~~~xml <sql id="columns"> t1.newsId, t1.`newsTypeId`, t1.`newsTitle`, t1.`newsInfo`, t1.`newsFrom`, t1.`newsContent`, t1.`createTime`, t1.`newsimg`, t2.`newstype_id`, t2.`newstype_title` </sql> <sql id="newsSearch"> SELECT <include refid="columns"/> FROM news t1 LEFT JOIN newstype t2 ON t1.`newsTypeId`=t2.`newstype_id` </sql> <select id="selectNewsListSearch" parameterType="java.util.Map" resultMap="newsList"> <include refid="newsSearch"/> <where> <choose> <when test="newsTypeId!=null"> and t2.newstype_id=#{newsTypeId} </when> <when test="newsTypeTitle!=null"> and t2.newstype_title=#{newsTypeTitle} </when> <otherwise> and 1=1 </otherwise> </choose> </where> </select> ~~~ ### 十三、mybatis缓存 缓存是只针对查询业务有效,增删改操作会更新缓存。 #### 13.1 一级缓存 作用范围在一个sqlsession之间,如果中间有增删改操作会更新缓存,或者手动关闭sqlSession。 一级缓存不需要自己打开或者关闭,默认开启的,也关闭不了。 一级缓存不可以进行数据共享 #### 13.2 二级缓存 二级缓存可以进行数据共享,在线程中可以进行数据共享。
mybatis的教程
最新推荐文章于 2024-08-21 23:39:15 发布