zoukankan      html  css  js  c++  java
  • mybatis学习一:基于xml与注解配置入门实例与问题

    注:本case参考自:http://www.cnblogs.com/ysocean/p/7277545.html

    一:Mybatis的介绍:                                         

    • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
    • iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)。
    • MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。

    二:基于xml配置的入门实例与介绍(idea的maven项目):                                            

    1:case项目结构如图:(pom文件)

        

      几点注意:

      • 有可能idea下Maven项目会很卡,那么调整:Other Setting->default Setting->搜索maven->Runner中:VM Options设置为:-DarchetypeCatalog=internal;
      • main目录下的java使我们自己建的,要将java->右键->Mark Directory as设置为root(否则底下不能建立包文件);

      pom.xml如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <!--
    modelVersion:pom文件的模型版本
    关于group id和artifact id,为了便于多人多模块协同开发管理(以后会讲),建议使用以下命名规范
    group id:com.公司名.项目名
    artifact id:功能模块名
    packaging:项目打包的后缀,war是web项目发布用的,默认为jar
    version:     artifact模块的版本
    name和url:相当于项目描述,可删除
    group id + artifact id +version :项目在仓库中的坐标
       -->
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.company.project</groupId>
        <artifactId>module</artifactId>
        <packaging>war</packaging>
        <version>0.0.1-SNAPSHOT</version>
        <name>test Maven Webapp</name>
        <url>http://maven.apache.org</url>
      <!--上面这部分必须有-->
    
        <dependencies>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.3.0</version>
            </dependency>
            <!--<dependency>这里的jdbc的数据库连接jar总是报错,可以注释掉后从外部导入jar
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.7-bin</version>
            </dependency>-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.12</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.12</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
        </dependencies>
    </project>

    2、创建数据库表:

     1 create database spring_mybatis_test1;
     2 use spring_mybatis_test1;
     3 create table user(
     4     id int(20) not null auto_increment,
     5     username varchar(50) ,
     6     sex varchar(10),
     7     birthday date,
     8     address varchar(100),
     9     primary key(id)
    10 );

     向其中插入一条数据: insert into user(id,username,sex,birthday,address,) values(1,‘tom’,‘男’,'1993-05-25','earth'); 

    补充:下面将要用到的配置参数:

      ①、parameterType:指定输入参数的类型

      ②、resultType:指定输出结果的类型,在select中如果查询结果是集合,那么也表示集合中每个元素的类型

      ③、#{}:表示占位符,用来接收输入参数,类型可以是简单类型,pojo,HashMap等等

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

        如果接收 pojo 对象值,通过 OGNL 读取对象中的属性值,即属性.属性.属性...的方式获取属性值

      ④、${}:表示一个拼接符,会引起 sql 注入,不建议使用  

        用来接收输入参数,类型可以是简单类型,pojo,HashMap等等

        如果接收简单类型,${}里面只能是 value

        如果接收 pojo 对象值,通过 OGNL 读取对象中的属性值,即属性.属性.属性...的方式获取属性值

    3:Mybatis的配置文件mybatis-configuration.xml:(事务,dataSource,userMapper.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标签,当mybatis和spring整合之后,这个标签是不用配置的 -->
    
        <!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境
          一、development:开发模式
           二、work:工作模式-->
        <environments default="development">
            <!--id属性必须和上面的default一样  -->
            <environment id="development">
                <!--事务管理器
                    一、JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围
                    二、MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期
                        比如 spring 或 JEE 应用服务器的上下文,默认情况下,它会关闭连接。然而一些容器并不希望这样,
                        因此如果你需要从连接中停止它,就可以将 closeConnection 属性设置为 false,比如:
                        <transactionManager type="MANAGED">
                            <property name="closeConnection" value="false"/>
                        </transactionManager>
                  -->
                <transactionManager type="JDBC"/>
                <!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源  -->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/spring_mybatis_test1"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <!-- 注册userMapper.xml文件,
            userMapper.xml位于com.ys.mapper这个包下,所以resource写成com/ys/mapper/userMapper.xml-->
            <mapper resource="mapping/userMapping.xml"/>
        </mappers>
    </configuration>

    4:实体类和映射文件userMapper.xml

    • 实体类User:
       1 package com.spring.model;
       2 
       3 import java.util.Date;
       4 public class User {
       5     private int id;
       6     private String username;
       7     private String sex;
       8     private Date birthday;
       9     private String address;
      10     public int getId() {
      11         return id;
      12     }
      13     public void setId(int id) {
      14         this.id = id;
      15     }
      16     public String getUsername() {
      17         return username;
      18     }
      19     public void setUsername(String username) {
      20         this.username = username;
      21     }
      22     public String getSex() {
      23         return sex;
      24     }
      25     public void setSex(String sex) {
      26         this.sex = sex;
      27     }
      28     public Date getBirthday() {
      29         return birthday;
      30     }
      31     public void setBirthday(Date birthday) {
      32         this.birthday = birthday;
      33     }
      34     public String getAddress() {
      35         return address;
      36     }
      37     public void setAddress(String address) {
      38         this.address = address;
      39     }
      40     @Override
      41     public String toString() {
      42         return "User [id=" + id + ", username=" + username + ", sex=" + sex
      43                 + ", birthday=" + birthday + ", address=" + address + "]";
      44     }
      45 }
      View Code
    • 映射文件:注意36-49行的自增主键获取
       1 <?xml version="1.0" encoding="UTF-8" ?>
       2 <!DOCTYPE mapper
       3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
       5 <mapper namespace="user"><!--注意namespace的名称,测试文件中直接引用namespace-->
       6 
       7     <!-- 根据 id 查询 user 表中的数据
       8         id:唯一标识符,此文件中的id值不能重复
       9         resultType:返回值类型,一条数据库记录也就对应实体类的一个对象
      10         parameterType:参数类型,也就是查询条件的类型
      11    -->
      12     <select id="selectUserById"
      13             resultType="com.spring.model.User" parameterType="int">
      14         <!-- 这里和普通的sql 查询语句差不多,后面的 #{id}表示占位符,里面不一定要写id,写啥都可以,但是不要空着 -->
      15         select * from user where id = #{id}
      16     </select>
      17 
      18     <!-- 查询 user 表的所有数据
      19         注意:因为是查询所有数据,所以返回的应该是一个集合,这个集合里面每个元素都是User类型
      20      -->
      21     <select id="selectUserAll" resultType="com.spring.model.User">
      22         select * from user
      23     </select>
      24 
      25     <!-- 模糊查询:根据 user 表的username字段
      26             下面两种写法都可以,但是要注意
      27             1、${value}里面必须要写value,不然会报错
      28             2、${}表示拼接 sql 字符串,将接收到的参数不加任何修饰拼接在sql语句中
      29             3、使用${}会造成 sql 注入
      30      -->
      31     <select id="selectLikeUserName" resultType="com.spring.model.User" parameterType="String">
      32         select * from user where username like '%${value}%'
      33         <!-- select * from user where username like #{username} -->
      34     </select>
      35 
      36     <!-- 向 user 表插入一条数据 -->
      37     <insert id="insertUser" parameterType="com.spring.model.User">
      38         <!-- 将插入的数据主键返回到 user 对象中
      39              keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性
      40              select LAST_INSERT_ID():查询上一次执行insert 操作返回的主键id值,只适用于自增主键
      41              resultType:指定 select LAST_INSERT_ID() 的结果类型
      42              order:AFTER,相对于 select LAST_INSERT_ID()操作的顺序
      43          -->
      44         <selectKey keyProperty="id" resultType="int" order="AFTER">
      45             select LAST_INSERT_ID()
      46         </selectKey>
      47         insert into user(username,sex,birthday,address)
      48         value(#{username},#{sex},#{birthday},#{address})
      49     </insert>
      50 
      51     <!-- 根据 id 更新 user 表的数据 -->
      52     <update id="updateUserById" parameterType="com.spring.model.User">
      53         update user set username=#{username} where id=#{id}
      54     </update>
      55 
      56     <!-- 根据 id 删除 user 表的数据 -->
      57     <delete id="deleteUserById" parameterType="int">
      58         delete from user where id=#{id}
      59     </delete>
      60 </mapper>
        

    5:测试类:

      1 package com.ys.test;
      2  
      3 import java.io.InputStream;
      4 import java.util.List;
      5  
      6 import org.apache.ibatis.session.SqlSession;
      7 import org.apache.ibatis.session.SqlSessionFactory;
      8 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
      9 import org.junit.Before;
     10 import org.junit.Test;
     11  
     14 public class CRUDTest {
     15     //定义 SqlSession
     16     SqlSession session =null;
     17      
     18     @Before
     19     public void init(){
     20         //定义mybatis全局配置文件
     21         String resource = "mybatis-configuration.xml";
     22         //加载 mybatis 全局配置文件
     23         InputStream inputStream = CRUDTest.class.getClassLoader().getResourceAsStream(resource);
     25         //构建sqlSession的工厂
     26         SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
     27         //根据 sqlSessionFactory 产生 session
     28         session = sessionFactory.openSession();
     29     }
     30      
     31     //根据id查询user表数据
     32     @Test
     33     public void testSelectUserById(){
     34         /*这个字符串由 userMapper.xml 文件中 两个部分构成
     35             <mapper namespace="user"> 的 namespace 的值
     36             <select id="selectUserById" > id 值*/
     37         String statement = "user.selectUserById";
     38         User user = session.selectOne(statement, 1);
     39         System.out.println(user);
     40         session.close();
     41     }
     42      
     43     //查询所有user表所有数据
     44     @Test
     45     public void testSelectUserAll(){
     46         String statement = "user.selectUserAll";
     47         List<User> listUser = session.selectList(statement);
     48         for(User user : listUser){
     49             System.out.println(user);
     50         }
     51         session.close();
     52     }
     53      
     54     //模糊查询:根据 user 表的username字段
     55     @Test
     56     public void testSelectLikeUserName(){
     57         String statement = "user.selectLikeUserName";
     58         List<User> listUser = session.selectList(statement, "%t%");
     59         for(User user : listUser){
     60             System.out.println(user);
     61         }
     62         session.close();
     63          
     64     }
     65     //向 user 表中插入一条数据
     66     @Test
     67     public void testInsertUser(){
     68         String statement = "user.insertUser";
     69         User user = new User();
     70         user.setUsername("Bob");
     71         user.setSex("女");
     72         session.insert(statement, user);
     73         //提交插入的数据
     74         session.commit();
     75         session.close();
     76     }
     77      
     78     //根据 id 更新 user 表的数据
     79     @Test
     80     public void testUpdateUserById(){
     81         String statement = "user.updateUserById";
     82         //如果设置的 id不存在,那么数据库没有数据更改
     83         User user = new User();
     84         user.setId(4);
     85         user.setUsername("jim");
     86         session.update(statement, user);
     87         session.commit();
     88         session.close();
     89     }   
     91  
     92     //根据 id 删除 user 表的数据
     93     @Test
     94     public void testDeleteUserById(){
     95         String statement = "user.deleteUserById";
     96         session.delete(statement,4);
     97         session.commit();
     98         session.close();
     99     }
    100 }

    结果:以下我只测试了testSelectUserById和testSelectLikeUserName,两个是一样的: User [id=1, username=tom, sex=男, birthday=Tue May 25 00:00:00 CST 1993, address=earth] 。

    6:获取主键值:

    • 数据库有自增主键:映射配置中的36-49行
       1 <!-- 向 user 表插入一条数据 -->
       2     <insert id="insertUser" parameterType="com.ys.po.User">
       3         <!-- 将插入的数据主键返回到 user 对象中
       4              keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性
       5              select LAST_INSERT_ID():查询上一次执行insert 操作返回的主键id值,只适用于自增主键
       6              resultType:指定 select LAST_INSERT_ID() 的结果类型
       7              order:AFTER,相对于 select LAST_INSERT_ID()操作的顺序
       8          -->
       9         <selectKey keyProperty="id" resultType="int" order="AFTER">
      10             select LAST_INSERT_ID()
      11         </selectKey>
      12         insert into user(username,sex,birthday,address)
      13             value(#{username},#{sex},#{birthday},#{address})
      14     </insert>
    • 非自增主键:
       1 <!-- 向 user 表插入一条数据 -->
       2     <insert id="insertUser" parameterType="com.ys.po.User">
       3         <!-- 将插入的数据主键返回到 user 对象中
       4         流程是:首先通过 select UUID()得到主键值,然后设置到 user 对象的id中,在进行 insert 操作
       5              keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性
       6              select UUID():得到主键的id值,注意这里是字符串
       7              resultType:指定 select UUID() 的结果类型
       8              order:BEFORE,相对于 select UUID()操作的顺序
       9          -->
      10         <selectKey keyProperty="id" resultType="String" order="BEFORE">
      11             select UUID()
      12         </selectKey>
      13         insert into user(id,username,sex,birthday,address)
      14             value(#{id},#{username},#{sex},#{birthday},#{address})
      15     </insert>

    三:基于注解配置的入门实例与介绍(idea的maven项目):                              

    1:我们直接在上面的case中配置注解方式,整个目录结构如下:   

      

    需要改动的地方包括以上三个部分:

    2:不需要动的部分       

    • pom.xml不需要改动;
    • User实体bean不需要改动;
    • userMapping.xml弃用

    3、定义操作user表的注解接口UserMapper.java(接口)     

     1 package com.spring.model;
     2 
     3 import org.apache.ibatis.annotations.Delete;
     4 import org.apache.ibatis.annotations.Insert;
     5 import org.apache.ibatis.annotations.Select;
     6 import org.apache.ibatis.annotations.Update;
     7 
     8 public interface UserMapper {
     9 
    10     //根据 id 查询 user 表数据
    11     @Select("select * from user where id=#{id}")
    12     public User selectUserById(int id) throws  Exception;
    13 
    14     //箱user插入一条数据
    15     @Insert("insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})")
    16     public void insertUser(User user) throws Exception;
    17 
    18     //根据 id 修改 user 表数据
    19     @Update("update user set username=#{username},sex=#{sex} where id=#{id}")
    20     public void updateUserById(User user) throws Exception;
    21 
    22     //根据 id 删除 user 表数据
    23     @Delete("delete from user where id=#{id}")
    24     public void deleteUserById(int id) throws Exception;
    25 }

    4、mybatis-configuration.xml中注册映射接口UserMapper.java   

    1 ......
    2 <mappers>
    3     <!-- xml方式,注册userMapper.xml文件,
    4     userMapper.xml位于com.ys.mapper这个包下,所以resource写成com/ys/mapper/userMapper.xml
    5     <mapper resource="mapping/userMapping.xml"/>-->
    6     <mapper class="com.spring.model.UserMapper"></mapper>
    7 </mappers>

    5、创建测试类  

     1 package com.spring;
     2 
     3 import com.spring.CRUDTest;
     4 import com.spring.model.User;
     5 import com.spring.model.UserMapper;
     6 import org.apache.ibatis.session.SqlSession;
     7 import org.apache.ibatis.session.SqlSessionFactory;
     8 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
     9 import org.junit.Before;
    10 import org.junit.Test;
    11 
    12 import java.io.InputStream;
    13 
    14 public class TestAnnotationCRUD {
    15     SqlSession session=null;
    16 
    17     @Before
    18     public void init(){
    19         //定义mybatis全局配置文件
    20         String resource = "mybatis-configuration.xml";
    21         //加载 mybatis 全局配置文件
    22         InputStream inputStream = CRUDTest.class.getClassLoader().getResourceAsStream(resource);
    23         //构建sqlSession的工厂
    24         SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    25         //根据 sqlSessionFactory 产生 session
    26         session = sessionFactory.openSession();
    27     }
    28 
    29     //注解的增删改查方法测试
    30     @Test
    31     public void testAnncationCRUD() throws Exception {
    32         //根据session获取 UserMapper接口
    33         UserMapper userMapper = session.getMapper(UserMapper.class);
    34         //调用selectUserById()方法
    35         User user = userMapper.selectUserById(1);
    36         System.out.println(user);
    37 
    38         //调用  insertUser() 方法
    39         User user1 = new User();
    40         user1.setUsername("aliks");
    41         user1.setSex("不详");
    42         userMapper.insertUser(user1);
    43 
    44         //调用 updateUserById() 方法
    45         User user2 = new User();
    46         user2.setId(6);
    47         user2.setUsername("lbj");
    48         userMapper.updateUserById(user2);
    49 
    50         //调用 () 方法
    51         userMapper.deleteUserById(6);
    52 
    53         session.commit();
    54         session.close();
    55     }
    56 
    57

    idea输出: User [id=1, username=tom, sex=男, birthday=Tue May 25 00:00:00 CST 1993, address=earth] 

    数据库结果:

    注解配置使我们放弃了映射文件mapping.xml,需要接口实现数据库操作与到方法间的映射

      

      

      

      

     
  • 相关阅读:
    Hugo安装与部署
    R语言 金融数据分析之quantmod (4) 对比多只股票
    R语言 股票数据获取比较 quantmod、tidyquant、pedquant
    R语言 金融数据分析之quantmod (3)
    R语言 金融数据分析之quantmod (2)
    R语言 金融数据分析之quantmod (1)
    R语言 网站数据获取 (rvest)——网络爬虫初学
    mysql查询json中的某个字段
    批量删除以相同前缀开头的表
    leetcode 1879.两个数组最小的异或值之和 模拟退火 KM 状压dp
  • 原文地址:https://www.cnblogs.com/whtblog/p/9071806.html
Copyright © 2011-2022 走看看