一、为什么使用动态代理mapper实现类
在第一节中我们是通过接口->实现类->mapper.xml实现数据库语句与mybatis的整合,xml中的sql statement 硬编码到实现类的java代码中,在这里我们可不可以不通过接口实现类的硬编码方式进行整合,而是用mybatis提供的接口动态代理来实现。
未修改之前的测试类:
@Before
public void before() throws IOException {
//1、读取mybatis全局配置文件并获取文件输入流
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//2、通过输入流获取sqlsession的代理工厂bean
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3、通过代理工厂bean获取sqlSessions
sqlSession = sqlSessionFactory.openSession();
//4、将sqlsession加载进userdao实例对象中去
studentDao = new StudentDaoImpl(sqlSession);
}
修改之后的测试类:
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sessionFactory.openSession(true);
//动态获取mapper操作对象
userMapper = sqlSession.getMapper(UserMapper.class);
}
二、完整的例子
2.1、创建user数据库及其实体类
1、创建数据库
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(3) NOT NULL AUTO_INCREMENT,
`user_name` varchar(15) COLLATE utf8_bin NOT NULL,
`telephone` varchar(15) COLLATE utf8_bin NOT NULL,
`imax_email` varchar(15) COLLATE utf8_bin NOT NULL,
`sex` varchar(2) COLLATE utf8_bin NOT NULL,
`age` int(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
2、创建User实体类
private int id;
private String username;
private String iMaxEmail;
private String telephone;
private String sex;
private int age;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", iMaxEmail='" + iMaxEmail + '\'' +
", telephone='" + telephone + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getiMaxEmail() {
return iMaxEmail;
}
public void setiMaxEmail(String iMaxEmail) {
this.iMaxEmail = iMaxEmail;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
2.2、创建UserMapper接口类
User selectOneUser(int id);
List<User> selectAll();
List<User> selectUserBySex(String sex);
void insertUser(User user);
void deleteUserById(int id);
void updateUser(User user);
//动态sql语句实现模糊查询
List<User> selectManUserByName(@Param("username") String username);
List<User> selectUserByArgs(String username,int age);
List<User> selectUsersByArgs(String sex,String username);
User selectUser(int id);
2.3、配置UserMapper.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.achuan.demo.dao.UserMapper">
<resultMap id="user" type="com.achuan.demo.entity.User">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="user_name" property="username" jdbcType="VARCHAR"/>
<result column="telephone" property="telephone" jdbcType="VARCHAR"/>
<result column="imax_email" property="iMaxEmail" jdbcType="VARCHAR"/>
<result column="sex" property="sex" jdbcType="VARCHAR"/>
<result column="age" property="age" jdbcType="INTEGER"/>
</resultMap>
<select id="selectOneUser" parameterType="int" resultMap="user">
select * from user where id = #{id}
</select>
<select id="selectUser" parameterType="int" resultMap="user">
select * from user where id = #{id}
</select>
<select id="selectAll" resultMap="user">
select * from user;
</select>
<select id="selectUserBySex" parameterType="string" resultMap="user">
select * from user where sex = #{sex};
</select>
<!--useGeneratedKeys:开启主键回写
keyColumn:指定数据库的主键
keyProperty:主键对应的pojo属性名-->
<!--flushCache (可选配置,默认配置为true)
将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句)-->
<insert id="insertUser" parameterType="com.achuan.demo.entity.User" useGeneratedKeys="true" keyColumn="id" keyProperty="id" flushCache="false">
insert into user(
id,
user_name,
sex,
imax_email,
telephone,
age
)values (
null,
#{username},
#{sex},
#{iMaxEmail},
#{telephone},
#{age}
);
</insert>
<update id="updateUser" parameterType="com.achuan.demo.entity.User" flushCache="false">
update user
<trim prefix="set" suffixOverrides=",">
<if test="username!=null">user_name = #{username},</if>
<if test="iMaxEmail!=null">imax_email = #{iMaxEmail},</if>
<if test="sex!=null">sex = #{sex},</if>
<if test="telephone!=null">telephone = #{telephone},</if>
<if test="age!=null">age = #{age}</if>
</trim>
where id = #{id};
</update>
<delete id="deleteUserById" parameterType="int" flushCache="false">
delete from user where id = #{id};
</delete>
<select id="selectManUserByName" parameterType="string" resultMap="user">
select * from user where sex = "男"
<if test="username != null and username.trim() != ''">
and user_name = #{username}
</if>
</select>
<select id="selectUserByArgs" resultMap="user">
select * from user
<choose>
<when test="param1!=null and param1.trim()!=''">
where user_name = #{param1}
</when>
<when test="param2 < 40">
where age = #{param2}
</when>
<otherwise>
where user_name = "张益达"
</otherwise>
</choose>
</select>
<!--#{}是占位符,可以防止sql语句侵入,与参数名字无关,'${}'是取出参数参数值信息,不能防止sql语句侵入-->
<select id="selectUsersByArgs" resultMap="user">
select * from user
<where>
<if test="param1 != null and param1.trim() != ''">
and sex like #{param1}
</if>
<if test="param2 != null and param2.trim() != ''">
and user_name like #{param2}
</if>
</where>
</select>
注意:namespace的值必须与制定类的绝对路径相同,数据库增删查改标签的方法必须对应namespace映射mapper接口中的方法名相对应。
2.4、设置测试类
UserMapper userMapper;
SqlSession sqlSession;
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sessionFactory.openSession(true);
//动态获取mapper操作对象
userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void test01(){
User user = new User();
user.setiMaxEmail("[email protected]");
user.setSex("男");
user.setAge(45);
user.setTelephone("431231542645");
user.setUsername("张益达");
userMapper.insertUser(user);
// sqlSession.commit();
}
@Test
public void test02(){
User user = new User();
user.setId(7);
user.setiMaxEmail("[email protected]");
user.setSex("女");
user.setAge(45);
user.setTelephone("52627");
user.setUsername("胡一菲");
userMapper.updateUser(user);
}
@Test
public void test03(){
userMapper.deleteUserById(8);
}
@Test
public void test04(){
List<User> userList = userMapper.selectAll();
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void test05(){
User user = userMapper.selectOneUser(7);
System.out.println(user);
}
2.5、test05测试运行结果