Mapper代理
测试类中的sql语句的id硬编码问题:
启用Mapper代理方式:
- 建立与sql映射文件同路径同名的Mapper接口(如:接口建立在分层式的com.it.Mapp中那么已经存在于resources中的sql映射文件就需要同样放在同样的 路径下:在resources下建一个包
com/it/Mapp
,注意:用的是/
,然后在电脑中找到项目工程的target点进入发现接口文件和sql映射文件在一起了)- sql映射文件中的namespace改成接口的全限定名
- Mapper接口中定义方法名与sql映射文件的id相同,返回类型一致
- 测试类中用SqlSession的对象sqlSession.getMapper(Mapper接口.class);
Mapper接口:(方法名为Mapper映射文件中的id,返回值为实体类User)
package com.itjh.mapp;
import com.itjh.pojo.User;
import java.util.List;
public interface UserMapper {
List<User> selectall();
}
Mapper映射文件(xml后缀的文件):id:对应Mapper接口中的selectall方法;namespace:Mapper接口全限定名;resultType为返回结果类型:User类的全限定名
<?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.itjh.mapp.UserMapper">
<!--resultType:返回结果的类型,比如User类-->
<select id="selectall" resultType="com.itjh.pojo.User">
select * from farther;
</select>
</mapper>
User类:接收数据库中数据进来并且提供打印(toString()方法)
{
String name ;
Integer age ;
String gander ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGander() {
return gander;
}
public void setGander(String gander) {
this.gander = gander;
}
@Override
public String toString() {
return "com.itjh.pojo.User{" +
"name='" + name + '\'' +
", age=" + age +
", gander='" + gander + '\'' +
'}';
}
}
mybatis:加载mapper文件换成扫描mapper文件所属的包
<?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.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///parent"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--加载sql映射文件-->
<mappers>
<!-- <mapper resource="com.itjh.mapp"/>-->
<package name="com.itjh.mapp"/>
</mappers>
</configuration>
(重点):
测试类中改变的那两行:得到一个接口对象,再调用接口的方法,而这个方法名又和sql映射文件里的id相同,且俩文件都在一个路径下,所以接口中的这个方法会自动的进入sql映射文件,再通过映射文件得到集合,而接口中的方法的返回类型也是集合,于是就自然把得到的集合返回,测试类这边在用一个集合收住,最后打印
@Test
public void show() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession=sqlSessionFactory.openSession();
//获得UserMapper接口的代理对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
//返回一个集合
List<User> list=userMapper.selectall();
System.out.println(list);
}
别名1
有时候当你的实体类中的settter()方法(如setiName(),取set后面的部分,即:Name)与数据库中的你想要的字段名对不上号时,就会显示null
等 (String 类型的就显示null)
[Employee{iName=null, age=45, gander='男'}
瞅一眼实体类:数据库的为name,而当前实体类的就是iName
package com.itjh.pojo;
public class Employee {
String iName;
Integer age;
String gander;
public String getYouName() {
return iName;
}
public void setiName(String name) {
this.iName = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGander() {
return gander;
}
public void setGander(String gander) {
this.gander = gander;
}
@Override
public String toString() {
return "Employee{" +
"iName='" + iName + '\'' +
", age=" + age +
", gander='" + gander + '\'' +
'}';
}
}
那么就在Mapper文件中进行别名的配置 ###:
直接在sql语句中搞一搞:令数据库的name等于iName:name as iName
(每一次调用都要写这么一大段,贼麻烦)
<mapper namespace="com.itjh.mapp.EmployeeMapper">
<select id="selectall" resultType="com.itjh.pojo.Employee">
select name as iName ,age,gander
from farther
</select>
</mapper>
- 加鲁鲁进化:利用sql标签,将一部分sql语句写在里面(很麻烦,要写很多sql语句)
<mapper namespace="com.itjh.mapp.EmployeeMapper">
<sql id="employee_column">
name as iName ,age,gander
</sql>
<select id="selectall" resultType="com.itjh.pojo.Employee">
select
<include refid="employee_column"></include>
from farther
</select>
</mapper>
当然把sql语句全部写进标签也可以
- 加鲁鲁超级进化——无敌霸王龙:利用resultMap标签,记得把
resultType
改成resultMap
,再把resultMap标签的id写进去(比之上俩方便很多)
<mapper namespace="com.itjh.mapp.EmployeeMapper">
<resultMap id="employee" type="com.itjh.pojo.Employee">
<result property="iName" column="name"></result>
</resultMap>
<select id="selectall" resultMap="employee">
select
*
from farther
</select>
</mapper>
别名2
在Mapper配置文件中:resultType参数为实体类全限定名,但比较麻烦
<select id="selectall" resultType="com.itjh.pojo.Dao">
select * from bank where id = #{id}
</select>
解决办法:在mybatis配置文件中添加别名:扫描实体类所在的包,当映射文件的resultType填写参数时,写入类的小写类名就行(因为扫描,所以类名小写自动变成了可以用的别名)
<typeAliases>
<package name="com.itjh.pojo"/>
</typeAliases>
Mapper映射文件:
<select id="selectall" resultType="dao">
select * from bank where id = #{id}
</select>