MyBatis-增删改查,获取添加后的主键,模糊查询

Mybatis简介

1.1、什么是MyBatis
  • MyBatis 是一款优秀的持久层框架
  • MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程
  • MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 【Plain Old Java Objects,普通的 Java对象】映射成数据库中的记录。
  • MyBatis 本是apache的一个开源项目ibatis, 2010年这个项目由apache 迁移到了google code,并且改名为MyBatis
  • 2013年11月迁移到Github
  • Mybatis官方文档 : http://www.mybatis.org/mybatis-3/zh/index.html
  • GitHub : https://github.com/mybatis/mybatis-3
1.2、持久化
  • 持久化是将程序数据在持久状态和瞬时状态间转换的机制。
    即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。
    JDBC就是一种持久化机制。文件IO也是一种持久化机制。
  • 为什么需要持久化呢?
    内存断电后数据会丢失,但有一些对象是无论如何都不能丢失的,比如银行账号等,遗憾的是,人们还无法保证内存永不掉电。
    内存过于昂贵,与硬盘、光盘等外存相比,内存的价格要高2~3个数量级,而且维持成本也高,至少需要一直供电吧。所以即使对象不需要永久保存,也会因为内存的容量限制不能一直待在内存中,需要持久化来缓存到外存。
1.3、持久层
  • 什么是持久层?
  • 完成持久化工作的代码块 . ----> dao层 【DAO (Data Access Object) 数据访问对象】
  • 大多数情况下特别是企业级应用,数据持久化往往也就意味着将内存中的数据保存到磁盘上加以固化,而持久化的实现过程则大多通过各种关系数据库来完成。
  • 与系统其他部分相对而言,这个层面应该具有一个较为清晰和严格的逻辑边界。 【说白了就是用来操作数据库存在的!】
1.4、为什么需要Mybatis
  • Mybatis就是帮助程序猿将数据存入数据库中以及从数据库中取出数据 .
  • 传统的jdbc操作 , 有很多重复代码块 .比如 : 数据取出时的封装 , 数据库的建立连接等等… , 通过框架可以减少重复代码,提高开发效率 .
  • MyBatis 是一个半自动化的ORM框架 (Object Relationship Mapping) -->对象关系映射
  • 所有的事情,不用Mybatis依旧可以做到,只是用了它,所有实现会更加简单!
MyBatis的优点
  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件就可以了,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供xml标签,支持编写动态sql。

Mybatis操作数据库

MyBatis的Mapper开发

Mapper代理的方式 主要是解决 不写dao实现类 程序员只需要编写Mapper接口就可以了 但满足规范时 MyBatis 会自动生成Mapper的代理实现类 操作

需要注意的地方

  • Mapper接口的完整路径 要和Mapper映射文件中的namespace保持一致
  • Mapper接口中的方法 要和映射文件中select update insert delete标签中的 id 值一致
  • Mapper接口中方法的参数只能有一个 并且类型要和映射文件中select update insert delete标签中的parameterType的类型一致 、
  • Mapper接口中返回值要和要和映射文件中select update insert delete标签中的resultType或者resultMap的类型一致

注意点:如果接口中方法返回值的是一个List集合,在映射文件中写泛型的类型即可.

增删改的时候需要提交事务

 *  提交事务方式一:
 *      sqlSessionFactory.openSession(true);
 *  提交事务方式二:
 *      sqlSession.commit(); [数据插入之后,关闭之前 进行提交事务]
环境搭建

建立数据库数据表,并且插入数据

CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名称',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `sex` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '性别',
  `address` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 27 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;


INSERT INTO `user` VALUES (1, '盛世名', NULL, '2', NULL);
INSERT INTO `user` VALUES (10, '张甲吉', '2014-07-10', '1', '北京市');
INSERT INTO `user` VALUES (16, '张名东', NULL, '1', '河南郑州');
INSERT INTO `user` VALUES (22, '孙训', NULL, '1', '河南郑州');
INSERT INTO `user` VALUES (24, '周芷若', NULL, '1', '河南郑州');
INSERT INTO `user` VALUES (25, '赵敏', NULL, '1', '河南郑州');
INSERT INTO `user` VALUES (26, '名小昭', NULL, NULL, NULL);
创建一个java项目

在lib文件夹下导入需要的jar包
在这里插入图片描述
注意: 直接导入mybatis 和 mysql驱动包 2个包就可以了 但是建议把所有的包都导入进去

创建实体类User
public class User {

  private long id;
  private String username;
  private Date birthday;
  private String sex;
  private String address;

getter setter toString
编写主配置文件 mybatis-config.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:指定外部配置文件  从类(src)路径下开始找 以文件夹的形式展现
    url:从电脑硬盘上查找 需要添加file协议 file:///
    -->
    <properties resource="db.properties"/>
<!--    <properties url="file:///E:\\java-workspace\\ssm\\1-mybatis\\src\\db.properties"/>-->

    <environments default="development">
        <environment id="development">
            <!--transactionManager 事务管理器-->
            <transactionManager type="JDBC"/>
            <!--dataSource  数据源配置
                type :1、POOLED  有数据源连接池 是mybatis自己实现的一个连接池
                      2、UNPOOLED    无数据源连接池
            -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClassName}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--加载映射文件 mappers
        四种方式:
        mapper
            1、resource:指定外部配置文件  从类(src)路径下开始找 以文件夹的形式展现
            2、url:硬盘中带盘符带协议的完整路径
            3、class:
                使用class需要的两个条件:(前提:mapper代理方式)
                    3.1:映射文件和接口同包同目录
                    3.2:映射文件名和接口名保持一致,不区分大小写!!
        package
            4、package:包扫描的方式去加载映射文件(与使用class的要求一致) 最常用
    -->
    <mappers>
        <mapper resource="com/codeyancy/cn/mapper1/usermapper1.xml"/>
<!--        <mapper resource="com/codeyancy/cn/mapper/UserMapper.xml"/>-->
<!--        <mapper url="file:///E:\\java-workspace\\ssm\\1-mybatis\\src\\com\\codeyancy\\cn\\mapper\\UserMapper.xml"/>-->
<!--        <mapper class="com.codeyancy.cn.mapper.UserMapper"/>-->
        <!--包扫描-->
        <package name="com.codeyancy.cn.mapper"/>
    </mappers>
</configuration>

抽取db.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=666
编写mapper配置文件和接口

在这里插入图片描述

UserMapper接口

public interface UserMapper {
    /**
     * 查询所有
     */

    List<User> findAll();

    /**
     * 根据id查询
     */
    User findById(Integer id);

    /**
     * 添加
     */
    void addUser(User user);

    /**
     * 修改
     */
    void updateUser(User user);

    /**
     * 删除
     */
    void deleteUser(Integer id);
    /**
     * 模糊查询
     */
    List<User> findByUserName(String name);

    /**
     * 添加用户返回主键
     */
    void addUserReturnId(User user);

}

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:接口完整路径
-->
<mapper namespace="com.codeyancy.cn.mapper.UserMapper">
<!--    查询全部-->
    <select id="findAll" resultType="com.codeyancy.cn.entity.User">
        select * from user
    </select>

<!--    根据id查询一条-->
    <select id="findById" resultType="com.codeyancy.cn.entity.User" parameterType="java.lang.Integer">
        select * from user where id=#{id}
    </select>

<!--    添加-->
    <insert id="addUser" parameterType="com.codeyancy.cn.entity.User">
        insert into user (username, birthday, sex, address) values
        (#{username},#{birthday},#{sex},#{address})
    </insert>

<!--    修改-->
    <update id="updateUser" parameterType="com.codeyancy.cn.entity.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>

<!--    删除-->
    <delete id="deleteUser" parameterType="java.lang.Integer">
        delete from user where id =#{id}
    </delete>

<!--    模糊查询
两种写法:
    1、${}   select * from user where username like '%${username}%'
    2、#{}   select * from user where username like '%' #{username} '%'  //这个单引号也可以改为双引号
-->
    <!--对名字进行模糊查询-->
    <select id="findByUserName" parameterType="java.lang.String" resultType="com.codeyancy.cn.entity.User">
        select * from user where username like '%' #{username} '%'
    </select>
    
<!--
添加信息后的主键返回
    resultType 表示返回值类型
    keyColumn
    keyProperty 表示主键的属性
    order 表示返回的主键是在添加前 还是添加后   取值after   before
    last_insert_id()  是mysql中的函数  返回的是最后一次添加的id
-->
    <!--添加用户返回主键-->
    <insert id="addUserReturnId" parameterType="com.codeyancy.cn.entity.User">
        <selectKey keyProperty="id" keyColumn="id" resultType="java.lang.Integer" order="AFTER">
            select last_insert_id()
        </selectKey>
        insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
    </insert>

</mapper>

思考:MyBatis中${} 和 #{} 的区别?推荐使用哪一个?

推荐使用#{}

编写测试代码

UserMapperDemo

public class UserMapperDemo {
    SqlSession sqlSession;
    InputStream resourceAsStream;

    @Before
    public void init(){
    	//配置文件路径
        String path = "mybatis-config.xml";
         resourceAsStream = null;
        try {
        	//通过路径加载配置文件
            resourceAsStream = Resources.getResourceAsStream(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获得sqlsessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //获得sqlSession
        sqlSession = sqlSessionFactory.openSession();
    }

    @Test
    public void test() throws IOException {
        //sqlSession.getMapper() 获取Mapper接口的代理实现类
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        /*List<User> users = mapper.findAll();
        users.forEach(o-> System.out.println(o));*/

        System.out.println(mapper.findById(1));

//        User user = new User();
//        user.setUsername("aaa");
//        mapper.addUser(user);

//        User user = mapper.findById(1);
//        user.setBirthday(new Date());
//        mapper.updateUser(user);

//        mapper.deleteUser(33);

		//模糊查询
        //System.out.println(mapper.findByUserName("名"));

        //添加用户返回主键
        User user = new User();
        user.setUsername("哈哈哈1");
        user.setBirthday(new Date());
        user.setSex("1");
        mapper.addUserReturnId(user);

        System.out.println("添加用户返回主键:"+user.getId());
    }


    @After
    public void destroy(){
        //提交事务
        sqlSession.commit();
        //关闭资源
        sqlSession.close();
        try {
            resourceAsStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

JUnit4常用的几个注解(annotation):

  • @Before:初始化方法 对于每一个测试方法都要执行一次(注意与BeforeClass区别,后者是对于所有方法执行一次)
  • @After:释放资源 对于每一个测试方法都要执行一次(注意与AfterClass区别,后者是对于所有方法执行一次)
  • @Test:测试方法,在这里可以测试期望异常和超时时间
  • @Test(expected=ArithmeticException.class)检查被测方法是否抛出ArithmeticException异常
  • @Ignore:忽略的测试方法
  • @BeforeClass:针对所有测试,只执行一次,且必须为static void
  • @AfterClass:针对所有测试,只执行一次,且必须为static void
  • 一个JUnit4的单元测试用例执行顺序为:
    @BeforeClass -> @Before -> @Test -> @After -> @AfterClass;
  • 每一个测试方法的调用顺序为:
    @Before -> @Test -> @After;

===========================================================================================

关于Maven静态资源过滤问题

java.lang.ExceptionInInitializerError
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/codeyancy/dao/UserMapper.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/codeyancy/dao/UserMapper.xml

解决办法:在pom.xml中添加以下代码过滤

    <!--在build中配置resources,来防止我们资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

配置以上文件后仍然出错的解决办法:
将mybatis-config.xml和UserMapper.xml中的UTF-8中间的 - 去掉即可解决问题!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值