Mybatis

mybatis 和 mybatis-plus 配置文件: 用于配置数据库连接和 MyBatis 运行时所需的各种特性,包含了设置和影响 MyBatis 行为的属性、映射文件的位置。mapper接口和mapper.xml之间需要遵循一定规则,才能成功的让mybatis将mapper接口和mapper.xml绑定起来。创建IUserMapper接口: 用于操作数据库CURD的方法。文件:用于mybatis配置文件读取数据库信息。resources 目录下 创建。resources 目录下 创建。resources 目录下 的。类:用于跟数据库字段做映射。 阅读详情

 一种持久层框架。支持定制化SQL、存储过程以及高级映射。

 避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。

 支持简单的XML或注解来配置和映射原生类型、接口和java的POJO为数据库中的记录。

 

 如何获取Mybatis?

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
</dependency>

 

第一个Mybatis程序

 1.搭建环境

   MYSQL–Database&table

CREATE DATABASE mybatis_demo;

create table `user`(
	id int(20) PRIMARY KEY,
	name	VARCHAR(30),
	pwd	VARCHAR(30)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

 2.新建Maven项目

   mybatisDemo

 3.导入Maven依赖

   pom.xml

<dependencies>
    <!--MySQL驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.32</version>
    </dependency>
    <!--MyBatis-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId> 
        <version>3.5.7</version>
    </dependency>
    <!--junit-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

 4.编写Mybatis的核心文件

   resource/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>
    <!--环境、可配置多个-->
    <environments default="development">
        <environment id="development">
            <!--事务管理-->
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo" />
                <property name="username" value="root"  />
                <property name="password" value="123" />
            </dataSource>
        </environment>
    </environments>

    <!--每个Mapper.xml都需要在核心配置文件中注册-->
    <mappers>
        <mapper resource="UserMapper.xml"></mapper>
    </mappers>
</configuration>

 5.编写Mybatis工具类

   主要通过配置文件来获取Mybatis间的相关类

public class MyBatisUtils  {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        //固定的写法,因此写成工具类
        try {
            //获取Mybaits的sqlSessionFactory对象
            String resource ="mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取通过sqlSessionFactory来获取SqlSession类
    //SqlSession包含了面向数据库执行SQL语句所需的所有方法
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

 6.编写Mybatis代码

​    目录结构

目录
	utils
		MyBatisUtils
	pojo
		User
	dao
		UserDao
resourcrs
	mybaits-config.xml
	UserMapper.xml

   实体层 pojo/User

public class User {
    private int id;
    private String name;
    private String pwd;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }

    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 getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public User(int id, String name, String pwd) {

        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public User() {

    }
}

   dao层

    dao/UserDao

public interface UserDao {
    List<User> getUsers();
}

  申明一个接口后,需要一个相对应的mapper文件来处理。

    dao/UserDaoMapper.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">
<!--namespace = "相对应的Mapper接口"-->
<mapper namespace="com.rz.dao.UserDao">
    <!--
        select查询语句
        id = "对应的方法名"
		resultType : 接收 封装结果集实体
    -->
    <select id="getUsers" resultType="com.rz.pojo.User">
        select * from `user`
    </select>
</mapper>
  1. 测试
public class UserDaoTest {
    @Test
    public void test(){
        //1.获取SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        //2.执行SQL语句
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> users = mapper.getUsers();

        for (User user : users) {
            System.out.println(user);
        }

        //3.关闭SqlSession
        sqlSession.close();
    }
}

 注:

​   第一次上手时,容易忽略细节,产生错误

org.apache.ibatis.binding.BindingException: Type interface com.rz.dao.UserDao is not known to the MapperRegistry.

​   产生原因:未在Mybatis配置文件注册

 

CRUD操作

 CRUD的具体语句都在xxxMapper.xml上书写

 

SELECT

1.在UserDao接口添加需要方法

 //根据ID查询用户
    User getUserById(int id);

2.在UserMapper.xml中写入语句

<!--
    select查询语句
    id = "对应的方法名"
    resultType:SQL语句执行的返回值
    parameterType 需要传入的值
-->
<select id="getUserById" resultType="com.rz.pojo.User" parameterType="int">
    select * from `user` where id = #{id}
</select>

3.编写测试

@Test
    public void Test1(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User userById = mapper.getUserById(1);
        System.out.println(userById); //User{id=1, name='Tom', pwd='123'}

        sqlSession.close();
    }

 

INSERT

1.在UserDao接口添加需要方法

int addUser(User user);

2.在UserMapper.xml中写入语句

<!--插入操作-->
<!-- parameterType :传入的参数
     其中 #{xxx} 须与 对象的属性名保持一致	
-->
<insert id="addUser" parameterType="com.rz.pojo.User">
    insert into user(id,name,pwd) values (#{id},#{name},#{pwd})
</insert>

3.编写测试

@Test
public void Test(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();

    UserDao mapper = sqlSession.getMapper(UserDao.class);
    int flag = mapper.addUser(new User(4, "Jack", "123"));

    /*
         Mybaits 若执行insert、delete、update操作,则需要提交事务
    	 因为Mybaits默认是关闭事务操作的
    */
    if (flag > 0){
        sqlSession.commit();
    }

    sqlSession.close();
}

 

UPDATE

1.在UserDao接口添加需要方法

int updateUser(User user);

2.在UserMapper.xml中写入语句

<update id="updateUser" parameterType="com.rz.pojo.User">
    update user set name=#{name},pwd=#{pwd} where id =#{id}
</update>

3.编写测试

@Test
public void Test(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();

    UserDao mapper = sqlSession.getMapper(UserDao.class);
    int flag = mapper.updateUser(new User(4, "JackWu", "231"));

    //增删改需要提交事务
    if (flag > 0){
        sqlSession.commit();
    }

    sqlSession.close();
}

 

DELETE

1.在UserDao接口添加需要方法

int delUser(int id);

2.在UserMapper.xml中写入语句

<delete id="delUser">
    delete from user where id = #{id}
</delete>

3.编写测试

@Test
public void Test(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();

    UserDao mapper = sqlSession.getMapper(UserDao.class);
    int flag = mapper.delUser(4);

    //增删改需要提交事务
    if (flag > 0){
        sqlSession.commit();
    }

    sqlSession.close();
}

 

开发小技巧:

​ 当字段或参数过多时,可以考虑通过Map来传参

1.在UserDao接口添加需要方法

int addUserOfMap(Map<String,Object> map);

2.在UserMapper.xml中写入语句

<insert id="addUserOfMap" parameterType="map">
    insert into user(id,name) values (#{id},#{name})
</insert>

3.编写测试

@Test
public void Test(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();

    UserDao mapper = sqlSession.getMapper(UserDao.class);

    Map map = new HashMap<String, Object>();
    map.put("id",4);
    map.put("name","jack");


    int flag = mapper.addUserOfMap(map);

    //增删改需要提交事务
    if (flag > 0){
        sqlSession.commit();
    }

    sqlSession.close();
}

 

核心配置文件

​ mybatis-config.xml

 文档结构

configuration	(配置)
	properties	(属性)
	setting	 (设置)
	typeAliases	 (类型别名)
	typeHandlers	(类型处理器)
	objectFactory	(对象工厂)
	plugins	 (插件)
	environments	(环境配置)
		environment (环境变量)
			transactionManager	(事务管理器)
			dataSource	(数据源)
	databaseidProvider	(数据库厂商标识)
	mappers	(映射器)

​

​ environments

  Mybatis可以配置多种环境 ,但每一个SqlSessionFactory实例只能选择一种环境

eg:

<!-
	决定使用哪个环境便 改变 environments标签中的 default 属性
	eg:
		<environments default="development">
		<environments default="test">
	注:
		默认<transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
-->
<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager> <!--指定事务管理类型为JDBC-->
            <dataSource type="POOLED"> <!--指定当前数据源类型是连接池-->
                <!--数据源配置的基本参数-->
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo" />
                <property name="username" value="root"  />
                <property name="password" value="123" />
            </dataSource>
        </environment>
        
        <environment id="test">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo" />
                <property name="username" value="root"  />
                <property name="password" value="123" />
            </dataSource>
        </environment>
    </environments>

 

​ properties

  可以通过properties属性来引用配置文件

  eg:

​    1.编写一个配置文件 db.properties

driver = com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis_demo
username=root
password=123

​    2.在核心文件中引入

<?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="db.properties"/>


    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <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>

    <!--每个Mapper.xml都需要在核心配置文件中注册-->
    <mappers>
        <mapper resource="UserMapper.xml"></mapper>
    </mappers>
</configuration>

 注:

​   可以直接引入外部文件、可以在其中增加一些属性配置

​   若两个文件中拥有用一字段,则优先使用外部配置文件

 

typeAliases

​  为java类型设置一个名字,可以用来减少类完全限定名的冗余

 eg:

​   1.在配置文件引入

​     a1.引入实体类

<typeAliases>
        <typeAlias type="com.rz.pojo.User" alias="user"/>
</typeAliases>

​     a2.引入包,默认名为这个类的类名,其中 首字母需小写。

<typeAliases>
        <package name="com.rz.pojo" />
</typeAliases>

  2.在Mapper.xml中使用

<select id="getUsers" resultType="user" >
        select * from `user`
</select>
<!-- 有区别于-->
<insert id="addUser" parameterType="com.rz.pojo.User">
    insert into user(id,name,pwd) values (#{id},#{name},#{pwd})
</insert>

 

mappers

<!--每个Mapper.xml都需要在核心配置文件中注册-->
    <mappers>
        <!--使用相对于类路径的资源引用-->
        <mapper resource="UserMapper.xml"></mapper>
        <!--使用完全限定资源定位法-->
        <mapper url="xxx/UserMapper.xml" />  <!--通常不用-->
        <!-- 
			使用映射器接口实现类的完全限定类名
				注: 接口和Mapper必须同名、且在同一路径
		-->
        <mapper class="com.rz.dao.UserMapper"/>
        <!-- 将包内的映射器接口实现全部注册为映射器-->
        <package name="com.rz.dao" />
    </mappers>

 

分页

 减少数据的处理量

​ 使用Limit分页

select * from user limit 0,2;
select * from user limit 2,4;

使用Mybatis实现分页

 1.接口

public interface UserDao {
    //分页
    List<User> getUserByLimt(Map<String,Object> map);
}

 2.配置文件Mapper.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.rz.dao.UserDao">

    <!--分页查询-->
    <select id="getUserByLimt" parameterType="map" resultType="user">
        select * from user limit #{startIndex},#{pageSize};
    </select>

</mapper>

 3.测试

@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);

        Map map = new HashMap<String, Integer>();

        map.put("startIndex",0);
        map.put("pageSize",2);

        List<User> userByLimt = mapper.getUserByLimt(map);

        for (User user : userByLimt) {
            System.out.println(user);
        }


        sqlSession.close();
    }

分页插件 PageHelper

  MyBatis 分页插件 PageHelper

 

解决属性名和字段名不一致的问题

 eg:

  实体类的相关属性

import lombok.Data;

@Data
public class User {
    private int id;
    private String name;
    private String password;
}

  而数据库中的字段为 pwd 与 属性password不符。根据上面查询的方法 得出的结果 password 全部为 null

 为了解决这个问题,将在Mapper.xml中引用resultMap[结果集映射]

<!-- id:名字,type:类名 -->
    <resultMap id="userMap" type="user">
        <!-- column:数据库中的字段名 property:类中的属性名 -->
        <result column="id" property="id" />
        <result column="name" property="name" />
        <result column="pwd" property="password" />
    </resultMap>

<!-- 并且相关标签中的属性也需要变化-->
<select id="getUsers" resultMap="userMap" >
        select * from `user`
 </select>

关系对关系

 关系存在着1对1,1对多,多对1三种情况。而1对1的情况在上文的例子中已经展示出来了。

 此处将采用老师和学生的关系进行展示。

 

 老师与学生:

  多个学生,对应着一个老师【多对一】(关联)

  一个老师 教 多少学生【一对多】 (集合)

 

多对一

 查询所有学生的信息 以及 对应的老师信息

 Mapper

public interface StudentMapper {
    public List<Student> getStudent();
}

Mapper.xml

 (按照查询嵌套处理)

​   查询所有的学生信息

​   根据所查询出来的tid,找到对应的老师

<?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.rz.dao.StudentMapper">

    <resultMap id="StudentAndTeacher" type="Student">
        <!--result 只能处理简单的属性-->
        <result property="id" column="id" />
        <result property="name" column="name" />
        <!--
            复杂的属性,则需要单独处理:
                对象 -> association
                集合 -> collection
        -->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
        <!--
            select 是将 column值 作为参数代入 所需的select语句
        -->
    </resultMap>

    <select id="getStudent" resultMap="StudentAndTeacher">
        select * from student;
    </select>

    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id = #{id};
    </select>


</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="com.rz.dao.StudentMapper">

    <resultMap id="StudentAndTeacher" type="Student">
        <result property="id" column="sid" />
        <result property="name" column="sname" />
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname" />
        </association>
</resultMap>

    <select id="getStudent" resultMap="StudentAndTeacher">
        select s.id sid,s.name sname,t.name tname
          from student s,teacher t
          where s.tid=t.id;
    </select>
</mapper>

测试

@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> student = mapper.getStudent();

        for (Student s: student) {
            System.out.println(s);
        }
        sqlSession.close();
    }

 

一对多处理

 环境搭建:

  1.实体类

@Data
public class Student {
    private  int id;
    private String name;
    private int tid;
}

@Data
public class Teacher {
    private int id;
    private String name;
    //拥有多个学生
    private List<Student> students;

}

 2.Mapper

public interface TeacherMapper {

    //获取老师及其管理学生
    Teacher getTeacherAndStudents(@Param("id") int id);
}

 3.Mapper.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.rz.dao.TeacherMapper">

    <resultMap id="TeacherAndStudent" type="Teacher">
        <result  property="id" column="tid" />
        <result  property="name" column="tname" />
        <!--
            javaType="" 指定属性的类型
            集合中的泛型信息,我们使用ofType获取
        -->
        <collection property="students" ofType="Student">
            <result property="id" column="sid" />
            <result property="name" column="sname"/>
        </collection>
    </resultMap>
    
    <select id="getTeacherAndStudents" resultMap="TeacherAndStudent">
        select s.id sid,s.name sname,t.name tname,t.id tid
          from student s, teacher t
          where s.tid = t.id and t.id = #{id};
    </select>
</mapper>

 4.测试

 @Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacherAndStudents(1);

        System.out.println(teacher);


        sqlSession.close();
    }

 

动态SQL

 根据不同的条件生成不同的SQL语句

 SQL标签

if
choose(when,otherwise)
trim(where,set)
foreach

环境搭建

 SQL

create table `blog`(
	id varchar(50),
	title varchar(100) ,
	author varchar(30),
	create_time datetime,
	views int(30)
)ENGINE=INNODB DEFAULT CHARSET=utf8

 工程相关内容

  1.实体类

@Data
public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

 2.接口
  Blog Mapper.class

public interface BlogMapper {
    //插入数据
    int addBook(Blog blog);

}

  BlogMapper.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.rz.dao.BlogMapper">
    <insert id="addBlog" parameterType="Blog">
    INSERT INTO `blog`
    VALUES (#{id},#{title},#{author},#{createTime},#{views})
</insert>


</mapper>

 3.配置

  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="db.properties"/>

    <settings>
        <!--
            是否开启自动驼峰命名规则 -> 处理字段名和属性名不一致
        -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    
    <typeAliases>
        <package name="com.rz.pojo"/>
    </typeAliases>


    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <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="com/rz/dao/BlogMapper.xml" />
    </mappers>

</configuration>

 4.测试

@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        Blog blog = new Blog();
        blog.setId(IdUtils.getId());
        blog.setTitle("Java_");
        blog.setAuthor("Tom");
        blog.setCreateTime(new Date());
        blog.setViews(5361);

        mapper.addBlog(blog);

        blog.setId(IdUtils.getId());
        blog.setTitle("JavaWeb_");
        mapper.addBlog(blog);

        blog.setId(IdUtils.getId());
        blog.setTitle("Spring_");
        mapper.addBlog(blog);

        blog.setId(IdUtils.getId());
        blog.setTitle("Mybatis_");
        mapper.addBlog(blog);

     sqlSession.close();
    }

 

IF语句

 1.添加方法

//查询博客
    List<Blog> queryBlogByIf(Map map);

 2.xml的修改

  <!--
        首先 where 1 = 1
            其次添加 if标签
            <if test="条件">
    -->
    <select id="queryBlogByIf" parameterType="map" resultType="Blog">
        select * from `blog` where 1 =1
        <if test="title != null">
            and title=#{title}
        </if>
        <if test="author != null">
            and  author =#{author}
        </if>
    </select>

3.测试

@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap hashMap = new HashMap();
        hashMap.put("title","javaWeb_");
        hashMap.put("author","Tom");

        List<Blog> blogs = mapper.queryBlogByIf(hashMap);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }


        sqlSession.close();
    }

 

trim(where,set)

​ where

  为了让if标签有效,且避免 where 1=1 的重复标签,则采取 where标签

​   where元素只会在至少有一个子元素的条件返回SQL子句的情况下才去插入WHERE子句。并且会自动将IF语句中开头的AND 或 OR 去除掉,

BlogMapper.xml

<select id="queryBlogByIf" parameterType="map" resultType="Blog">
        select * from `blog`
        <where>
            <if test="title != null">
                 title=#{title}
            </if>
            <if test="author != null">
                and  author =#{author}
            </if>
        </where>

    </select>

test

@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap hashMap = new HashMap();
        hashMap.put("title","javaWeb_");
//        hashMap.put("author","Tom");

        List<Blog> blogs = mapper.queryBlogByIf(hashMap);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }


        sqlSession.close();
    }

 

set

​  用于UPDATE语句中set属性.通过set的标签来进行动态SQL语句处理.

​  此时set元素会动态前置SET关键字,并删除无关的逗号
 
 1.方法

int updateBlog(Map map);

2.xml的修改

<update id="updateBlog" parameterType="map" >
        update `blog`
        <set>
            <if test="title != null">
                title=#{title},
            </if>
            <if test="author != null">
                author =#{author}
            </if>
        </set>
        where id = #{id}
    </update>

3.测试

@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap hashMap = new HashMap();
        hashMap.put("title","javaWeb_");
        hashMap.put("author","Jerry");
        hashMap.put("id","1fcbe3963c3143409d4ae49603aa0e51"); //为了测试,直接从数据库调

        mapper.updateBlog(hashMap);


        sqlSession.close();
    }

trim

 无论是where还是set 本质上都是trim

 格式:

<trim prefix="" prefixOverrides="" suffix="" suffixOverrides="">
            ...
</trim>

 prefix 前缀 prefixOverrides是覆盖什么 eg: prefix=“where”
 prefixOverrides=“AND | OR”
 suffixOverrides 后缀覆盖什么 eg:suffixOverrides =","
 

choose,when,otherwise

 有时候并不想应用到所有的条件语句,而需要其中一项。这是可以采用choose元素。

List<Blog> queryBlogChoose(Map map);
<select id="queryBlogChoose" parameterType="map" resultType="Blog">
        select * from `blog`
        <where>
            <choose>
                 <when test="title != null">
                     title=#{title}
                 </when>
                 <when test="author != null">
                     author =#{author}
                 </when>
                <otherwise>
                     and views = #{views}
                </otherwise>
            </choose>
        </where>
    </select>
@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap hashMap = new HashMap();
        //因为Choose只需要一个 所以只要有一个生效,后面的 都将会不被理睬。
        hashMap.put("title","javaWeb_");
//        hashMap.put("author","Tom");
        hashMap.put("views",5361);

        List<Blog> blogs = mapper.queryBlogChoose(hashMap);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }


        sqlSession.close();
    }

动态SQL有利于我们在SQL层面处理一些逻辑代码

 

Foreach

 对集合进行遍历[通常是在构建IN条件语句的时候]->区间范围

  1.首先将表中数据的id改为1 、2、3…

  2.

//查询第1-2-3号的博客
List<Blog> queryBlogForeach(Map map);
<!--
        collection 拿到的集合名
        item 集合元素
        open 添加前缀
        close 添加后缀
        separator 分隔符
    -->
    <select id="queryBlogForeach" parameterType="map" resultType="Blog">
        select * from `blog`
        <where>
          id IN
          <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
          </foreach>
        </where>
    </select>
@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap hashMap = new HashMap();
        ArrayList<Integer> ids = new ArrayList<Integer>();

        hashMap.put("ids",ids);
        ids.add(1);
        ids.add(2);
        List<Blog> blogs = mapper.queryBlogForeach(hashMap);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }


        sqlSession.close();
    }

 

SQL片段

若在开发中遇到 SQL公共部分,则可以进行抽离,方便使用.

1.首先将共同部分抽离

<sql id="selectBlog">
        select * from `blog`
</sql>

2.在语句中引用 [采用include标签]

<select id="queryBlogByIf" parameterType="map" resultType="Blog">
        <include refid="selectBlog" />
        <where>
            <if test="title != null">
                 title=#{title}
            </if>
            <if test="author != null">
                and  author =#{author}
            </if>
        </where>
    </select>

 注:

​   1.最好基于单表来定义SQL片段

​   2.不要存在where标签

 

使用注解开发

注解名作用
@Insert实现新增
@Update更新
@Delete删除
@Select查询
@Result实现封装结果集
@Results封装多个结果集
@One实现一对多结果集封装
@Many实现多对一结果集封装

​  eg:

  1.UserDao.

public interface UserDao {
    @Select("select * from user")
    List<User> getUsers();
}

  2.核心配置文件绑定接口

<!--绑定接口-->
    <mappers>
        <mapper class="com.rz.dao.UserDao" />
    </mappers>

  3.测试

public class UserDaoTest {

    @Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);

        List<User> users = mapper.getUsers();

        for (User user : users) {
            System.out.println(user);
        }


        sqlSession.close();
    }
}

 注:

  注解处理简单的十分高效,但若遇到复杂的时候,采用xml配置则会更高效。

 

实现增删改查

开启自动提交事务

//获取通过sqlSessionFactory来获取SqlSession类
    //SqlSession包含了面向数据库执行SQL语句所需的所有方法
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);
    }

​

SELECT

1.添加接口方法

//当方法存在多个参数时,每个参数前必须引入 @Param("value")说明
    @Select("select * from user where id = #{id}")
    User getUserById(@Param("id")int id);

2.测试

@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);

        User users = mapper.getUserById(1);

        System.out.println(users);


        sqlSession.close();
    }

INSERT

@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{pwd})")
    int addUser(User user);
@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);
        int flag = mapper.addUser(new User(4,"Jack","123"));

        //增删改需要提交事务
        if (flag > 0){
            sqlSession.commit();
        }

        sqlSession.close();
    }

UPDATE

@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{pwd})")
int addUser(User user);
@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);
        int flag = mapper.updateUser(new User(4, "JackWu", "231"));

        //增删改需要提交事务
        if (flag > 0){
            sqlSession.commit();
        }

        sqlSession.close();
    }

DELETE

@Delete("delete from user where id = #{id}")
    int delUser(int id);
@Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);
        int flag = mapper.delUser(4);

        //增删改需要提交事务
        if (flag > 0){
            sqlSession.commit();
        }

        sqlSession.close();
    }

 

一对一注解 @One

​ OrderMapper

public interface OrderMapper {

    @Select("SELECT *,o.id oid FROM `orders` o,user u where o.uid = u.id;")
    @Results({
            @Result(column = "oid" ,property = "id"),
            @Result(column="total" ,property="total"),
            @Result(column="uid",property="user.id"),
            @Result(column="username",property="user.username"),
            @Result(column="password",property="user.password"),
    }) //Results 约定于resultMap
    public List<Order> findAll();
}

Test

@Test
    public void test() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);

        List<Order> all = mapper.findAll();

        for (Order order : all) {
            System.out.println(order);
        }
    }

 

例外一种方式

 通过封装集体

 其中one 是传入column的值,通过UserMapper的方法找到 想要的相关数据

public interface OrderMapper {
    
    @Select("SELECT *,o.id oid FROM orders o")
    @Results({
            @Result(column = "oid" ,property = "id"),
            @Result(column="total" ,property="total"),
            @Result(
                    property = "user", //要封装的属性名称
                    column = "uid" ,//根据哪个字段查询user表的数据
                    javaType = User.class,  //要封装的实体类型
                    one =@One(select = "com.rz.mapper.UserMapper.findById")
            )
    })
    public List<Order> findAll();
}

 

一对多注解 @Many

 OrderMapper.java

 增加了一个通过uid获得相关数据的方法

public interface OrderMapper {

    @Select("SELECT *,o.id oid FROM orders o")
    @Results({
            @Result(column = "oid" ,property = "id"),
            @Result(column="total" ,property="total"),

            @Result(
                    property = "user", //要封装的属性名称
                    column = "uid" ,//根据哪个字段查询user表的数据
                    javaType = User.class,  //要封装的实体类型
                    one =@One(select = "com.rz.mapper.UserMapper.findById")
            )
    })
    public List<Order> findAll();

    @Select("select * from orders where uid = #{uid}")
    public List<Order> findByUId(int uid);
}

UserMapper

@Select("select * from user")
    @Results({
            @Result(column = "id" ,property = "id"),
            @Result(column="username" ,property="username"),
            @Result(column = "password",property = "password"),

            @Result(
                    property = "orderList",
                    column = "id" ,
                    javaType = List.class,
                    one =@One(select = "com.rz.mapper.OrderMapper.findByUId")
            )
    })
    public List<User> findUserAndOrderAll();

Test

@Test
    public void test() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> userList = mapper.findUserAndOrderAll();

        for (User user : userList) {
            System.out.println(user);
        }

        sqlSession.close();
    }
Mybatis三剑客(mybatis-generator、mybatis-plugin、mybatis-pagehelper)介绍、配置及破解 本文用的是maven,idea15Mabatis三剑客分别是:mybatis-generator、mybatis-plugin、mybatis-pagehelper一、mybatis-generator根据我们的数据库自动生成pojo、dao和xml文件 pojo里面放的是跟数据库字段一一对应的对象、dao层是接口,供service使用,xml是这个dao层接口的实现,sql语句都写在xml里1. 阅读详情

相关推荐

MyBatisCodeHelper-Pro:IntelliJ IDEA专用Mybatis代码生成插件

本文还有配套的精品资源,点击获取 简介:MyBatisCodeHelper-Pro是一个为IntelliJ IDEA 2020.3.X版本设计的高效Mybatis代码生成插件。该插件通过自动生成Mapper接口、XML配置文件、Service、DAO和实体类等代码,显著提高Mybatis开发者的生产力,并减少重复性编码工作。它支持定制SQL、存储过程、高级映射,并提供智能代...

weixin_35762258的博客 5860

Mybatis插件MyBatisCodeHelperPro使用

通过MyBatisCodeHelperPro插件快速通过实体类反向生成数据库表,并使用插件通过数据库表快速生成Mapper接口和Mapperxml文件

Tony_chenph的博客 1万+

mybatiscodehelper.zip

在idea下使用maven的mybatis-generator-maven-plugin插件自动生成实体映射文件

mybatis插件助手的使用

一、首先安装MybatisCodeHelper-Pro插件助手 打开idea,点击File—》Setting—》Plugins—》点击小齿轮,选择Install Pligin from disk 然后从你本地中找到MybatisCodeHelper-Pro的压缩包,然后点ok 重启Idea,激活插件, 点击Tools—》MybatisCodeHelper—》Activation 二、激活成功后连接数据库 点击右侧的Database,然后点击+号,选择Data Source,选择.

hiuqwhiuhadi的博客 2266

MyBatisCodeHelper_1.4.5

特性 支持mysql和oracle 根据java对象生成mybatis crud代码和建表sql 根据mybatis接口中的方法名生成mybatis的sql 支持find,update,delete,count方法 只需定义一个方法名就可以得到完整mybatis xml代码 可生成大部分单表操作sql 极大提升效率 mybatis接口文件的mapper xml之间的相互跳转 数据库对象更新后一键更新对应的Sql和mybatis xml文件 默认提供insert,insertSelective,insertList,update。因为delete可以由方法名生成 默认不提供 提供mybatis接口方法名的重构 refid, resultMap跳转到到定义,支持重命名 refid,resultMap,keyProperty,property的自动补全 mybatis mapper xml文件sql的自动补全 使用方法 在数据库对象上使用alt+insert (generate mybatis files)来生成crud代码和建表sql(mac上使用ctrl+N) 数据库对象添加字段后使用alt+insert (generate mybatis files) 来生成更新sql,mapper xml中的字段 在mybatis接口的方法名上使用alt+enter来生成对应的mapper sql

mybatisCodeHelper

支持mysql和oracle和sqlite 根据java对象生成mybatis crud代码和建表sql 根据mybatis接口中的方法名生成mybatis的sql 支持find,update,delete,count方法 只需定义一个方法名就可以得到完整mybatis xml代码 可生成大部分单表操作sql 极大提升效率 mybatis接口文件的mapper xml之间的相互跳转 支持生成if-test 方法名生成sql支持生成到service和service接口 数据库对象更新后一键更新对应的Sql和mybatis xml文件 默认提供insert,insertSelective,insertList,update。因为delete可以由方法名生成 默认不提供 提供mybatis接口方法名的重构 refid, resultMap跳转到到定义,支持重命名 refid,resultMap,keyProperty,property的自动补全 支持更换图标 mybatis mapper xml文件sql的自动补全

MyBatis Code

MyBatis pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaL...

kaylee_study的博客 322

MybatisCodeHelperNew-2.8.1-191-201.zip(亲测Intellij2020.1绝对可用)

Intellij最新插件MybatisCodeHelper-2.8.1-191-201,使用方法IDEA顶部菜单:Tools -> MybatisCodeHelper -> Activation -> OfflineActivation,在offline key框输入任意字符串 Intellij2020.1版本可以使用,先安装官方最新版本,然后做文件替换即可,替换路径为:C:\Users\xxxx\AppData\Roaming\JetBrains\IntelliJIdea2020.1\plugins\MyBatisCodeHelper-Pro\lib 使用方法请参看博客:https://blog.youkuaiyun.com/lianghecai52171314/article/details/105511508

绝对详细的MyBatis代码生成器讲解

在springboot工程中如果使用mybatis作为持久层框架,那必须知道如何自动生成 java 实体类、dao 层接口(mapper 接口)及mapper.xml文件,这样可以减少不必要的开发。

gzmyh的博客 2288

MybatisCodeHelperNew-2.8.2.zip

idea---MybatisCodeHelperNew-2.8.2版插件 ,绝对支持idea2020.2版本

基于因果推理的LLM去毒:精准定位注意力头实现高效干预

在大型语言模型(LLM)的部署与应用中,模型安全与可控性是核心挑战之一。传统方法如全参数微调成本高昂,且可能损害模型通用能力。本文聚焦于一种基于因果推理的精准干预技术,其原理在于利用因果发现算法定位Transformer模型中与“毒性”输出存在强因果关联的特定注意力头。该技术通过分析注意力头的激活模式与生成文本毒性分数之间的因果关系,识别出关键责任单元,而非依赖传统的相关性分析。其技术价值在于实现了轻量级、高可解释性的模型行为修正,能以极低的参数改动代价有效降低模型在敏感话题上的有害输出。在应用场景上,该方

weixin_32667439的博客 313

Mybatis-Plus和Mybatis区别

核心关系:MyBatis-Plus 是 MyBatis 的增强版,完全兼容 MyBatis,不改变原有使用方式,仅做功能补充。核心差异:MP 提供了「通用 CRUD、条件构造器、分页插件、代码生成器」等开箱即用的功能,大幅减少重复代码;而原生 MyBatis 更侧重 SQL 的手动控制。选型建议:优先选 MyBatis-Plus(开发效率更高),遇到复杂 SQL 时,仍可像原生 MyBatis 一样手动编写,兼顾效率与灵活性。

weixin_53050448的博客 1237

电阻应变式力传感器

电阻应变式力传感器

lu_fresh_student的博客 5075

MYBATIS缓存

MYBATIS的第一缓存是SQLSession 并且这种缓存是即使在仅仅只有一个框架的情况下都是存在的, 因为第一缓存是默认开启的(default), 因为第一缓存级别使用的是SqlSession, 所以在调用同一个SqlSession, 并且在这同一个SqlSession当中多次查询同一个数据, 那么仅仅只会执行一次相应的SQL语句, 之后会直接从SQL缓存当中进行获取以我的测试类为例@Test结果如图所示, 跟我们预想的一样, 在第一级别的缓存下, 仅仅调用了一次相应的查询语句。

2303_79546217的博客 1432

Claude Code 从入门到精通,通过实战项目穿插 Agent Skills、MCP、Hooks、子代理、插件等十五个知识点

本文介绍了Claude Code的高级使用技巧,通过一个个人简历网站实战项目,详细讲解了15个核心知识点。主要内容包括:三种权限模式(默认/编辑/计划)的使用与切换;历史会话管理(/resume、/rename、/clear命令);会话回滚功能(/rewind);以及危险参数--dangerously-skip-permissions的注意事项。文章还演示了如何通过计划模式拆分代码文件,并强调了在复杂任务中仔细检查规划步骤的重要性。这些技巧能帮助开发者更高效地使用Claude Code完成项目开发。

1788

拉曼光谱入门:5.表面增强与共振增强

拉曼散射效应因其弱信号特性限制了传统拉曼光谱术的检测灵敏度。为克服这一局限,表面增强拉曼光谱术(SERS)和共振增强拉曼光谱术(RRS)被开发出来,显著提升了信号强度。SERS通过金属表面的电磁和化学效应放大信号,而RRS则通过匹配激发光波长与分子电子跃迁波长来增强信号。这两种技术扩大了拉曼光谱的应用范围,尤其在低浓度和微量试样分析中表现出色,尽管在实验操作和试样损伤方面存在挑战。

qq_53529450的博客 1446

MyBatis

mybatis、mybatis-spring、mybatis-springboot源码学习

parkerJ 642

Vue3 + 高德地图实现车辆电子围栏监控与报警

通过本文的实现,我们完成了一个通用的车辆电子围栏监控功能:支持多种围栏类型。支持进入/离开/双向报警。使用缓存机制避免重复告警。可与Vue3 + 高德地图无缝集成。在实际项目中,可以结合WebSocket 实时定位,实现车辆的实时监控 + 围栏告警系统🚀。

专注于前端开发与实战技巧,记录从零到一的学习与项目经验。分享 Vue3 / JavaScript / TypeScript / Flutter /Uniapp等前端技术,以及 性能优化、工程化、最佳实践。 1035

Mybatis的批量操作

每种方法都有其适用场景和限制。例如,使用 标签生成的批量 SQL 在某些数据库中可能因为 max_allowed_packet 大小限制而失败。因此,在选择批量处理方案时,需要根据具体的业务需求和数据库特性进行综合考虑。愿你我都能在各自的领域里不断成长,勇敢追求梦想,同时也保持对世界的好奇与善意!

weixin_45809780的博客 2602

基于BEV(鸟瞰图)的3D检测:PointPillars与CenterPoint

基于BEV(鸟瞰图)的3D检测:PointPillars与CenterPoint​ ,人工智能,计算机视觉,大模型,AI,本文围绕基于BEV的3D检测,解析了PointPillars与CenterPoint两种算法。PointPillars用点柱特征编码网络处理点云,通过2D卷积网络提取特征,检测头为解耦头;CenterPoint将三维物体表为点,分两阶段检测,先找中心点及属性,再细化预测。两者都可借特定骨干网生成BEV特征图且基于BEV检测,但检测头设计和物体表示方式不同。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 27万+

从 Open SQL JOIN 走向 ABAP CDS Association:把查询写成可复用的数据模型

摘要: 本文通过飞行模型示例,对比了ABAP中三种表关联实现方式:Open SQL JOIN、CDS显式JOIN和CDS Association。重点解析了Association的本质是将表关系声明为数据模型语言,使用时通过路径表达式按需展开为JOIN。文章指出路径表达式在不同位置会默认展开为不同JOIN类型(如SELECT列表默认为LEFT OUTER),并演示了如何用[inner]强制指定INNER JOIN。最后结合S/4HANA实际案例,说明Association通过中心化关系定义和路径复用,能有效

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 384

MyBatis02-mybatis-config.xml配置文件讲解

mybatis-config.xml核心配置文件,内容的讲解

qq_31532983的博客 1403

YOLOv11模型改进-模块-引入特征细化模块FRFN 解决小目标、遮挡等问题

FRFN 是一种专门设计的深度学习结构,旨在提高图像处理任务中的特征表示能力。它的核心设计理念是通过逐层细化和优化特征图,从而实现更高的分类和检测精度。1. 特征提取层:通过卷积层提取初始特征,并进行批量归一化以增强稳定性。2. 特征细化模块:在每个模块中,当前层特征图与前一层特征图进行融合,以强化特征表示。3. 跳跃连接:通过跳跃连接保留多尺度信息,帮助缓解深层网络中的信息丢失。4. 非线性激活:使用激活函数(如ReLU)增加模型的非线性能力。5. 输出层。

qq_64693987的博客 3337

Spring Boot整合MyBatis实现简单的CRUD

这篇文章主要针对java初学者,详细介绍如何创建一个基本的springboot项目来对数据库进行crud操作。

沐雨橙风ιε的博客 4488

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: 运行时数据区之虚拟机栈
下一篇: 本地方法栈
code_Floyed
博客等级 码龄7年 3粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值