学习mybatis3的第三天

学习mybatis3的第三天

1、学习全局配置文件的properties标签

properties标签。


在这里插入图片描述
mybatis可以使用properties来引入外部properties配置文件的内容。
原先我们的全局配置文件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></properties>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="EmployeeMapper.xml"/>
    </mappers>
</configuration>

其中很多的参数都是写死的。

properties标签里面由两个属性
第一个是:resources。
在这里插入图片描述
另外一个是:URL。
在这里插入图片描述
这两个属性都是用来引入资源的。不过区别是:
resource:引入类路径下的资源
URL:引入网络/磁盘路径下的资源

1、现在准备在
在这里插入图片描述
类路径下的conf目录下,新建一个dbconfig.properties
在这里插入图片描述
2、编辑dbconfig.properties

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

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>
    
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="EmployeeMapper.xml"/>
    </mappers>
</configuration>

现在:

<?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="dbconfig.properties"></properties>
    <environments default="development">
        <environment id="development">
            <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>
    </environments>
    <mappers>
        <mapper resource="EmployeeMapper.xml"/>
    </mappers>
</configuration>

因为:dbconfig.properties这个配置文件是在类路径下的。所以,应该使用
resource属性,而且直接在类路径下,没有在任何包下,所以直接写文件名。如果在某个包下,就写成:xx/xx/dbconfig.properties

<properties resource="dbconfig.properties"></properties>

再使用${}来取出配置文件的参数值。

<property name="driver" value="${jdbc.driver}"/>

4、测试:
在这里插入图片描述

2、学习全局配置文件的settings标签

这个标签非常重要!!!包含很多设置项。
清楚每个设置项的功能。
映射下划线变成驼峰命名。
设置项:mapUnderscoreToCamelCase.
是否开启自动驼峰命名规则,默认是fasle,不开启。
这就是为什么:
当时java bean属性名lastName,但是数据库的字段名是last_name的时候,查不出来这个数据的值(null)
之后,select last_name lastName from …

现在准备加上settings标签:

<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>

在这里插入图片描述

这时,就算是sql映射文件里面的sql是secle *
在这里插入图片描述
且java bean属性名lastName,但是数据库的字段名是last_name
这个属性的值还是可以查出来,不是Null
注意:
在这里插入图片描述
settings标签一定要在properties下面。
否则会报错:
Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 26; columnNumber: 17; 元素类型为 “configuration” 的内容必须匹配 “(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)”。

mapUnderscoreToCamelCase:这个设置项可以规范数据库的字段名和java bean的字段名。

3、学习第三个标签:typeAliases

别名处理器。
在这里插入图片描述
sql映射文件里面的返回值类型填写java bean对象的全类名,太长,使用别名。
1、修改mybatis-config.xml:

<configuration>
	<typeAliases>
	       <typeAlias type="com.rtl.mybatis.bean.Employee"></typeAlias>
	</typeAliases>
    </configuration>

2、修改sql映射文件:

<select id="getEmpById" resultType="employee">
        select * from tbl_employee where id = #{id}
    </select>

默认别名就是java bean类的小写。
Employee - > employee
当然,可以不使用默认的employee别名,自己指定啊。

全局配置文件:

<typeAliases>
        <typeAlias type="com.rtl.mybatis.bean.Employee" alias="emp"></typeAlias>
    </typeAliases>

sql映射配置文件:

 <select id="getEmpById" resultType="emp">
        select * from tbl_employee where id = #{id}
    </select>

批量为某个包下的所有类取别名。
只能使用默认别名。
全局配置文件

<configuration>
	<typeAliases>
        <package name="com.rtl.mybatis.bean"/>
    </typeAliases>
    </configuration>

sql映射文件:

<select id="getEmpById" resultType="employee">
        select * from tbl_employee where id = #{id}
    </select>

注意:别名不区分大小写。

 <select id="getEmpById" resultType="Employee">
        select * from tbl_employee where id = #{id}
    </select>

其实:最好还是就写全类名比较好

不管
不管怎么样都不会出错。

4、学习第4个标签:typeHandlers

它是实现,自定义类型处理器。架起java数据类型和mysql数据类型的桥梁。
例如:如何把java的String变量保存到mysql兼容的carchar类型。
后面会详细讲解。

5、学习第5个标签:plugins

拦截sql语句执行的核心步骤。
利用插件机制进行拦截。
拦截其实就是动态代理(后面会讲)
插件可以拦截以下四大对象的某些方法。
混个眼熟:四大对象:
1、Executor
2、ParameterHandler
3、ResultSetHandler
4、StatementHandler,sql语句的处理器
插件可以拦截到Executor对象的某些方法。

6、学习第6个标签:environments

enviroments:说明mybatis可以配置多种环境。
environment:配置一个具体的环境信息。每一个environment都必须要有transactionManager和dataSource

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

environment有一个属性id
id代表当前环境的唯一标识。
比如:测试和开发用的环境不同。
开发人员使用本地的数据库环境。
测试人员使用专门的测试数据库环境。

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

environments配置了多个环境,一个是开发的,一个是测试的。
通过修改:
或者:

每一个environment都必须要有transactionManager和dataSource
先看看transactionManager.

<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
        </environment>
</environments>

transactionManager有两种取值,分别是:JDBC和MANAGED
JDBC:使用JDBC提交回滚。使用JdbcTransactionFactory.class控制事务管理
MANAGED:使用ManagedTransactionFactory.class控制事务管理。

在这个类里面:
org.apache.ibatis.session.Configuration

public Configuration() {
    typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
    typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
    }

JDBC是别名,JdbcTransactionFactory.class
MANAGED:ManagedTransactionFactory.class

Spring做事务控制才是最终的解决方案。

每一个environment都必须要有transactionManager和dataSource
再看看dataSource.

<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
       </environment>
</environments>

数据源的类型有几种呢?
POOLED、UNPOOLED、JNDI
在这个类里面:
org.apache.ibatis.session.Configuration
写了别名:

 public Configuration() {
    typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
    typeAliasR## 标题egistry.registerAlias("MANAGED", ManagedTransactionFactory.class);

    typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
    typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
    typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);

7、学习第7个标签:databaseleProvider

mybatis可以执行不同的sql,根据不同的DB厂商。
这个标签,是支持myabatis的一致性的体现。

8、学习第八个标签:mappers

将sql映射注册到全局配置文件中。

<mappers>
        <mapper resource="EmployeeMapper.xml"/>
    </mappers>

resource:引用类路径下的资源。
URL:引用网络/磁盘路径下的资源。

学完了全局配置文件mybatis-config.xml的知识,开始学习sql映射的配置文件xxxMapper.xml

sql映射的配置文件xxxMapper.xml很重要。这里面有sql语句。
这里面的知识点很重要,这个sql映射的配置文件是整个mybatis框架的魅力所在。

1、在EmployeeMapper接口里面添加上更多的抽象方法。
原先的接口:

package com.rtl.mybatis.dao;

import com.rtl.mybatis.bean.Employee;

public interface EmployeeMapper {
    public Employee getEmpById(Integer id);
}

现在的接口:

package com.rtl.mybatis.dao;

import com.rtl.mybatis.bean.Employee;

public interface EmployeeMapper {
    public Employee getEmpById(Integer id);
    
    public void addEmp(Employee employee);
    
    public void updateEmp(Employee employee);
    
    public void deleteEmpById(Integer id);
}

2、修改sql映射文件,为接口的这几个方法添加定义。
原先的EmployeeMapper.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.rtl.mybatis.dao.EmployeeMapper">
    <select id="getEmpById" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id}
    </select>
</mapper>

现在的EmployeeMapper.xml::
注意:EmployeeMapper.xml里面的sql不写分号。
在这里插入图片描述
部分,补充的insert语句。
注意:last_name和lastName。
对应接口的添加方法:

public void addEmp(Employee employee);
 <insert id="addEmp">
        insert into tbl_employee(last_name,gender,email) values(#{lastName},#{gender},#{email})
    </insert>

我们发现在接口的方法里面有参数,但是我们在写insert sql语句的时候,并没有写参数,说明可以省略。
下面是不省略的写法。

 <insert id="addEmp" >
        insert into tbl_employee(last_name,gender,email) values(#{lastName},#{gender},#{email})
    </insert>

更新方法:
接口的方法:

public void updateEmp(Employee employee);

xml的sql写法:

<update id="updateEmp">
        update tbl_employee set last_name=#{lastName},email=#{email},gender=#{gender} where id=#{id}
    </update>

删除方法:
接口里面的删除方法:

public void deleteEmpById(Integer id);

xml映射配置文件的sql:

<delete id="deleteEmpById">
        delete from tbl_employee where id=#{id}
    </delete>

全部的sql映射文件EmployeeMapper.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.rtl.mybatis.dao.EmployeeMapper">
    <select id="getEmpById" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id}
    </select>

    <insert id="addEmp" parameterType="com.rtl.mybatis.bean.Employee">
        insert into tbl_employee(last_name,gender,email) values(#{lastName},#{gender},#{email})
    </insert>

    <update id="updateEmp">
        update tbl_employee set last_name=#{lastName},email=#{email},gender=#{gender} where id=#{id}
    </update>

    <delete id="deleteEmpById">
        delete from tbl_employee where id=#{id}
    </delete>
</mapper>

对应的接口:

package com.rtl.mybatis.dao;

import com.rtl.mybatis.bean.Employee;

public interface EmployeeMapper {
    public Employee getEmpById(Integer id);

    public void addEmp(Employee employee);

    public void updateEmp(Employee employee);

    public void deleteEmpById(Integer id);
}


测试类的编写:
下面这种方式获取到的SqlSession openSession不会自动提交数据。
必须要手动提交才会生效。(java bean添加上有参无参构造器。)

        SqlSession openSession = sqlSessionFactory.openSession();
        openSession.commit();

另外需要注意一点:
如果是以下的方式来写的话,就不需要手动提交了。

 SqlSession openSession = sqlSessionFactory.openSession(true);
 openSession.commit();下面这句话就不要。

全部测试类:(测试添加)

 @Test
    public void test3() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            Employee employee = new Employee(null, "jerry", "jerry@qq.com", "1");
            mapper.addEmp(employee);
            openSession.commit();
        }finally {
            openSession.close();
        }
    }

在这里插入图片描述

测试修改:
要把1号员工的信息也改成jerry的信息。
修改前的1号员工的信息:
在这里插入图片描述修改之后:

 Employee employee = new Employee(1, "jerry", "jerry@wangyiyun.com", "0");

在这里插入图片描述

 //测试修改
    @Test
    public void test4() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            Employee employee = new Employee(1, "jerry", "jerry@wangyiyun.com", "0");
            mapper.updateEmp(employee);
            openSession.commit();
        }finally {`在这里插入代码片`
            openSession.close();
        }
    }

测试删除:
希望把2号员工给删除掉。
在这里插入图片描述
测试类:

//测试删除
    @Test
    public void test5() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            mapper.deleteEmpById(2);
            openSession.commit();
        }finally {
            openSession.close();
        }
    }

在这里插入图片描述
mybatis允许增删改直接定义一下类型返回值:
Integer,Long,Boolean
如果是查询的话,是可以定义返回值类型的。

 <select id="getEmpById" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id}
 </select>
接口方法:
public Employee getEmpById(Integer id);

但是如果是增删改的话:

<insert id="addEmp" parameterType="com.rtl.mybatis.bean.Employee">
        insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender})
</insert>

接口方法:
public Boolean addEmp(Employee employee);

测试类:

 @Test
    public void test3() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            Employee employee = new Employee(null, "tom", "tom@qq.com", "1");
            Boolean addEmp = mapper.addEmp(employee);
            System.out.println("添加2号员工是否成功:"+addEmp);
            openSession.commit();
        }finally {
            openSession.close();
        }
    }

在这里插入图片描述

添加前:
在这里插入图片描述
现在准备添加2号员工。
Employee employee = new Employee(null, “tom”, “tom@qq.com”, “1”);
在这里插入图片描述
在这里插入图片描述

mybatis获取自增主键的值:

现在表里面有两条数据,主键id的值=2
在这里插入图片描述
我们再添加一条数据,id会变为3,我们如何获取这个3呢??
useGeneratedKeys="true"使用自增主键获取主键值策略。
keyProperty="id"指定mybatis获取到的主键值应该将这个值赋值给javaBean的哪个属性。
1、修改sql映射文件EmployeeMapper.xml
之前的:

 <insert id="addEmp" parameterType="com.rtl.mybatis.bean.Employee" >
        insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender})
    </insert>

现在的:

<insert id="addEmp" parameterType="com.rtl.mybatis.bean.Employee" useGeneratedKeys="true" keyProperty="id">
        insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender})
</insert>

测试类:
之前的:

//测试添加
    @Test
    public void test3() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession openSession = sqlSessionFactory.openSession(true);
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            Employee employee = new Employee(null, "jack", "jack@qq.com", "1");
            Boolean addEmp = mapper.addEmp(employee);
            System.out.println("添加3号员工是否成功:"+addEmp);
            openSession.commit();
        }finally {
            openSession.close();
        }

现在的:

//测试添加
    @Test
    public void test3() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession openSession = sqlSessionFactory.openSession(true);
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            Employee employee = new Employee(null, "jack", "jack@qq.com", "1");
            Boolean addEmp = mapper.addEmp(employee);
            //这句话一定要放在addEmp()执行完之后。
            Integer id = employee.getId();
            System.out.println("准备添加的员工的id号:"+id);
            System.out.println("添加4号员工是否成功:"+addEmp);
            openSession.commit();
        }finally {
            openSession.close();
        }

在这里插入图片描述
一定要在执行添加完毕之后,再去获取它的id,否则还是null,即使再DB中已经执行了添加操作。
在这里插入图片描述
在这里插入图片描述

研究mybatis的参数处理。

1、单个参数:

select * from tbl_employee where id = #{id}

使用#{}来进行传递。

2、多个参数

1、在接口EmployeeMapper里面再加入一个方法。
之前的EmployeeMapper:

package com.rtl.mybatis.dao;

import com.rtl.mybatis.bean.Employee;

public interface EmployeeMapper {
    public Employee getEmpById(Integer id);

    public Boolean addEmp(Employee employee);

    public void updateEmp(Employee employee);

    public void deleteEmpById(Integer id);
}

现在的:接口
EmployeeMapper

package com.rtl.mybatis.dao;

import com.rtl.mybatis.bean.Employee;

public interface EmployeeMapper {
    public Employee getEmpByIdAndLastName(Integer id,String lastName);

    public Employee getEmpById(Integer id);

    public Boolean addEmp(Employee employee);

    public void updateEmp(Employee employee);

    public void deleteEmpById(Integer id);
}

多了一个两个参数的方法。
在这里插入图片描述
2、对应的修改EmployeeMapper.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.rtl.mybatis.dao.EmployeeMapper">
    <select id="getEmpById" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id}
    </select>

    <insert id="addEmp" parameterType="com.rtl.mybatis.bean.Employee" useGeneratedKeys="true" keyProperty="id">
        insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender})
    </insert>

    <update id="updateEmp">
        update tbl_employee set last_name=#{lastName},email=#{email},gender=#{gender} where id=#{id}
    </update>

    <delete id="deleteEmpById">
        delete from tbl_employee where id=#{id}
    </delete>
</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.rtl.mybatis.dao.EmployeeMapper">

    <select id="getEmpByIdAndLastName" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id} and last_name=#{lastName}
    </select>

    <select id="getEmpById" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id}
    </select>

    <insert id="addEmp" parameterType="com.rtl.mybatis.bean.Employee" useGeneratedKeys="true" keyProperty="id">
        insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender})
    </insert>

    <update id="updateEmp">
        update tbl_employee set last_name=#{lastName},email=#{email},gender=#{gender} where id=#{id}
    </update>

    <delete id="deleteEmpById">
        delete from tbl_employee where id=#{id}
    </delete>
</mapper>

在这里插入图片描述
测试类:

//测试查询(按照id和lastName)
    @Test
    public void test6() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            Employee employee = mapper.getEmpByIdAndLastName(1, "jerry");
            System.out.println(employee);
            openSession.commit();
        }finally {
            openSession.close();
        }
    }

一运行发现报错。

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [0, 1, param1, param2]
### Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [0, 1, param1, param2]

分析异常出现的原因:
方法:

public interface EmployeeMapper {
    public Employee getEmpByIdAndLastName(Integer id,String lastName);
}

取值的时候:在EmployeeMapper.xml里面:

select * from tbl_employee where id = #{id} and last_name=#{lastName}

在这里插入图片描述
在EmployeeMapper.xml里面,当你写select标签的时候,也就是查询的标签,必须写id和resultType
其他的增删改就没有必要。
解决办法:
在接口的方法里面需要传递多个参数的时候,多个参数会被封装成一个map
在这里插入图片描述

这个map的key是0,1,2…
这个map的value是传入的参数的值。( Employee employee = mapper.getEmpByIdAndLastName(1, “jerry”);)
所以,我们在EmployeeMapper.xml里面,需要这样写:
之前的写法:

<select id="getEmpByIdAndLastName" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id} and last_name=#{lastName}
</select>

现在的写法:

<select id="getEmpByIdAndLastName" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id = #{0} and last_name=#{1}
</select>

在这里插入图片描述

但是,这样很难看,做不到见名知意。
最终版:
接口这样写:

public interface EmployeeMapper {
    public Employee getEmpByIdAndLastName(@Param("id") Integer id,@Param("lastName") String lastName);

    public Employee getEmpById(Integer id);

    public Boolean addEmp(Employee employee);

    public void updateEmp(Employee employee);

    public void deleteEmpById(Integer id);
}

在这里插入图片描述
EmployeeMapper.xml这样写:(不写0和1)

<select id="getEmpByIdAndLastName" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id} and last_name=#{lastName}
</select>

在这里插入图片描述
在这里插入图片描述
我们在mapper.xml里面写sql的时候,既可以写#{},也可以写${}
区别???
select * from tab where id = ${id} and last_name=#{lastName}

select * from tab where id = 2 and last_name=?
说明:${}是将传过来的参数值,直接放进sql里面,具有sql注入的问题。会有安全问题。
但是#{}是先以占位符的形式存在。相当于PrepareedStatement。
大多数情况,我们使用#{}。

之前做的查询操作,返回的都是一个Employee对象,现在如果返回的是List呢???

1、在接口里面加一个方法,实现模糊查询,得到的结果是一个List集合
查询名字里面包含j字母的!

package com.rtl.mybatis.dao;

import com.rtl.mybatis.bean.Employee;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {
    public List<Employee> getEmpsByLastNameLike(String lastName);

    public Employee getEmpByIdAndLastName(@Param("id") Integer id,@Param("lastName") String lastName);

    public Employee getEmpById(Integer id);

    public Boolean addEmp(Employee employee);

    public void updateEmp(Employee employee);

    public void deleteEmpById(Integer id);
}

在这里插入图片描述
2、修改EmployeeMapper.xml
注意:返回值类型必须写这个List里面的数据类型。所以还是Employee,千万别写List哈。

<select id="getEmpsByLastNameLike" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where last_name like #{lastName}
</select>

在这里插入图片描述
测试类:

//测试查询:(模糊查询,返回值是多个元素)
    @Test
    public void test7() throws IOException {
        //(16,17,18行)1、根据这个全局的mybatis-config.xml配置文件生成一个SqlSessionFactory对象。
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2、根据SqlSessionFactory对象获取sqlSession实例,整个实例可以执行已经映射的sql语句。
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            List<Employee> emps = mapper.getEmpsByLastNameLike("%j%");
            for (Employee emp : emps) {
                System.out.println(emp);
            }
        }finally {
            openSession.close();
        }
    }

数据库已经存在的数据:
在这里插入图片描述

在这里插入图片描述

查询结果本来返回Employee,但是业务要求,返回的是Map,key是这个javaBean的属性名,value是这个javaBean的属性值。

返回一条记录的map,key就是列名,value就是对应的值。

在这里插入图片描述

晚安:好梦!睡觉时间1:17

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值