mybatis基础

mybatis是什么?

mybatis是一人持久层框架,mybatis是一个不完全的ORM框架。sql语句需要程序员自己去编写,但是mybatis也有映射(输入参数映射、输出结果映射)。

mybatis入门门槛不高,学习成本低,让程序员把精力放在sql语句上,对sql语句优化非常方便,适用与需求变化较多项目,比如互联网项目。

mybatis框架执行过程:

1、配置mybatis的配置文件,SqlMapConfig.xml(名称不固定)

2、通过配置文件,加载mybatis运行环境,创建SqlSessionFactory会话工厂

SqlSessionFactory在实际使用时按单例方式。

3、通过SqlSessionFactory创建SqlSession

SqlSession是一个面向用户接口(提供操作数据库方法),实现对象是线程不安全的,建议sqlSession应用场合在方法体内。

4、调用sqlSession的方法去操作数据。

如果需要提交事务,需要执行SqlSession的commit()方法。

5、释放资源,关闭SqlSession

 

mybatis开发dao的方法:

1、原始dao 的方法

需要程序员编写dao接口和实现类

需要在dao实现类中注入一个SqlSessionFactory工厂。

 

2、mapper代理开发方法(建议使用)

只需要程序员编写mapper接口(就是dao接口)

程序员在编写mapper.xml(映射文件)和mapper.java需要遵循一个开发规范:

1、mapper.xml中namespace就是mapper.java的类全路径。

2、mapper.xml中statement的id和mapper.java中方法名一致。

3、mapper.xml中statement的parameterType指定输入参数的类型和mapper.java的方法输入 参数类型一致。

4、mapper.xml中statement的resultType指定输出结果的类型和mapper.java的方法返回值类型一致。

 

SqlMapConfig.xml配置文件:可以配置properties属性、别名、mapper加载。

 

输入映射:

parameterType:指定输入参数类型可以简单类型、pojo、hashmap。。

对于综合查询,建议parameterType使用包装的pojo,有利于系统 扩展。

 

输出映射:

resultType:

查询到的列名和resultType指定的pojo的属性名一致,才能映射成功。

reusltMap:

可以通过resultMap 完成一些高级映射。

如果查询到的列名和映射的pojo的属性名不一致时,通过resultMap设置列名和属性名之间的对应关系(映射关系)。可以完成映射。

高级映射:

将关联查询的列映射到一个pojo属性中。(一对一)

将关联查询的列映射到一个List<pojo>中。(一对多)

 

动态sql:(重点)

if判断(掌握)       where         foreach                 sql片段(掌握)

mybatis是一个持久层的框架,是apache下的顶级项目。

mybatis托管到goolecode下,再后来托管到github下(https://github.com/mybatis/mybatis-3/releases)。

mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。

mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射

SqlMapConfig.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>


    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理,事务控制由mybatis-->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池,由mybatis管理-->
            <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="852258" />
            </dataSource>
        </environment>
    </environments>
    <!-- 加载 映射文件 -->
    <mappers>
        <mapper resource="sqlmap/User.xml"/>

        <!--通过resource方法一次加载一个映射文件 -->
        <!-- <mapper resource="mapper/UserMapper.xml"/> -->

        <!-- 通过mapper接口加载单个 映射文件
        遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
        上边规范的前提是:使用的是mapper代理方法
         -->
        <!-- <mapper class="cn.itcast.mybatis.mapper.UserMapper"/> -->

        <!-- 批量加载mapper
        指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载
        遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
        上边规范的前提是:使用的是mapper代理方法
         -->

    </mappers>

</configuration>

 log4j.properties

# Global logging configuration
#在开发环境下日志级别要设置成DeBUG,生产环境设置成info或error
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

根据用户id(主键)查询用户信息

根据用户名称模糊查询用户信息

添加用户

删除 用户

更新用户

 

User.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">

<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 
注意:使用mapper代理方法开发,namespace有特殊重要的作用
-->
<mapper namespace="test">

	<!-- 在 映射文件中配置很多sql语句 -->
	<!-- 需求:通过id查询用户表的记录 -->
	<!-- 通过 select执行数据库查询
	id:标识 映射文件中的 sql
	将sql语句封装到mappedStatement对象中,所以将id称为statement的id
	parameterType:指定输入 参数的类型,这里指定int型 
	#{}表示一个占位符号
	#{id}:其中的id表示接收输入 的参数,参数名称就是id,如果输入 参数是简单类型,#{}中的参数名可以任意,可以value或其它名称
	
	resultType:指定sql输出结果 的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象。
	 -->
	<select id="findUserById" parameterType="int" resultType="com.zhang.mybatis.po.User">
		SELECT * FROM USER WHERE id=#{value}
	</select>
	
	<!-- 根据用户名称模糊查询用户信息,可能返回多条
	resultType:指定就是单条记录所映射的java对象 类型
	${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。
	使用${}拼接sql,引起 sql注入
	${value}:接收输入 参数的内容,如果传入类型是简单类型,${}中只能使用value
	 -->
	<select id="findUserByName" parameterType="java.lang.String" resultType="com.zhang.mybatis.po.User">
		SELECT * FROM USER WHERE username LIKE '%${value}%'
	</select>
	
	<!-- 添加用户 
	parameterType:指定输入 参数类型是pojo(包括 用户信息)
	#{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值
	-->
	<insert id="insertUser" parameterType="com.zhang.mybatis.po.User">
		<!-- 
		将插入数据的主键返回,返回到user对象中
		
		SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用与自增主键
		
		keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
		order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
		resultType:指定SELECT LAST_INSERT_ID()的结果类型
		 -->
		<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
			SELECT LAST_INSERT_ID()
		</selectKey>
		insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
		<!-- 
		使用mysql的uuid()生成主键
		执行过程:
		首先通过uuid()得到主键,将主键设置到user对象的id属性中
		其次在insert执行时,从user对象中取出id属性值
		 -->
		<!--  <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
			SELECT uuid()
		</selectKey>
		insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address}) -->
		
		
	</insert>
	
	<!-- 删除 用户
	根据id删除用户,需要输入 id值
	 -->
	<delete id="deleteUser" parameterType="java.lang.Integer">
		delete from user where id=#{id}
	</delete>
	
	<!-- 根据id更新用户
	分析:
	需要传入用户的id
	需要传入用户的更新信息
	parameterType指定user对象,包括 id和更新信息,注意:id必须存在
	#{id}:从输入 user对象中获取id属性值
	 -->
	<update id="updateUser" parameterType="com.zhang.mybatis.po.User">
		update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} 
		 where id=#{id}
	</update>
	
</mapper>

 

package com.zhang.mybatis.first;

import com.zhang.mybatis.po.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

public class MybatisFirst {
    public long getTime(String pattern) throws ParseException {
        DateFormat format=new SimpleDateFormat("yyyy-MM-dd");
        java.util.Date date=format.parse(pattern);
        return date.getTime();
    }
    public SqlSession getSqlSession() throws IOException {
        //sqlmap配置文件
        String resource="SqlMapConfig.xml";
        InputStream inputStream=Resources.getResourceAsStream(resource);
        //创建会话工厂
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().
                build(inputStream);
        SqlSession sqlSession=sqlSessionFactory.openSession();
        return sqlSession;
    }
    //根据id查询用户信息,得到一条记录结果
    @Test
    public void findUserByIdTest() throws IOException {
        SqlSession sqlSession=getSqlSession();
        User user=sqlSession.selectOne("test.findUserById",1);
        System.out.println(user);
        //释放资源
        sqlSession.close();
    }
    //根据名称模糊查询用户列表
    @Test
    public void findUserByNameTest() throws IOException {
        SqlSession sqlSession=getSqlSession();
        List<User> users=sqlSession.selectList("test.findUserByName","小明");
        System.out.println(users);
        //释放资源
        sqlSession.close();
    }
    @Test
    public void insertUserTest() throws IOException, ParseException {
        SqlSession sqlSession=getSqlSession();
        long l=getTime("1997-5-13");
        User user=new User();
        user.setUsername("王博");
        user.setBirthday(new Date(l));
        user.setSex("男");
        user.setAddress("宝鸡市");
        sqlSession.insert("test.insertUser",user);
        //提交事物
        sqlSession.commit();
        System.out.println(user.getId());
        //释放资源
        sqlSession.close();
    }
    @Test
    public void deleteUser() throws IOException {
        SqlSession sqlSession=getSqlSession();
        sqlSession.delete("test.deleteUser",1);
        sqlSession.commit();
        sqlSession.close();

    }
    @Test
    public void updateUser() throws IOException, ParseException {
        SqlSession sqlSession=getSqlSession();
        User user=new User();
        user.setId(1);
        user.setUsername("张大大");
        user.setBirthday(new Date(getTime("1988-5-21")));
        user.setSex("女");
        user.setAddress("中国");
        sqlSession.update("test.updateUser",user);
        sqlSession.commit();
        sqlSession.close();

    }
}

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。

如果接收简单类型,#{}中可以写成value或其它名称。

#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

 

${}表示一个拼接符号,会引用sql注入,所以不建议使用${}

${}接收输入参数,类型可以是简单类型,pojo、hashmap。

如果接收简单类型,${}中只能写成value。

${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

 

mybatis和hibernate本质区别和应用场景

hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sql,sql语句自动生成了。

对sql语句进行优化、修改比较困难的。

应用场景:

适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。

mybatis:专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。

应用场景:

适用与需求变化较多的项目,比如:互联网项目。

企业进行技术选型,以低成本 高回报作为技术选型的原则,根据项目组的技术力量进行选择。

mybatis开发dao方法

SqlSessionFactoryBuilder

 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory

将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。

在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

SqlSessionFactory

通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。

将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。

SqlSession

SqlSession是一个面向用户(程序员)的接口。

SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)、。

SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。

SqlSession最佳应用场合在方法体内,定义成局部变量使用。

原始dao开发方法(程序员需要写dao接口和dao实现类)

程序员需要写dao接口和dao实现类。

需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession

dao接口 

package com.zhang.mybatis.dao;

import com.zhang.mybatis.po.User;

import java.util.List;

public interface UserDao {
    /**
     * 根据id查询用户
     */
    User findUserById(int id) throws Exception;
    /**
     * 根据用户名或的用户列表
     */
    List<User> findUserByName(String name) throws Exception;
    /**
     * 添加用户
     */
    void insertUser(User user) throws Exception;
    /**
     * 根据id删除用户
     */
    void deleteUser(int id) throws Exception;
}

​​​​​​​dao接口实现类

package com.zhang.mybatis.dao;

import com.zhang.mybatis.po.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;

/**
 * UserDao的实现类
 */
public class UserDaoIm implements UserDao{
    private SqlSessionFactory sqlSessionFactory;
    //注入工厂
    public UserDaoIm(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User findUserById(int id) throws Exception {
        //通过工厂创建SqlSession
        SqlSession sqlSession=sqlSessionFactory.openSession();
        User user=sqlSession.selectOne("test.findUserById",id);
        //关闭会话
        sqlSession.close();
        return user;
    }

    @Override
    public List<User> findUserByName(String name) throws Exception {
        //通过工厂创建SqlSession
        SqlSession sqlSession=sqlSessionFactory.openSession();
        List<User> users=sqlSession.selectList("test.findUserByName",name);
        //关闭会话
        sqlSession.close();
        return users;
    }

    @Override
    public void insertUser(User user) throws Exception {
        //通过工厂创建SqlSession
        SqlSession sqlSession=sqlSessionFactory.openSession();
        sqlSession.selectOne("test.insertUser",user);
        //提交事物
        sqlSession.commit();
        //关闭会话
        sqlSession.close();
    }

    @Override
    public void deleteUser(int id) throws Exception {
        //通过工厂创建SqlSession
        SqlSession sqlSession=sqlSessionFactory.openSession();
        sqlSession.selectOne("test.deleteUser",id);
        //提交事物
        sqlSession.commit();
        //关闭会话
        sqlSession.close();

    }
}

测试代码

package com.zhang.mybatis.dao;
import com.zhang.mybatis.po.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Date;
import java.util.List;


public class UserDaoImTest {
    private SqlSessionFactory sqlSessionFactory;

    public UserDaoImTest() throws IOException {
        String source= "SqlMapConfig.xml";
        InputStream inputStream= Resources.getResourceAsStream(source);
        sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void findUserById() throws Exception {
        UserDao userDao=new UserDaoIm(sqlSessionFactory);
        User user=userDao.findUserById(1);
        System.out.println(user);
    }
    @Test
    public void findUserByName() throws Exception {
        UserDao userDao=new UserDaoIm(sqlSessionFactory);
        List<User> users=userDao.findUserByName("博");
        System.out.println(users);
    }

    @Test
    public void insertUser() throws Exception {
        UserDao userDao=new UserDaoIm(sqlSessionFactory);
        User user=new User();
        user.setUsername("张冯");
        user.setBirthday(new Date(999999999));
        user.setSex("男");
        user.setAddress("商洛");
        userDao.insertUser(user);
    }

    @Test
    public void deleteUser() throws Exception {
        UserDao userDao=new UserDaoIm(sqlSessionFactory);
        userDao.deleteUser(22);
    }
}

​​​​​​​原始 dao开发问题

1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。

 

2、调用sqlsession方法时将statement的id硬编码了      statement的id:"test.deleteUser"

 

3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发

​​​​​​​mapper代理方法(程序员只需要mapper接口(相当 于dao接口))

程序员还需要编写mapper.xml映射文件

程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。

开发规范:

1、在mapper.xml中namespace等于mapper接口地址

2、mapper.java接口中的方法名和mapper.xml中statement的id一致

 

3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。

 

4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

​​​​​​​mapper.java

package com.zhang.mybatis.mapper;

import com.zhang.mybatis.po.User;
import com.zhang.mybatis.po.UserExten;
import com.zhang.mybatis.po.UserQueryVo;

import java.util.List;

/**
 * UserMapper接口
 */
public interface UserMapper {
    /**
     * 用户综合查询
     */
    List<UserExten> findUserList(UserQueryVo queryVo)throws Exception;
    /**
     * 用户综合查询
     */
    int findUserCount(UserQueryVo queryVo)throws Exception;
    /**
     * 用户综合查询
     */
    List<User> findUserByIdResultMap(int id)throws Exception;
    /**
     * 根据id查询用户
     */
    User findUserById(int id) throws Exception;
    /**
     * 根据用户名或的用户列表
     */
    List<User> findUserByName(String name) throws Exception;
    /**
     * 添加用户
     */
    void insertUser(User user) throws Exception;
    /**
     * 根据id删除用户
     */
    void deleteUser(int id) throws Exception;
}

​​​​​​​mapper.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">

<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 
注意:使用mapper代理方法开发,namespace有特殊重要的作用
-->
<mapper namespace="com.zhang.mybatis.mapper.UserMapper">
	<!--定义sql片段-->
	<sql id="queryUser">
		<if test="userExten.sex!=null">
			and user.sex=#{userExten.sex}
		</if>
		<if test="userExten.sex!=null and userExten.username!=null">
			and user.username like '%${userExten.username}%'
		</if>
		<if test="ids!=null">
		<!--使用foreach遍历传入ids
			and (id=1 or id=28 or id=30)
			and IN id(1,28,30)
		-->
			<foreach collection="ids" item="user_id" open="and (" close=")"
					 separator=" or ">
				id=#{user_id}
			</foreach>
		</if>
	</sql>
	<resultMap id="userMap" type="user">
		<id column="id_" property="id"></id>
		<result column="username_" property="username"/>
	</resultMap>
	<!-- 在 映射文件中配置很多sql语句 -->
	<!-- 需求:通过id查询用户表的记录 -->
	<!-- 通过 select执行数据库查询
	id:标识 映射文件中的 sql
	将sql语句封装到mappedStatement对象中,所以将id称为statement的id
	parameterType:指定输入 参数的类型,这里指定int型 
	#{}表示一个占位符号
	#{id}:其中的id表示接收输入 的参数,参数名称就是id,如果输入 参数是简单类型,#{}中的参数名可以任意,可以value或其它名称
	
	resultType:指定sql输出结果 的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象。
	 -->
	<!--where标签两个条件都满足时,会自动去掉第一个and-->
	<select id="findUserList" parameterType="userQueryVo" resultType="UserExten">
		SELECT * FROM User
		<where>
			<include refid="queryUser"></include>
		</where>
	</select>

	<select id="findUserCount" parameterType="userQueryVo" resultType="int">
		SELECT * FROM User
		<where>
			<include refid="queryUser"></include>
		</where>
	</select>

	<select id="findUserById" parameterType="int" resultType="com.zhang.mybatis.po.User">
		SELECT * FROM USER WHERE id=#{value}
	</select>

	<select id="findUserByIdResultMap" parameterType="int" resultMap="userMap">
		SELECT id id_,username username_ FROM USER WHERE id>#{value}
	</select>
	<!-- 根据用户名称模糊查询用户信息,可能返回多条
	resultType:指定就是单条记录所映射的java对象 类型
	${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。
	使用${}拼接sql,引起 sql注入
	${value}:接收输入 参数的内容,如果传入类型是简单类型,${}中只能使用value
	 -->
	<select id="findUserByName" parameterType="java.lang.String" resultType="user">
		SELECT * FROM USER WHERE username LIKE '%${value}%'
	</select>
	
	<!-- 添加用户 
	parameterType:指定输入 参数类型是pojo(包括 用户信息)
	#{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值
	-->
	<insert id="insertUser" parameterType="com.zhang.mybatis.po.User">
		<!-- 
		将插入数据的主键返回,返回到user对象中
		
		SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用与自增主键
		
		keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
		order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
		resultType:指定SELECT LAST_INSERT_ID()的结果类型
		 -->
		<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
			SELECT LAST_INSERT_ID()
		</selectKey>
		insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
		<!-- 
		使用mysql的uuid()生成主键
		执行过程:
		首先通过uuid()得到主键,将主键设置到user对象的id属性中
		其次在insert执行时,从user对象中取出id属性值
		 -->
		<!--  <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
			SELECT uuid()
		</selectKey>
		insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address}) -->
		
		
	</insert>
	
	<!-- 删除 用户
	根据id删除用户,需要输入 id值
	 -->
	<delete id="deleteUser" parameterType="java.lang.Integer">
		delete from user where id=#{id}
	</delete>
	
	<!-- 根据id更新用户
	分析:
	需要传入用户的id
	需要传入用户的更新信息
	parameterType指定user对象,包括 id和更新信息,注意:id必须存在
	#{id}:从输入 user对象中获取id属性值
	 -->
	<update id="updateUser" parameterType="com.zhang.mybatis.po.User">
		update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} 
		 where id=#{id}
	</update>
	
</mapper>


 ​​​​​​​在SqlMapConfig.xml中加载mapper.xml

 <mappers>
        <mapper resource="sqlmap/User.xml"/>
        <!--<mapper resource="sqlmap/UserMapper.xml"/>-->
        <!--通过mapper接口加载映射文件,
        规范:需要将mapper接口类名和mapper.xml名保持一致,并在同一个目录内,
        前提是使用的mapper代理方法-->
       <!-- <mapper class="com.zhang.mybatis.mapper.UserMapper"/>-->
        <!--批量加载映射文件(推荐使用)-->
        <package name="com.zhang.mybatis.mapper"/>

    </mappers>

​​​​​​​ 测试

package com.zhang.mybatis.mapper;

import com.zhang.mybatis.po.User;
import com.zhang.mybatis.po.UserExten;
import com.zhang.mybatis.po.UserQueryVo;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.*;

public class UserMapperTest {
    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void setUp()throws Exception{
        String resource="SqlMapConfig.xml";
        InputStream inputStream= Resources.getResourceAsStream(resource);
        sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testFindUserById() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        User user=userMapper.findUserById(28);
        System.out.println(user);
    }
    @Test
    public void testFindUserByIdResultMap() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        List<User> user=userMapper.findUserByIdResultMap(28);
        System.out.println(user);
    }
    @Test
    public void testFindUserByName() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        List<User> user=userMapper.findUserByName("冯");
        System.out.println(user);
    }
    @Test
    public void testFindUserList() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        UserQueryVo queryVo=new UserQueryVo();
        UserExten userExten=new UserExten();
        userExten.setSex("男");
        userExten.setUsername("王博");
        List<Integer> ids=new ArrayList<>();
        ids.add(1);
        ids.add(28);
        ids.add(30);
        queryVo.setIds(ids);
        queryVo.setUserExten(userExten);
        List<UserExten> user=userMapper.findUserList(queryVo);
        System.out.println(user);
    }
    @Test
    public void testFindUserCount() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        UserQueryVo queryVo=new UserQueryVo();
        UserExten userExten=new UserExten();
        userExten.setSex("男");
        userExten.setUsername("王博");
        queryVo.setUserExten(userExten);
        int user=userMapper.findUserCount(queryVo);
        System.out.println(user);
    }
}

 

即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

 

 

SqlMapConfig.xml

mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:

properties(属性)

settings(全局配置参数)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境集合属性对象)

environment(环境子属性对象)

transactionManager(事务管理)

dataSource(数据源)

mappers(映射器)

<?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="db.properties"></properties>
    <!--定义别名-->
    <typeAliases>
        <!--<typeAlias type="com.zhang.mybatis.po.User" alias="user"></typeAlias>-->
        <package name="com.zhang.mybatis.po"></package>
    </typeAliases>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理,事务控制由mybatis-->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池,由mybatis管理-->
            <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="sqlmap/User.xml"/>
        <!--<mapper resource="sqlmap/UserMapper.xml"/>-->
        <!--通过mapper接口加载映射文件,
        规范:需要将mapper接口类名和mapper.xml名保持一致,并在同一个目录内,
        前提是使用的mapper代理方法-->
       <!-- <mapper class="com.zhang.mybatis.mapper.UserMapper"/>-->
        <!--批量加载映射文件(推荐使用)-->
        <package name="com.zhang.mybatis.mapper"/>

    </mappers>

</configuration>

 

 

 

 

​​​​​​​typeAliases(别名)重点

​​​​​​​需求

在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数的类型、需要resultType指定输出结果的映射类型。

如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。

 ​​​​​​​mybatis默认支持别名

别名

映射的类型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

 

 

​​​​​​​自定义别名

在SqlMapConfig.xml中

<!--定义别名-->
<typeAliases>
    <!--单个别名-->
    <!--<typeAlias type="com.zhang.mybatis.po.User" alias="user"></typeAlias>-->
    <!--批量定义别名-->
    <package name="com.zhang.mybatis.po"></package>
</typeAliases>

 

​​​​​​typeHandlers(类型处理器)

mybatis中通过typeHandlers完成jdbc类型和java类型的转换。

通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义.

mybatis支持类型处理器:

类型处理器

Java类型

JDBC类型

BooleanTypeHandler

Booleanboolean

任何兼容的布尔值

ByteTypeHandler

Bytebyte

任何兼容的数字或字节类型

ShortTypeHandler

Shortshort

任何兼容的数字或短整型

IntegerTypeHandler

Integerint

任何兼容的数字和整型

LongTypeHandler

Longlong

任何兼容的数字或长整型

FloatTypeHandler

Floatfloat

任何兼容的数字或单精度浮点型

DoubleTypeHandler

Doubledouble

任何兼容的数字或双精度浮点型

BigDecimalTypeHandler

BigDecimal

任何兼容的数字或十进制小数类型

StringTypeHandler

String

CHARVARCHAR类型

ClobTypeHandler

String

CLOBLONGVARCHAR类型

NStringTypeHandler

String

NVARCHARNCHAR类型

NClobTypeHandler

String

NCLOB类型

ByteArrayTypeHandler

byte[]

任何兼容的字节流类型

BlobTypeHandler

byte[]

BLOBLONGVARBINARY类型

DateTypeHandler

Datejava.util

TIMESTAMP类型

DateOnlyTypeHandler

Datejava.util

DATE类型

TimeOnlyTypeHandler

Datejava.util

TIME类型

SqlTimestampTypeHandler

Timestampjava.sql

TIMESTAMP类型

SqlDateTypeHandler

Datejava.sql

DATE类型

SqlTimeTypeHandler

Timejava.sql

TIME类型

ObjectTypeHandler

任意

其他或未指定类型

EnumTypeHandler

Enumeration类型

VARCHAR-任何兼容的字符串类型,作为代码存储(而不是索引)。

 

 

​​​​​​​mappers(映射配置)

通过resource加载单个映射文件

​​​​​​​通过mapper接口加载单个mapper

批量加载mapper(推荐使用)

 <mappers>
        <mapper resource="sqlmap/User.xml"/>
        <!--<mapper resource="sqlmap/UserMapper.xml"/>-->
        <!--通过mapper接口加载映射文件,
        规范:需要将mapper接口类名和mapper.xml名保持一致,并在同一个目录内,
        前提是使用的mapper代理方法-->
       <!-- <mapper class="com.zhang.mybatis.mapper.UserMapper"/>-->
        <!--批量加载映射文件(推荐使用)-->
        <package name="com.zhang.mybatis.mapper"/>

    </mappers>

查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射

mybatis中使用resultMap完成高级输出结果映射

定义reusltMap

<resultMap id="userMap" type="user">
		<id column="id_" property="id"></id>
		<result column="username_" property="username"/>
	</resultMap>

使用resultMap作为statement的输出映射类型

<select id="findUserByIdResultMap" parameterType="int" resultMap="userMap">
		SELECT id id_,username username_ FROM USER WHERE id>#{value}
	</select>

使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。

如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系

动态sql

用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。

对查询条件进行判断,如果输入参数不为空才进行查询条件拼接

​​​​​​​sql片段

将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其它的statement中就可以引用sql片段。

方便程序员进行开发

foreach

向sql传递数组或List,mybatis使用foreach解析

<!--定义sql片段-->
	<sql id="queryUser">
		<if test="userExten.sex!=null">
			and user.sex=#{userExten.sex}
		</if>
		<if test="userExten.sex!=null and userExten.username!=null">
			and user.username like '%${userExten.username}%'
		</if>
		<if test="ids!=null">
		<!--使用foreach遍历传入ids
			and (id=1 or id=28 or id=30)
			and IN id(1,28,30)
		-->
			<foreach collection="ids" item="user_id" open="and (" close=")"
					 separator=" or ">
				id=#{user_id}
			</foreach>
		</if>
	</sql>
<select id="findUserList" parameterType="userQueryVo" resultType="UserExten">
		SELECT * FROM User
		<where>
			<include refid="queryUser"></include>
		</where>
	</select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值