Mybatis第二谈,深入学习Mybatis(Mybatis的动态代理、深入理解Mybatis的参数、多个参数传值)

1、mybatis的动态代理

原理:

  • mybatis根据dao方法的调用,获取执行sql语句的信息。
  • mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建这个类的对象
  • 完成SqlSession调用调用方法,访问数据库
  • List students = studnetDao.selectStudent();调用

具体实现:

  1. dao对象类型是 studnetDao,全限定名称是:com.yky.Dao.StudnetDao 全限定名称和 中的 namespace一致
  2. 方法名称:selectStudent,这个方法就是mapper文件中的id值
  3. 通过dao方法的返回值也可以确定MyBatis要调用的SqlSession的方法
    返回值为List集合的是select方法
    如果返回值是int类型的数据,看mapper文件中的标签是 就会调用相应的方法

动态代理使用mybatis

	用动态代理使用mybatis过程:
        1、获取SqlSession接口
        2、使用SqlSession的getMapper();方法来在mybatis内部创建StudentDao对象
        3、使用这个对象调用方法

2、深入理解参数

从Java代码中把数据传入mapper文件sql语句中

1. parameterType:

  • 写在mapper文件中的一 个属性。表示dao接口中方法的参数数据类型
  • 例如:studentDao接口
    public student selectstudentById(Interger id)值是java数据类型的全限定名称或者别名(文档p15)
  • 可以省略(mybatis通过反射获取到接口参数类型)
<select id="selectStudentById" parameterType="java.lang.Integer"resultType="com.yky.domain.Student">
select id,name,email,age from student where id=#{id}
</select>

2. 一个简单类型的参数:

  • 简单类型:Java的基础数据类型和String都叫简单类型

  • 在mapper文件获取简单类型的一个参数的值,使用#{任意字符} —>占位符

3. mybatis 封装 jdbc

由mybatis执行下面的代码:

  1. mybatis创建Connection,PreparedStatement对象
String sql = "select id,name,email,age from student where id = ?";
PreparedStatement pst = conn.prepqredStatement(sql);
pat.setInt(1,1001);
  1. 执行sql封装resultType = "com.yky.domain.Student"这个对象;
ResultSet rs = ps.executeQuery();
	Student student = null;
	while(rs.next){
		//从数据库取表的一行数据,存到一个Java对象属性中
		student = new Student();
		student.setId();}
	return student;	 

4.多个参数传值

1、命名参数(推荐)

  1. xml文件中的sql语句代码:
<select id="selectStudentMultiParam" resultType="com.yky.domain.Student">
	select id,name,email,age from student where age = #{studentage} or name=#{studentname}<!--占位符中填写你对参数的命名-->
</select>
  1. dao接口中的多个参数的方法:
//命名传参,多个参数
    List<Student> selectStudentMultiParam(@Param("studentname") String name,
                                          @Param("studentage")

2、对象传参

Java的属性值就是sql需要的参数值,每一个属性就是一个参数

  • 格式:#{property,JavaType = Java中数据类型名,jdbcType= 数据类型名称}

  • JavaType、jdbcType的类型能够检测出来,一般不需要设置 。常用格式 :#{property}

  • Student.xml文件中select语句的写法:

<!--没有省略-->
<!--<select id="selectStudentMultiObjdct" resultType="com.yky.domain.Student">-->
	<!--select id,name,email,age from student where name = #{bakname,javaType = java.lang.String,jdbcType = VARCHAR} or-->
<!-- age = #{bakage,javaType = java.lang.Integer,jdbcType = INTEGER}-->
<!-- </select>-->
<!--省略-->
<select id="selectStudentMultiObjdct"resultType="com.yky.domain.Student">
	select id,name,email,age from student where name = #{bakname} or age = #{bakage}
</select>
  • 新建一个传参的类(传参的类没有限制,也可以使用Student类自身传参
    这个类就是sql语句传参的类型
public class StudentBak {
	    private String bakname;
	    private Integer bakage
  • 测试:
//多个参数,使用Java对象
@Test
public void selectStudentMurilObject(){
	SqlSession sqlSession = MybatisUtils.getSqlSession();
	StudnetDao studnetDao = sqlSession.getMapper(StudnetDao.class);
	StudentBak studentBak = new StudentBak();
	studentBak.setBakname("lk");
	studentBak.setBakage(18);
	List<Student> students = studnetDao.selectStudentMultiObjdct(studentBak);
	students.forEach(student -> System.out.println(student));
}

3、按位置传参

  • Student.xml文件中select语句的写法:
<!--多个参数,按位置传参-->
<select id="selectStudentMultiPosition" resultType="com.yky.domain.Student">
     select id,name,email,age from student where name =#{arg0} or age = #{arg1};
</select>
//多个参数,按位置传参
List<Student> selectStudentMultiPosition(String name,Integer age);

4、Map传参

  • 语法:#{map的key}

  • Student.xml文件中select语句的写法:


			
<!--多个参数,map传参-->
<select id="selectStudentMultiByMap"resultType="com.yky.domain.Student">
	select id,name,email,age from student where name =#{mapname} or age = #{mapage};
</select>
/多个参数,map传参
List<Student> selectStudentMultiByMap(Map<String,Object> map);
测试:
//多个参数,map传参
@Test
public void selectStudentMurilMap(){
		SqlSession sqlSession = MybatisUtils.getSqlSession();
		StudnetDao StudentDao = sqlSession.getMapper(StudnetDao.class);
		Map<String,Object> map = new HashMap<>();
		map.put("mapname","lk");
		map.put("mapage",18);
		List<Student> students = StudentDao.selectStudentMultiByMap(map);
		students.forEach(stu -> System.out.println(stu));
}

5.占位符比较:#和$

  • 由于#{}更安全,所有一般优先考虑使用#{}
  • $可以替换表名列名
    在这里插入图片描述

3、具体代码实现:

1. 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>
    <!--控制mybatis全局行为-->
    <settings>
        <!--打印日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"></setting>
    </settings>

    <!--定义别名:
    typeAlias :可以指定一个类型一个自定义的别名
        1、type:自定义类型的全限定名称
        2、alias:别名
    -->
    <typeAliases>
        <package name="com.mybatis.domain"/>
<!--        <typeAlias type="com.mybatis.domain.Student" alias="Student"></typeAlias>-->
    </typeAliases>

    <!--环境标签 default:表示使用哪一个环境配置-->
    <environments default="development">
        <!--环境标签中的一个环境配置 id:表示这一个环境配置的唯一标识-->
        <environment id="development">
            <!--JDBC的事务提交-->
            <transactionManager type="JDBC"/>
            <!--使用连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=UTC&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="yky"/>
            </dataSource>
        </environment>

    </environments>

    <!--mysql映射文件的位置 一个mysql映射文件一个mapper-->
    <mappers>
        <mapper resource="com/mybatis/Dao/studentDao.xml"/>
    </mappers>

</configuration>
  1. student.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.mybatis.Dao.StudentDao">

    <!--id:唯一标识,推荐调用该语句的方法名 resultType:转换的数据类型,该类型的全限定名称-->
    <!--    <select id="selectStudent" resultType="com.mybatis.domain.Student">-->
    <!--        select id,name,email,age from student order by id-->
    <!--    </select>-->

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

    <select id="selectStudentByStudent" resultType="com.mybatis.domain.Student">
        select id,name,email,age from student where name = #{name} or id = #{id}
    </select>

    <select id="selectStudentByMap" resultType="com.mybatis.domain.Student">
        select id,name,email,age from student where age = #{mapage} or id = #{mapid}
    </select>

    <select id="selectStudentBy" resultType="com.mybatis.domain.Student">
        select id,name,email,age from student where age = #{arg0} or id = #{arg1}
    </select>

    <select id="selectStudentBy$" resultType="com.mybatis.domain.Student">
        select id,name,email,age from student where age =  ${age}
    </select>

    <select id="selectStudentBy$2" resultType="Student">
        select id,name,email,age from student order by ${age}
    </select>

    <!--    <select id="selectCount" resultType="java.lang.Integer">-->
    <!--        select count(*) from student-->
    <!--    </select>-->

    <select id="selectCount" resultType="int">
        select count(*) from student
    </select>
    
    <select id="selectMap" resultType="map">
        select * from student where id = #{id}
    </select>
</mapper>
  1. pom.xml文件的增加代码:
    为了能够在maven编译后获取到student.xml文件加入:
 <resources>
            <resource>
                <directory>src/main/java</directory><!--所在的目录-->
                <includes><!--包括目录下的.properties,.xml文件都会被扫描到-->
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
  1. 测试部分的代码:
     //使用@param传参,并且没有实现类
    @Test
    public void selectStudentByid() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        Student student = studentDao.selectStudentById(1001);
        System.out.println(student);
    }

    //多个参数,使用对象传参
    @Test
    public void selectStudentByStudent() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        Student student1 = new Student();
        student1.setName("lk");
        student1.setId(1001);
        List<Student> studentList = studentDao.selectStudentByStudent(student1);
        studentList.forEach(student -> System.out.println(student));
    }

    //使用map传参
    @Test
    public void selectStudentByMap() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        Map<String, Object> map = new HashMap<>();
        map.put("mapage", 18);
        map.put("mapid", 1001);
        List<Student> studentList = studentDao.selectStudentByMap(map);
        studentList.forEach(student -> System.out.println(student));
    }

    //直接写参数
    @Test
    public void selectStudentBy() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student> studentList = studentDao.selectStudentBy(18, 1001);
        studentList.forEach(student -> System.out.println(student));
    }

    //直接写参数,$拼接字符串
    @Test
    public void selectStudentBy$() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student> studentList = studentDao.selectStudentBy$(18);
        studentList.forEach(student -> System.out.println(student));
    }

    //直接写参数,$代替列名
    @Test
    public void selectStudentByline$() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student> studentList = studentDao.selectStudentBy$2("id");
        studentList.forEach(student -> System.out.println(student));
    }

猜你喜欢

转载自blog.csdn.net/qq_44895397/article/details/106533341