Mybatis-2

Mybatis的CRUD

在这里插入图片描述

IUserDao接口

/**
 * 用户操作接口
 */
public interface IUserDao {
    /**
     * 查询所有用户
     *
     * @return
     */
    List<User> findAll();
    /**
     * 保存用户
     *
     * @param user
     */
    void saveUser(User user);
    /**
     * 修改用户
     *
     * @param user
     */
    void updateUser(User user);
    /**
     * 根据id删除用户
     *
     * @param id
     */
    void deleteUser(Integer id);
    /**
     * 根据id查询用户
     *
     * @param id
     * @return
     */
    User findUserById(Integer id);
    /**
     * 根据名称查询用户
     * @param name
     * @return
     */
    List<User> findUserByName(String name);
    /**
     * 查询用户数量
     * @return
     */
    Integer findUserNumber();
}

User实体类

/**
 * 用户实体类
 */
public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getBirthday() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        return sdf.format(birthday);
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + getBirthday() +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

IUserMapper.xml映射文件

1.parameterType配置参数支持的内置别名

	基 本 类 型 和 String 我 们 可 以 直 接 写 类 型 名 称 , 也 可 以 使 用 包 名 . 类 名 的 方 式 , 例 如 :
java.lang.String。
	实体类类型,目前我们只能使用全限定类名。
	究其原因,是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名,
而我们的是实体类并没有注册别名,所以必须写全限定类名。在今天课程的最后一个章节中将讲解如何注册实体类
的别名。

这些都是支持的默认别名。我们也可以从源码角度来看它们分别都是如何定义出来的。
可以参考 TypeAliasRegistery.class 的源码。

在这里插入图片描述

<?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.ginger.dao.IUserDao">
    <!--配置查询所有-->
    <select id="findAll" resultType="com.ginger.pojo.User">
        select * from user
    </select>
    <!--保存用户-->
    <insert id="saveUser" parameterType="com.ginger.pojo.User">
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address});
    </insert>
    <!--根据id更新用户-->
    <update id="updateUser" parameterType="com.ginger.pojo.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>
    <!--根据id删除用户-->
    <delete id="deleteUser" parameterType="Integer">
        delete from user where id = #{id}
    </delete>
    <!--根据id查询用户-->
    <select id="findUserById" parameterType="Integer" resultType="com.ginger.pojo.User">
        select * from user where id = #{id}
    </select>
    <!--根据名称查询用户-->
    <select id="findUserByName" parameterType="String" resultType="com.ginger.pojo.User">
        <!--select * from user where username like  #{username}-->
        select * from user where username like '%${value}%'
    </select>
    <!--查询用户数量-->
    <select id="findUserNumber" resultType="Integer">
        select count(*) from user
    </select>
</mapper>

log4j.properties日志支持配置文件

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

Mybatis的配置文件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">
<!-- mybatis的主配置文件 -->
<configuration>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
    <mappers>
        <mapper resource="com/ginger/dao/IUserMapper.xml"/>
        <!--   <mapper class="com.ginger.dao.IUserDao"/>-->
    </mappers>
</configuration>

测试

public class IUserDaoTest {
    InputStream is;
    SqlSession sqlSession;
    IUserDao iud;
    @Before
    public void befor() throws IOException {
        //读取配置文件
        is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建构建者对象
        SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
        //使用构建者对象创建工厂对象
        SqlSessionFactory ssf = ssfb.build(is);
        //使用工厂对象创建SqlSession对象
        sqlSession = ssf.openSession();
        //使用sqlSession对象创建接口代理对象
        iud = sqlSession.getMapper(IUserDao.class);
    }
    @After
    public void after() {
        //释放资源
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSession.close();
    }
    /**
     * 查询所有用户
     *
     * @throws IOException
     */
    @Test
    public void test() throws IOException {
        List<User> users = iud.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }
    /**
     * 保存用户
     */
    @Test
    public void test1() {
        User user = new User();
        user.setUsername("疾风剑豪");
        user.setBirthday(new Date());
        user.setSex("男");
        user.setAddress("艾欧尼亚");
        iud.saveUser(user);
        //提交事务
        sqlSession.commit();
    }
    /**
     * 更新用户
     */
    @Test
    public void test2() {
        User user = new User();
        user.setId(41);
        user.setUsername("男枪");
        user.setBirthday(new Date());
        user.setSex("男");
        user.setAddress("征服之海");
        iud.updateUser(user);
        //提交事务
        sqlSession.commit();
    }
    /**
     * 根据id删除用户
     */
    @Test
    public void test3() {
        iud.deleteUser(50);
        //提交事务
        sqlSession.commit();
    }
    /**
     * 根据id查询用户
     */
    @Test
    public void test4(){
        User user = iud.findUserById(41);
        System.out.println(user);
    }
    /**
     * 根据姓名模糊查询
     */
    @Test
    public void test5(){
        //使用#{}
        //List<User> users = iud.findUserByName("%诡术%");
        //使用${}
        List<User> users = iud.findUserByName("诡术");
        for (User user : users) {
            System.out.println(user);
        }
    }
    /**
     * 查询用户数量
     */
    @Test
    public void test6(){
        Integer count = iud.findUserNumber();
        System.out.println(count);
    }
}

保存操作后获取保存数据的id

在这里插入图片描述

Mybaits中映射文件#{}和${}总结

#{}总结:
	#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,#{}可以有效防止sql注入。
	自动进行java类型和jdbc类型转换。
	#{}可以接收简单类型值或pojo属性值。
	如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}总结:
	${}表示拼接sql串。
	通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换。(因为是字符串拼接。)
	${}可以接收简单类型值或pojo属性值。
	如果parameterType传输单个简单类型值,${}括号中只能是value。(因为源码中已经写死了。)

Mybaits中映射文件#{}和${}图解
在这里插入图片描述

Mybatis参数与返回值映射

1.Mybatis包装类作为参数

1.OGNL表达式

Object Graphic Navigation Language
对象	图	导航	   语言

它是通过对象的取值方法来获取数据。在写法上把get给省略了。
比如:我们获取用户的名称
	类中的写法:user.getUsername();
	OGNL表达式写法:user.username
mybatis中为什么能直接写username,而不用user.呢:
	因为在parameterType中已经提供了属性所属的类,所以此时不需要写对象名

IUserDao接口

/**
 * 用户操作接口
 */
public interface IUserDao {
/**
     * 根据QueryVo查询用户
     * @param qv
     * @return
     */
    List<User> findUserByQueryVo(QueryVo qv);
}

QueryVo包装类

/**
 * 包装类
 */
public class QueryVo {
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}

User实体类

/**
 * 用户实体类
 */
public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getBirthday() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        return sdf.format(birthday);
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + getBirthday() +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

IUserMapper.xml映射文件

<!--根据QueryVo查询用户-->
    <select id="findUserByQueryVo" parameterType="com.ginger.pojo.QueryVo" resultType="com.ginger.pojo.User">
        select * from user where username like #{user.username}
    </select>

测试

 /**
     * 根据QueryVo查询用户
     */
    @Test
    public void test7(){
        User user = new User();
        //这里有想过设置username为%妖姬%合不合理,其实是没问题的,就是一个查询条件。又不入库。
        user.setUsername("%妖姬%");
        QueryVo qv = new QueryVo();
        qv.setUser(user);
        List<User> users = iud.findUserByQueryVo(qv);
        for (User user1 : users) {
            System.out.println(user1);
        }
    }

结果:

User{id=42, username='诡术妖姬', birthday=2018-03-02 03:09:37, sex='女', address='巨龙之巢'}
User{id=43, username='诡术妖姬', birthday=2018-03-04 11:34:34, sex='女', address='征服之海'}

2.Mybatis返回值映射

在mybatis中,如果实体类中的属性名称和数据库表中的列名称相同会通过反射,给实体类的属性赋值,这是在属性名称和列名称相同的情况下,如果不相同呢?

属性名称和表中的列名称不匹配怎么办?
在这里插入图片描述
测试

/**
     * 查询所有用户
     *
     * @throws IOException
     */
    @Test
    public void test() throws IOException {
        List<User> users = iud.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

映射文件

<!--配置查询所有-->
<select id="findAll" resultType="com.ginger.pojo.User">
    select * from user
</select>

结果:为什么就userName能赋值呢?
因为在window系统下,mysql数据库忽略字母大小写,刚好属性名称userName,列名称username就可以赋值上了。
注意:在linux系统下mysql数据库就不忽略字母大小写了。

User{userId=null, userName='男枪', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='诡术妖姬', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='诡术妖姬', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='影流之主', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='格雷福斯', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='光辉女郎', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='疾风剑豪', userBirthday=null, userSex='null', userAddress='null'}

1.Mybatis返回值映射问题解决方式1

测试

/**
     * 查询所有用户
     *
     * @throws IOException
     */
    @Test
    public void test() throws IOException {
        List<User> users = iud.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

映射文件

<!--配置查询所有-->
<select id="findAll" resultType="com.ginger.pojo.User">
  <!--使用数据库别名的方式-->
  select id as userId,username as userName,birthday as userBirthday,sex as userSex,address as userAddress from user
</select>

结果:

User{userId=41, userName='男枪', userBirthday=Wed Jun 10 11:25:58 CST 2020, userSex='男', userAddress='征服之海'}
User{userId=42, userName='诡术妖姬', userBirthday=Fri Mar 02 15:09:37 CST 2018, userSex='女', userAddress='巨龙之巢'}
User{userId=43, userName='诡术妖姬', userBirthday=Sun Mar 04 11:34:34 CST 2018, userSex='女', userAddress='征服之海'}
User{userId=45, userName='影流之主', userBirthday=Sun Mar 04 12:04:06 CST 2018, userSex='男', userAddress='影流'}
User{userId=46, userName='格雷福斯', userBirthday=Wed Mar 07 17:37:26 CST 2018, userSex='男', userAddress='班德尔城'}
User{userId=48, userName='光辉女郎', userBirthday=Thu Mar 08 11:44:00 CST 2018, userSex='女', userAddress='德玛西亚'}
User{userId=51, userName='疾风剑豪', userBirthday=Wed Jun 10 11:25:58 CST 2020, userSex='男', userAddress='艾欧尼亚'}

2.Mybatis返回值映射问题解决方式2

测试

/**
     * 查询所有用户
     *
     * @throws IOException
     */
    @Test
    public void test() throws IOException {
        List<User> users = iud.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

映射文件

<!--配置实体类和数据库表列名称映射关系-->
<!-- resultMap最终还是要将结果映射到pojo上,type就是指定映射到哪一个pojo -->
<!-- id:设置ResultMap的id -->
<resultMap id="userMap" type="com.ginger.pojo.User">
   	<!-- 定义主键 ,非常重要。如果是多个字段,则定义多个id -->
    <id property="userId" column="id"></id>
    <!--其他属性映射-->
    <result property="userName" column="username"></result>
    <result property="userBirthday" column="birthday"></result>
    <result property="userSex" column="sex"></result>
    <result property="userAddress" column="address"></result>
</resultMap>

<!--配置查询所有-->
<select id="findAll" resultMap="userMap">
    select * from user
</select>

结果:

User{userId=41, userName='男枪', userBirthday=Wed Jun 10 11:25:58 CST 2020, userSex='男', userAddress='征服之海'}
User{userId=42, userName='诡术妖姬', userBirthday=Fri Mar 02 15:09:37 CST 2018, userSex='女', userAddress='巨龙之巢'}
User{userId=43, userName='诡术妖姬', userBirthday=Sun Mar 04 11:34:34 CST 2018, userSex='女', userAddress='征服之海'}
User{userId=45, userName='影流之主', userBirthday=Sun Mar 04 12:04:06 CST 2018, userSex='男', userAddress='影流'}
User{userId=46, userName='格雷福斯', userBirthday=Wed Mar 07 17:37:26 CST 2018, userSex='男', userAddress='班德尔城'}
User{userId=48, userName='光辉女郎', userBirthday=Thu Mar 08 11:44:00 CST 2018, userSex='女', userAddress='德玛西亚'}
User{userId=51, userName='疾风剑豪', userBirthday=Wed Jun 10 11:25:58 CST 2020, userSex='男', userAddress='艾欧尼亚'}

resultMap扩展图解
在这里插入图片描述

Mybatis使用实现类实现CRUD

包结构
在这里插入图片描述

UserDaoImpl实现类

public class UserDaoImpl implements IUserDao {
    private SqlSessionFactory factory;
    public UserDaoImpl(SqlSessionFactory factory){
        this.factory = factory;
    }
    @Override
    public List<User> findAll() {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SqlSession中的方法,实现查询列表
        List<User> users = session.selectList("com.itheima.dao.IUserDao.findAll");//参数就是能获取配置信息的key
        //3.释放资源
        session.close();
        return users;
    }
    @Override
    public void saveUser(User user) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用方法实现保存
        session.insert("com.itheima.dao.IUserDao.saveUser",user);
        //3.提交事务
        session.commit();
        //4.释放资源
        session.close();
    }
    @Override
    public void updateUser(User user) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用方法实现更新
        session.update("com.itheima.dao.IUserDao.updateUser",user);
        //3.提交事务
        session.commit();
        //4.释放资源
        session.close();
    }
    @Override
    public void deleteUser(Integer userId) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用方法实现更新
        session.update("com.itheima.dao.IUserDao.deleteUser",userId);
        //3.提交事务
        session.commit();
        //4.释放资源
        session.close();
    }
    @Override
    public User findById(Integer userId) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SqlSession中的方法,实现查询一个
        User user = session.selectOne("com.itheima.dao.IUserDao.findById",userId);
        //3.释放资源
        session.close();
        return user;
    }
    @Override
    public List<User> findByName(String username) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SqlSession中的方法,实现查询列表
        List<User> users = session.selectList("com.itheima.dao.IUserDao.findByName",username);
        //3.释放资源
        session.close();
        return users;
    }
    @Override
    public int findTotal() {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SqlSession中的方法,实现查询一个
        Integer count = session.selectOne("com.itheima.dao.IUserDao.findTotal");
        //3.释放资源
        session.close();
        return count;
    }
}

IUserDao接口

/**
 *
 * 用户的持久层接口
 */
public interface IUserDao {
    /**
     * 查询所有用户
     * @return
     */
    List<User> findAll();
    /**
     * 保存用户
     * @param user
     */
    void saveUser(User user);
    /**
     * 更新用户
     * @param user
     */
    void updateUser(User user);

    /**
     * 根据Id删除用户
     * @param userId
     */
    void deleteUser(Integer userId);
    /**
     * 根据id查询用户信息
     * @param userId
     * @return
     */
    User findById(Integer userId);
    /**
     * 根据名称模糊查询用户信息
     * @param username
     * @return
     */
    List<User> findByName(String username);
    /**
     * 查询总用户数
     * @return
     */
    int findTotal();
}

User实体类

/**
 * 用户实体类
 */
public class User implements Serializable {
    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

IUserDao.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.itheima.dao.IUserDao">
    <!-- 查询所有 -->
    <select id="findAll" resultType="com.ginger.pojo.User">
        select * from user;
    </select>
    <!-- 保存用户 -->
    <insert id="saveUser" parameterType="com.ginger.pojo.User">
        <!-- 配置插入操作后,获取插入数据的id -->
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
    </insert>
    <!-- 更新用户 -->
    <update id="updateUser" parameterType="com.ginger.pojo.User">
        update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}
    </update>
    <!-- 删除用户-->
    <delete id="deleteUser" parameterType="java.lang.Integer">
        delete from user where id = #{uid}
    </delete>
    <!-- 根据id查询用户 -->
    <select id="findById" parameterType="INT" resultType="com.ginger.pojo.User">
        select * from user where id = #{uid}
    </select>
    <!-- 根据名称模糊查询 -->
    <select id="findByName" parameterType="string" resultType="com.ginger.pojo.User">
          select * from user where username like #{name}
   </select>
    <!-- 获取用户的总记录条数 -->
    <select id="findTotal" resultType="int">
        select count(id) from user;
    </select>
</mapper>

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>
    <!--配置环境-->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务 -->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql:///mybatis"></property>
                <property name="username" value="root"></property>
                <property name="password" value="root"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件的位置 -->
    <mappers>
        <mapper resource="com/ginger/dao/IUserDao.xml"></mapper>
    </mappers>
</configuration>

测试

/**
 *
 * 测试mybatis的crud操作
 */
public class MybatisTest {
    private InputStream in;
    private IUserDao userDao;
    @Before//用于在测试方法执行之前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.使用工厂对象,创建dao对象
        userDao = new UserDaoImpl(factory);
    }
    @After//用于在测试方法执行之后执行
    public void destroy()throws Exception{
        //6.释放资源
        in.close();
    }
    /**
     * 测试查询所有
     */
    @Test
    public void testFindAll(){
        //5.执行查询所有方法
        List<User> users = userDao.findAll();
        for(User user : users){
            System.out.println(user);
        }
    }
    /**
     * 测试保存操作
     */
    @Test
    public void testSave(){
        User user = new User();
        user.setUsername("至高之拳");
        user.setAddress("黑色玫瑰");
        user.setSex("男");
        user.setBirthday(new Date());
        //5.执行保存方法
        userDao.saveUser(user);
        System.out.println("保存操作之后:"+user);
    }
    /**
     * 测试更新操作
     */
    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(51);
        user.setUsername("蛮族之王");
        user.setAddress("巨神峰");
        user.setSex("男");
        user.setBirthday(new Date());
        //5.执行保存方法
        userDao.updateUser(user);
    }
    /**
     * 测试删除操作
     */
    @Test
    public void testDelete(){
        //5.执行删除方法
        userDao.deleteUser(51);
    }
    /**
     * 测试删除操作
     */
    @Test
    public void testFindOne(){
        //5.执行查询一个方法
        User  user = userDao.findById(48);
        System.out.println(user);
    }
    /**
     * 测试模糊查询操作
     */
    @Test
    public void testFindByName(){
        //5.执行查询一个方法
        List<User> users = userDao.findByName("%妖姬%");
        for(User user : users){
            System.out.println(user);
        }
    }
    /**
     * 测试查询总记录条数
     */
    @Test
    public void testFindTotal(){
        //5.执行查询一个方法
        int count = userDao.findTotal();
        System.out.println(count);
    }
}

Mybatis实现类执行流程分析图解

在这里插入图片描述

Mybatis代理执行流程分析图解

在这里插入图片描述

properties标签typeAliases标签和package标签使用

配置位置:mybatis核心配置文件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>
    <!-- 配置properties
        可以在标签内部配置连接数据库的信息。也可以通过属性引用外部配置文件信息
        resource属性: 常用的
            用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下。
        url属性:
            是要求按照Url的写法来写地址
            URL:Uniform Resource Locator 统一资源定位符。它是可以唯一标识一个资源的位置。
            它的写法:
                http://localhost:8080/mybatisserver/demo1Servlet
                协议      主机     端口       URI

            URI:Uniform Resource Identifier 统一资源标识符。它是在应用中可以唯一定位一个资源的。
    -->
    <properties url="file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.properties">
       <!-- <property name="driver" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql:///mybatis"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>-->
    </properties>

    <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
    <typeAliases>
        <!--typeAlias用于配置别名。type属性指定的是实体类全限定类名。alias属性指定别名,当指定了别名就再区分大小写 
        <typeAlias type="com.ginger.pojo.User" alias="user"></typeAlias>-->

        <!-- 用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
        <package name="com.ginger.domain"></package>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务 -->
            <transactionManager type="JDBC"></transactionManager>

            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件的位置 -->
    <mappers>
        <!--<mapper resource="com/ginger/dao/IUserDao.xml"></mapper>-->
        <!-- package标签是用于指定dao接口所在的包,当指定了之后就不需要在写mapper以及resource或者class了 -->
        <package name="com.ginger.dao"></package>
    </mappers>
</configuration>

jdbcConfig.properties

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

Mybatis中的连接池以及事务控制

1.Mybatis中连接池

连接池图解
在这里插入图片描述
Mybatis连接池

1、连接池:
	我们在实际开发中都会使用连接池。
	因为它可以减少我们获取连接所消耗的时间。
2、mybatis中的连接池
	mybatis连接池提供了3种方式的配置:
		配置的位置:
			主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种连接池方式。
		type属性的取值:
			POOLED:采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
			UNPOOLED:采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。
			JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。
				 注意:如果不是web或者maven的war工程,是不能使用的。
				 我们课程中使用的是tomcat服务器,采用连接池就是dbcp连接池。

数据源的配置方式
使用连接池

<!-- 配置连接数据库的信息:用的是数据源(连接池) -->
<dataSource type="POOLED">
    <property name="driver" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql:///mybatis"></property>
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
</dataSource>

不使用连接池

<!-- 配置连接数据库的信息:用的是数据源(连接池) -->
<dataSource type="UNPOOLED">
   <property name="driver" value="com.mysql.jdbc.Driver"></property>
   <property name="url" value="jdbc:mysql:///mybatis"></property>
   <property name="username" value="root"></property>
   <property name="password" value="root"></property>
</dataSource>

在这里插入图片描述

2.JNDI数据源

JNDI:Java Naming and Directory Interface。是SUN公司推出的一套规范,属于JavaEE技术之一。目的是模仿windows系统中的注册表。
在服务器中注册数据源:

1.JNDI图解

在这里插入图片描述

2.创建Maven的war工程并导入坐标

pom.xml

<dependencies>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.5</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
    </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
  </dependency>
</dependencies>

3.在webapp文件下创建META-INF目录

在这里插入图片描述

4.在META-INF目录中建立一个名为context.xml的配置文件

在这里插入图片描述
context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- 
<Resource 
name="jdbc/mybatis"                  数据源的名称
type="javax.sql.DataSource"                   数据源类型
auth="Container"                        数据源提供者
maxActive="20"                         最大活动数
maxWait="10000"                            最大等待时间
maxIdle="5"                               最大空闲数
username="root"                            用户名
password="1234"                            密码
driverClassName="com.mysql.jdbc.Driver"          驱动类
url="jdbc:mysql:///mybatis" 连接url字符串
/>
 -->
<Resource 
name="jdbc/mybatis"
type="javax.sql.DataSource"
auth="Container"
maxActive="20"
maxWait="10000"
maxIdle="5"
username="root"
password="1234"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql:///mybatis"
/>
</Context>

5.修改SqlMapConfig.xml中的配置

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>
    <typeAliases>
        <package name="com.itheima.pojo"></package>
    </typeAliases>
    <!-- 配置mybatis的环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境 -->
        <environment id="mysql">
            <!-- 配置事务控制的方式 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置连接数据库的必备信息  type属性表示是否使用数据源(连接池)-->
            <dataSource type="JNDI">
            	<!--
            		java:comp/env/jdbc/eesy_mybatis
            		java:comp/env:这个固定的路径不能修改
            		jdbc/eesy_mybatis:这个是context.xml配置文件中的name属性值
            	-->
                <property name="data_source" value="java:comp/env/jdbc/mybatis"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 指定mapper配置文件的位置 -->
    <mappers>
        <mapper resource="com/itheima/dao/IUserDao.xml"/>
    </mappers>
</configuration>

6.测试

注意一定要经过服务器,所以就把测试写在index.jsp页面中。
在这里插入图片描述

3.Mybatis事务控制(自动提交事务)

什么是事务
	事务的四大特性ACID
	不考虑隔离性会产生的3个问题
	解决办法:四种隔离级别

它是通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚

测试

public class IUserDaoTest {
    InputStream is;
    SqlSession sqlSession;
    IUserDao iud;
    @Before
    public void befor() throws IOException {
        //读取配置文件
        is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建构建者对象
        SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
        //使用构建者对象创建工厂对象
        SqlSessionFactory ssf = ssfb.build(is);
        //使用工厂对象创建SqlSession对象
        sqlSession = ssf.openSession(true);//设置为true自动提交事务
        //使用sqlSession对象创建接口代理对象
        iud = sqlSession.getMapper(IUserDao.class);
    }
    @After
    public void after() {
        //释放资源
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSession.close();
    }
    /**
     * 保存用户
     */
    @Test
    public void test1() {
        User user = new User();
        user.setUserName("疾风剑豪");
        user.setUserBirthday(new Date());
        user.setUserSex("男");
        user.setUserAddress("艾欧尼亚");
        iud.saveUser(user);
        //提交事务
        //sqlSession.commit();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值