欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mybatis笔记整理

程序员文章站 2022-04-20 08:29:18
mybatis主要类的介绍Resources:mybatis中负责读取主配置文件String config = "mybatis.xml";InputStream in = Resources.getResourceAsStream(config);SqlSessionFactoryBuilder:创建SqlSessionFactory对象SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSe...

mybatis主要类的介绍


  1. Resources: mybatis中负责读取主配置文件
String config = "mybatis.xml";
InputStream in = Resources.getResourceAsStream(config);
  1. SqlSessionFactoryBuilder: 创建SqlSessionFactory对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
  1. SqlSessionFactory: 重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目一个就够了。

​ SqlSessionFactory是个接口,实现类是defaultSqlSessionFactory。作用是获取sqlSession对象。

openSession()方法说明:

openSession():	无参,获取是非自动提交事务的sqlSession对象

openSession(boolean);	openSession(true)获取自动提交事务的Sqlsession
    
SqlSession sqlSession = factory.openSession();
  1. SqlSession(核心方法)

SqlSession接口:定义了操作数据的方法,例如:selectOne(),selectList(),insert(),update(),delete(),commit(),rollback()

SqlSession的实现类DefaultSqlSession

使用要求:SqlSession对象线程不安全,需要在方法内使用,在执行sql语句之前,使用openSession()获取sqlSession对象。在执行完sql语句后,需要关闭它,执行SqlSession.close(),这样保证他的使用是线程安全的。
mybatis笔记整理
mybatis笔记整理


mybatis-mapper模板文件 dao映射文件

<?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="">
    <select id="" resultType="">
        
    </select>

</mapper

mybatis笔记整理


mybatis-config模板 resources主配置文件 mybatis.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>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <environments default="">
        <environment id="">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/"/>
                <property name="username" value="root"/>
                <property name="password" value="137171"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource=""/>
    </mappers>
</configuration>

mybatis笔记整理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--settings 控制mybatis全局行为-->
    <settings>
        <!--设置mybatis输出日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <!--环境配置:数据库的连接信息
        default: 必须和某个environment的id值一样
            告诉mybatis使用哪个数据库连接信息,也就是访问哪个数据库
    -->
    <environments default="mydev">
        <!--environment 一个数据库信息的配置,环境
            id 一个唯一值,自定义,表示当下环境的名称
        -->
        <environment id="mydev">
            <!--
                transactionManager: mybatis的事务类型
                              type: JDBC (表示使用jdbc中的Connection对象的commit,rollback做事务处理)
            -->
            <transactionManager type="JDBC"/>
            <!--
                daraSource: 表示数据源,连接数据库
                      type: 表示数据库的类型,POOLED表示使用连接池
            -->
            <dataSource type="POOLED">
                <!--
                    driver,user,username,password 是固定的,不能自定义
                -->
                <!--数据库的驱动类名-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--连接数据库的url字符串-->
                <property name="url" value="jdbc:mysql://localhost:3306/ssh"/>
                <property name="username" value="root"/>
                <property name="password" value="137171"/>
            </dataSource>
        </environment>
        
        <!--表示线上的数据库,是项目真实使用的库-->
        <environment id="online">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/onlinedb"/>
                <property name="username" value="root"/>
                <property name="password" value="137171"/>
            </dataSource>
        </environment>
    </environments>

    <!--sql mappper(sql映射文件)的位置-->
    <mappers>
        <!-- 一个mapper标签指定一个文件的位置
             从类路径开始的路径信息。target/classes(类路径)
        -->
        <mapper resource="com/zh/dao/Student01Dao.xml"/>
    </mappers>
</configuration>

<!--
    mybatis 的主配置文件 定义了数据库的配置信息,sql映射文件的位置

    1.约束文件
    <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

        mybatis-3-config.dtd 约束文件的名称

    2.configuration 根标签
-->


动态代理


mybatis帮你创建dao接口的实现类,在实现类中调用SqlSession的方法执行sql语句

使用动态代理方式

1.获取SqlSession对象,SqlSessionFactory.openSession()
2.使用getMapper方法获取某个接口的对象,sqlSession.getMapper(接口.class)
3.使用dao接口的方法,调用方法就执行了mapper文件中的sql语句

使用动态代理的要求
1.dao接口和mapper文件放在一起,同一个目录
2.dao接口和mapper文件名称一致
3.mapper文件中的namespace的值是dao接口的全限定名称
4.mapper文件中的<select>,<insert>,<update>,<delete>等的id是接口中方法名称
5.dao接口中不要使用重载方法,不要使用同名的,不同参数的方法

1)自己创建实现类的方式
mybatis笔记整理

实现类

public class StudentDaoImpl implements StudentDao {

    @Override
    public List<Student> selectStudents() {

        //获取SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        String sqlId = "com.zh.dao.StudentDao.selectStudents";
        //执行sql语句,用SqlSession类里面的方法
        List<Student> students = sqlSession.selectList(sqlId);
        //关闭事务
        sqlSession.close();
        return students;
    }
}

测试类

public class TestMyBatis {
    @Test
    public void testSelectStudent(){

        StudentDao Dao = new StudentDaoImpl();
        List<Student> students = Dao.selectStudents();
        for (Student student: students){
            System.out.println(student);
        }
    }
}
  1. 使用JDK动态代理机制,不用创建实现类,直接调用==SqlSession.getMapper(dao接口.class)==j,就可以得到dao接口的实现类
public class TestMyBatis {
    @Test
    public void testSelectStudent(){

        /*
        * 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口.class)
        * getMapper能获取dao接口对应的实现类对象
        *
        * */
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);	//重点

        System.out.println("dao="+dao.getClass().getName());//dao=com.sun.proxy.$Proxy2,JDK动态代理

        List<Student> students = dao.selectStudents();
        for (Student student : students){
            System.out.println("学生"+student);
        }
    }
}


传入参数

从java代码中把数据传入到mapper文件的sql语句中

注意:parameterType

parameterType:  dao接口中方法参数的数据类型

parameterType它的值是java的数据类型全限定名称或者是Mybatis定义的别名
例如:parameterType="java.lang.Integer"
     parameterType="int"

注意:parameterType不是强制的,mybatis通过反射机制能够发现接口参数的数据类型,
所以可以没有,一般不写。

传入参数的几种方式

1	一个简单类型的参数:#{任意字符}
2 	多个简单类型的参数,使用@Param"自定义名称"3	使用一个java对象,对象的属性值作为mapper文件找到参数,#{java对象的属性值名称}
  1. 一个简单类型的参数
 简单类型:mybatis把java的基本数据类型和String都叫简单类型
 在mapper文件获取简单类型的一个参数的值,使用#{任意字符}

​ 接口

public Student selectStudentById(Integer id);

​ mapper映射查询语句

<select id="selectStudentById" resultType="com.zh.entity.Student" parameterType="java.lang.Integer">
    select id,name,email,age from student where id=#{id}
</select>
  1. 传递多个参数,在形参定义的前面加入 @Param(“自定义参数名称”) ★★★

​ 接口

public List<Student> selectMulitParam(@Param("myname") String name,@Param("myage") String age)

​ mapper文件

<select>
	select id,name,email,age from student where name=#{myname} or age=#{myage}
</select>
  1. 传递多个参数,使用java对象作为接口中方法的参数 ★★★

​ 自定义实体类 QueryParam.java
mybatis笔记整理

package com.zh.vo;
public class QueryParam {

    private String paramName;
    private Integer paramAge;

    public String getParamName() {return paramName;}
    public void setParamName(String paramName) {this.paramName = paramName;}
    public Integer getParamAge() {return paramAge;}
    public void setParamAge(Integer paramAge) { this.paramAge = paramAge;}}
}

​ 接口

List<Student> selectMultiObject(QueryParam param);

​ mapper文件

<select id="selectMultiObject" resultType="com.zh.entity.Student">
    select * from Student where name=#{paramName} or age=#{paramAge}
</select>

“#” 和 “$” 的区别

1	#是占位符,表示列值的,放在等号右侧
2	$是占位符,表示字符串的连接,把sql语句连接成一个字符串
3	#使用JDBC指定PreparedStatement对象执行SQL语句,效率高,没有sql注入的风险
4	$使用Starement对象执行sql,效率低,有sql注入的风险


封装Mybatis输出结果

mybatis笔记整理

  1. resultType

resultType 执行 sql 得到 ResultSet 转换的类型,使用类型的全限定名或别名。注意如果返回的是集合,那应该设置集合包含的类型。resultType 和 resultMap ,不能同时使用。

1	resultType 结果类型,指sql语句执行完成后,数据转为java对象,java类型是任意的
	resultType 结果类型,它的值
						1、类型的全限定名称
						2、类型的别名,例如 java.lang.Integer的别名为int

接口方法

public Student selectStudentById(Integer id);

mapper映射

<select id="selectStudentById" resultType="com.zh.entity.Student" >
       select id,name,email,age from student where id=#{id}
</select>

测试方法

@Test
public void testSelectStudentById(){

    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);

    Student student = dao.selectStudentById(2);

    System.out.println("student="+student);

}
  1. resultMap

resultMap 可以自定义sql的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。常用在列名和 java 对象属性名不一样的情况。

定义自定义类型的别名

1	在mybatis主配置文件中定义,使用<typeAlias>定义别名
2	可以在resultType中使用自定义别名

resultMap 结果映射,指定列名和java对象属性的对应关系

1	你自定义列值赋值给哪个属性
2	当你的列名和属性名不一样时,一定使用resultMap

接口

 //使用resultMap定义映射关系
 List<Student> selectAllStudent();

mapper映射文件

<resultMap id="StudentMap" type="com.zh.entity.Student">
            <!--column 列名 property java类型的属性名 -->
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="email" column="email"/>
            <result property="age" column="age"/>
</resultMap>

<!--使用resultMap-->
<select id="selectAllStudent" resultMap="StudentMap">
    select id,name,email,age from student
</select>
  1. 当查询的列名和类中属性名不一样时

方式一

自定义MyStudent.java

package com.zh.entity;

public class MyStudent {

    private Integer stuid;
    private String stuname;
    private String stuemail;
    private Integer stuage;

    public Integer getStuid() { return stuid;}
    public void setStuid(Integer stuid) { this.stuid = stuid;}
    public String getStuname() {return stuname;}
    public void setStuname(String stuname) { this.stuname = stuname;}
    public String getEmail() { return stuemail;}
    public void setEmail(String email) { this.stuemail = email;}
    public Integer getStuage() {return stuage;}
    public void setStuage(Integer stuage) { this.stuage = stuage;}
    @Override
    public String toString() {
        return "myStudent{" +
                "stuid=" + stuid +
                ", stuname='" + stuname + '\'' +
                ", email='" + stuemail + '\'' +
                ", stuage=" + stuage +
                '}';
    }
}

mapper映射

<!-- type映射地址是 com.zh.entity.MyStudent.java -->
<resultMap id="myStudentMap" type="com.zh.entity.MyStudent">
    <!--
		column:别名 
	     property: java类型的属性名 
	-->
    <id property="stuid" column="id"/>
    <result property="stuname" column="name"/>
    <result property="stuemail" column="email"/>
    <result property="stuage" column="age"/>
</resultMap>
<!--要查的sql列名和 MyStudent.java 属性名不一样-->
<select id="selectMyStudent" resultMap="myStudentMap">
    select id,name,email,age from student
</select>

方式二

mapper映射: 直接在sql语句中添加 ( as 对象属性名)

<!--resultType的默认原则是:同名的列值赋值给同名的属性,使用列别名(java对象属性名)--->
<select id="selectDiffColProperty" resultType="com.zh.entity.MyStudent">
    select id as stuid,name as stuname,email as stuemail,age as stuage from student
</select>

  1. like 模糊查询

在java代码中指定like的内容

//第一种模糊查询,在java代码指定like的内容
List<Student> selectLikeOne(String name);

mapper文件

<!--第一种like,java代码指定like的内容-->
<select id="selectLikeOne" resultType="com.zh.entity.Student">
    select id,name,email,age from student where name like #{name}
</select>

测试类

@Test
public void testSelectLikeOne(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);

    //定义一个String类型的值
    String name = "%周%";
    List<Student> students = dao.selectLikeOne(name);

    for (Student stu : students){
        System.out.println(stu);
    }
    sqlSession.close();

}

mybatis笔记整理


动态sql

sql内容是变化的,可以根据条件获取到不同的sql语句。主要是where部分发生变化。

动态sql的实现,使用的是mybatis提供的标签,,,

  1. 是判断条件

语法

部分sql语句

2) 用来包含多个,当多个if有一个成立时,会自动生成一个WHERE关键字,并去掉if中多余的and,or等

接口

//where
List<Student> selectStudentWhere(Student student);

mapper

<!--where
    <where>
        <if></if>
        <if></if>
    </where>
-->
<select id="selectStudentWhere" resultType="com.zh.entity.Student">
    select id,name,email,age from student
    <where>
        <if test="name != null and name != ''">
            name = #{name}
        </if>

        <if test="age > 0">
           or age = #{age}
        </if>


    </where>
</select>

测试

//where
@Test
public void testSelectStudentWhere(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);

    Student student = new Student();
    student.setName("周润发");
    student.setAge(20);
    List<Student> students = dao.selectStudentWhere(student);
    for (Student student1 : students){
        System.out.println("Where="+student1);
    }
    sqlSession.close();
}

执行结果:
mybatis笔记整理

去掉一个student.setName(“周润发”);执行结果:
mybatis笔记整理

3) 循环java中的数组,list集合的。主要用在sql的in语句中。

用法一 根据id查询

接口

//foreach   
List<Student> selectForeachOne(List<Integer> idlist);

mapper

<!--foreach 方式一-->
<select id="selectForeachOne" resultType="com.zh.entity.Student">
    select * from student where id in
    <foreach collection="list" item="myid" open="(" close=")" separator=",">
        #{myid}
    </foreach>

</select>

测试

//foreach 方式一
@Test
public void testSelectForeachOne() {
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);

    //定义一个list数组
    ArrayList<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);

    List<Student> students = dao.selectForeachOne(list);
    for (Student student : students) {
        System.out.println("foreach=" + student);
    }
}

用法二 根据对象属性查询

接口

//foreach   用法二 根据对象属性查询
List<Student> selectForeachTwo(List<Student> stulist);

mapper

<!--foreach 方式二-->
<select id="selectForeachTwo" resultType="com.zh.entity.Student">
    select * from student where id in
    <foreach collection="list" item="stu" open="(" close=")" separator=",">
        #{stu.id}
    </foreach>

</select>

测试

//foreach 方式二
@Test
public void testSelectForeachTwo() {
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);

    List<Student> stuList = new ArrayList<>();

    Student s1 = new Student();
    s1.setId(1);
    stuList.add(s1);

    Student s2 = new Student();
    s2.setId(2);
    stuList.add(s2);

    List<Student> students = dao.selectForeachTwo(stuList);
    for (Student student : students) {
        System.out.println("foreach=" + student);
    }


}

结果:
mybatis笔记整理

定义sql代码片段,替代相同sql语句

mapper

<!--定义sql片段-->
    <sql id="studentSql">
        select id,name,email,age from student
    </sql>

    <select id="selectStudentIf" resultType="com.zh.entity.Student">
--         select id,name,email,age from student
        <include refid="studentSql"/>
        where id > 0
        <if test="name != null and name != ''">
            name = #{name}
        </if>

        <if test="age >0">
            or age > #{age}
        </if>
    </select>

数据库的属性配置文件,把数据库连接信息放到一个单独的文件中。便于修改,保存,处理多个数据库信息。

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssh
jdbc.username=root
jdbc.password=137171

mybatis.xml

<!--指定properties文件位置,从根路径开始找文件-->
<properties resource="jdbc.properties"/>

<environments default="one">

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

mybatis.xml 主配置文件中 sql映射文件读取书写说明:

<!--sql映射文件的位置-->
<mappers>
    <!--方法一:指定多个mapper文件-->
    <mapper resource="com/zh/dao/StudentDao.xml"/>

    <!--方法二:使用包名
        name:mapper文件所在的包名,包中所有xml一次性加载
        要求:
        1   mapper文件名需要和接口名一样
        2   mapper文件和dao接口在同一目录下
    -->
    <package name="com.zh.dao"/>
</mappers>

mybatis笔记整理

本文地址:https://blog.csdn.net/weixin_40350981/article/details/109570137