Mybatis快速入门——Mybatis学习总结(一)

一.Mybatis介绍


MyBatis 本是apache的一个开源项目iBatis, 2013年11月迁移到Github。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

二. Mybatis框架图

三. 入门项目实践

3.1 环境搭建







依照上述方法加入 junit单元测试包, mysql 或者 oracle 连接启动包 ,就可以了 。

3.2 加入配置文件
3.2.1 log4j.properties  

        log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
        log4j.appender.stdout.Target=System.err  
        log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
        log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n  
        ### direct messages to file mylog.log ###  
        log4j.appender.file=org.apache.log4j.FileAppender  
        log4j.appender.file.File=G:/Log4j_log/MyBatis_Base_log  
        log4j.appender.file.layout=org.apache.log4j.PatternLayout  
        log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n  
        ### set log levels - for more verbose logging change 'info' to 'debug' ###  
        log4j.rootLogger=debug, stdout  

3.2.2 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事务管理 -->
                <transactionManager type="JDBC"/>
                <!-- 数据库连接池 -->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url"
                              value="jdbc:mysql://localhost:3306/mybatis_base?characterEncoding=utf-8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="com/tzq/batis/slqmap/User.xml"/>
        </mappers>
    </configuration>
3.3 创建pojo

pojo类作为mybatis进行sql映射使用,po类通常与数据库表对应。

数据库表

DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '下单用户id',
  `number` varchar(32) NOT NULL COMMENT '订单号',
  `createtime` datetime NOT NULL COMMENT '创建订单时间',
  `note` varchar(100) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

User.java

    package com.tzq.batis.pojo;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Integer id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    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 getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex
                + ", birthday=" + birthday + ", address=" + address + "]";
    }
}
3.4 创建sql 映射文件
<?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,已经当 id 有重命名时 ,区分的标识 -->
<mapper namespace="test">
</mapper>
3.5 实现根据id查询用户

在user.xml中添加select标签,编写sql:

<?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,已经当 id 有重命名时 ,区分的标识 -->
<mapper namespace="test">

    <!-- id:statement的id 或者叫做sql的id-->
    <!-- parameterType:声明输入参数的类型 -->
    <!-- resultType:声明输出结果的类型,应该填写pojo的全路径 -->
    <!-- #{}:输入参数的占位符,相当于jdbc的? -->
    <select id="queryUserById" parameterType="int"
        resultType="cn.itcast.mybatis.pojo.User">
        SELECT * FROM `user` WHERE id  = #{id}
    </select>
</mapper>
3.6 测试程序:
public class MybatisTest {
    private SqlSessionFactory sqlSessionFactory = null;

    @Before
    public void init() throws Exception {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

        // 2. 加载SqlMapConfig.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

        // 3. 创建SqlSessionFactory对象
        this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }

    @Test
    public void testQueryUserById() throws Exception {
        // 4. 创建SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 5. 执行SqlSession对象执行查询,获取结果User
        // 第一个参数是User.xml的statement的id,第二个参数是执行sql需要的参数;
        Object user = sqlSession.selectOne("queryUserById", 1);

        // 6. 打印结果
        System.out.println(user);

        // 7. 释放资源
        sqlSession.close();
    }
}

运行结果

更多sql 操作的 user.xml 代码

    <!-- 写sql语句   , namespace 表示当id 在 另一个 xml map文件中有一样的名字是 , 可以通过它来判断是哪一个-->
<mapper namespace="com.tzq.batis.mapperdao.UserMapperDao">
    <!--  #{}是 mybatis 里的通配符    resultType 代表 执行后的结果类型   parameterType 代表 下面通配符的属性类型-->
    <!-- 通过ID查询-->
    <select id="findByid" resultType="com.tzq.batis.pojo.User" parameterType="Integer">
        select * from user where id = #{VALUE }
    </select>

    <!--  根据用户名模糊查询数据
          #{}  表示占位符      #{} == ?    转换为 sql 会  给 #{} 的外出加上  ''  单引号
          ${}  表示  字符串拼接     拼接不会加单引号
    -->
    <select id="findUserByName" resultType="com.tzq.batis.pojo.User" parameterType="String">
        <!--  select * from user where username like "%"#{可以随便起名}"%"      与 下面语句一样的效果  -->
        select * from user where username like '%${value}%'
    </select>

    <!--  添加用户-->
    <insert id="insertUser" parameterType="com.tzq.batis.pojo.User">
        <selectKey resultType="integer" keyProperty="id" order="AFTER">
            select LAST_INSERT_ID()
        </selectKey>
        insert into user
        (username , sex) values (#{username},#{sex})
    </insert>

    <!--  更新用户-->
    <update id="updateUser" parameterType="com.tzq.batis.pojo.User">
        update user SET username = #{username} where id = #{id}
    </update>
    <!-- 删除用户 -->
    <delete id="deleteUser" parameterType="com.tzq.batis.pojo.User">
        delete FROM user where id = #{id}
    </delete>
</mapper>  

对应的java代码


        public class TestUserMybatis {

        /*
        获取session
         */
        public SqlSession getSqlSession() throws IOException {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //创建sqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            return sqlSession;
        }

        /*
        通过了ID 查询数据
         */
        @Test
        public void testSelect() throws IOException {
            SqlSession sqlSession = getSqlSession();
            //执行sql语句  ,表示查询一个
            User user = sqlSession.selectOne("com.tzq.batis.mapperdao.UserMapperDao.findByid", 1);
            System.out.println(user.toString());
            sqlSession.close();
        }

        /*
        根据用户名模糊查询数据
         */
        @Test
        public void testFindDimName() throws IOException {
            SqlSession sqlSession = getSqlSession();
            //执行sql语句
            List<User> list = sqlSession.selectList("test.findUserByName", "五");
            for (User user : list) {
                System.out.println(user.toString());
            }
            sqlSession.close();
        }

        /*
        添加用户
         */
        @Test
        public void testInsertUser() throws IOException {
            SqlSession sqlSession = getSqlSession();
            //执行sql语句
            User user = new User();
            user.setUsername("李四");
            user.setSex("男");

            int insert = sqlSession.insert("test.insertUser", user);
            sqlSession.commit();
            sqlSession.close();

            System.out.println(user.getId());
        }

        /*
      修改用户
       */
        @Test
        public void testUpdateUserById() throws IOException {
            SqlSession sqlSession = getSqlSession();
            //执行sql语句

            User user = new User();
            user.setId(29);
            user.setUsername("张三");

            sqlSession.update("updateUser", user);
            sqlSession.commit();
            sqlSession.close();
        }

        /*
    删除用户
     */
        @Test
        public void testDeleteUserById() throws IOException {
            SqlSession sqlSession = getSqlSession();
            //执行sql语句

            User user = new User();
            user.setId(29);

            sqlSession.update("deleteUser", user);
            sqlSession.commit();
            sqlSession.close();
        }


    }
3.7 小结
3.7.1 #{}和${}
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

sql {}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, pojoparameterType {}括号中只能是value。

3.7.2. parameterType和resultType

parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中

3.7.3. selectOne和selectList

selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)
selectList可以查询一条或多条记录。

3.8 Dao开发
3.8.1传统Dao的开发

Dao接口


    public interface UserDao {
    public User selectUserById(Integer id);
}

Dao接口的实现类

public class UserDaoImpl implements UserDao {
    private SqlSessionFactory sqlSessionFactory;

    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User selectUserById(Integer id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("findByid", id);
        return user;
    }
}

junit 测试类

public class TestUserDao {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void before() throws Exception {
        //加载核心配置文件
        String resource = "sqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //创建SqlSessionFactory
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }


    /**
     * Method: TestDao()
     */
    @Test
    public void testTestDao() throws Exception {
        UserDao dao = new UserDaoImpl(sqlSessionFactory);
        User user = dao.selectUserById(10);
        System.out.println(user.getUsername());
    }


} 

3.9 重量级嘉宾登场 —— Mapper动态代理方式

3.9.1 开发规范

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

#代理的接口代码:

    public interface UserMapperDao {
    /**
         * Mapper 动态代理方法
         * 只要实现了下面的四个原则 , 就不用写daoImpl 了
         * Created by MyPC on 2017/8/19.
         */
        /*
        四个原则
        1.接口的方法名与  Mapper.xml 中的 id 名 一样
        2.返回值类型与Mapper.xml文件中返回值类型一致
        3.方法的 输入参数 类型要与 Mapper.xml 的一致
        4.Mapper.xml命名空间绑定这个接口全路径名
         */
        public User findByid(Integer id);

    }
#junit测试类
    public class TestUserMapperDao {

        @Test
        public void testSelectUserById() throws IOException {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //创建sqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();

            UserMapperDao dao = sqlSession.getMapper(UserMapperDao.class);
            User user = dao.findByid(10);
            System.out.println(user.toString());

        }

    }

官网推荐使用 动态代理的方式 , 当然您可以根据自己的需求去写。

写的不好还望看见的兄弟不要嘲笑。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值