Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

9.18 mybatis mapper初涉及,及相关问题 #19

Closed
vieyahn2017 opened this issue Sep 18, 2018 · 11 comments
Closed

9.18 mybatis mapper初涉及,及相关问题 #19

vieyahn2017 opened this issue Sep 18, 2018 · 11 comments

Comments

@vieyahn2017
Copy link
Owner

vieyahn2017 commented Sep 18, 2018

mybatis, mapper

mybatis mapper 做批量插入

mybatis类型转换介绍 TypeHandler

如何优雅的使用mybatis 两种模式

@vieyahn2017
Copy link
Owner Author

vieyahn2017 commented Sep 18, 2018

mybatis 自定义mapper

 <!--批量添加数据-->
 <insert id="addList" parameterType="list" >
   insert into student (id, file_id,first_phone,second_phone) values
   <foreach collection="list" item="union" separator=",">
     (#{union.id},#{union.fileId},#{union.firstPhone},#{union.secondPhone})
   </foreach>
 </insert>
long addList(List<Student> list);   

需要新建mapper,不能在已有mapper上直接加

@vieyahn2017
Copy link
Owner Author

vieyahn2017 commented Sep 18, 2018

使用Mybatis做批量插入
http://quinnhe.iteye.com/blog/1470895

@vieyahn2017
Copy link
Owner Author

9.17

开发问题遗留之:

mybatis如此封装,怎么更改某返回值的格式,比如把Timestamp改成String

参考此文:
http://elim.iteye.com/blog/1847854

Mybatis类型转换介绍

1.1 目录
1.2 建立TypeHandler
1.2.1 TypeHandler接口
1.2.2 BaseTypeHandler抽象类
1.3 注册TypeHandler
1.4 Mybatis自动获取TypeHandler
1.5 Mybatis中自动注册的TypeHandler

@vieyahn2017
Copy link
Owner Author

http://elim.iteye.com/blog/1841033
Mybatis中配置Mapper的方法

@vieyahn2017 vieyahn2017 changed the title 9.18 mybatis解决问题on the way 9.18 mybatis 【all】 Jan 29, 2019
@vieyahn2017
Copy link
Owner Author

vieyahn2017 commented Jan 29, 2019

Example类是什么?
Example类指定如何构建一个动态的where子句. 表中的每个non-BLOB列可以被包括在where子句中. 例子是展示此类用法的最好方式.

Example类可以用来生成一个几乎无限的where子句.

Example类包含一个内部静态类 Criteria 包含一个用 anded 组合在where子句中的条件列表. Example类包含一个 List 属性,所有内部类Criteria中的子句会用 ored组合在一起. 使用不同属性的 Criteria 类允许您生成无限类型的where子句.

创建 Criteria 对象 可以使用Example类中的 createCriteria() 或者 or() . 如果 Criteria 对象是用 createCriteria() 创建的,它会自动为 List 属性添加一个 Criteria 对象 - 这使得它更容易写一个简单的where子句, 如果您不需要 or 或者其他几个子句组合的话. 用 or(Criteria criteria) 方法创建 Criteria 对象, 方法里的 criteria 对象会被添加进 Criteria 对象的列表中.

重要 我们推荐您只使用 or() 方法创建 Criteria 对象. 我们相信这种方法使代码更有可读性.

原文:https://blog.csdn.net/zhemeban/article/details/71901759

@vieyahn2017
Copy link
Owner Author

vieyahn2017 commented Jan 29, 2019

mybatis中的mapper接口文件以及example类的实例函数以及详解
https://blog.csdn.net/paincupid/article/details/50921110

    ##Example example = new ##Example();  
    example.setOrderByClause("字段名 ASC"); //升序排列,desc为降序排列。  
    example.setDistinct(false)//去除重复,boolean型,true为选择不重复的记录。  
    Criteria criteria = new Example().createCriteria();  
    is null;is not null;  
    equal to(value);not equal to(value);  
    GreaterThan(value);GreaterThanOrEqualTo(value);  
    LessThan(value); LessThanOrEqualTo(value);  
    in(item,item,item,...);not in(item,item,item,...);  
    like("%"+value+"%");not like("%"+value+"%");  
    Between(value1,value2);not between(value1,value2)  
      
       
      
//    mybatis中mapper的实例函数:  
    int countByExample(UserExample example) thorws SQLException按条件计数。  
    int deleteByPrimaryKey(Integer id) thorws SQLException按主键删除。  
    int deleteByExample(UserExample example) thorws SQLException按条件删除String/Integer insert(User record) thorws SQLException插入(返回值为id值)  
    User selectByPrimaryKey(Integer id) thorws SQLException按主键查询List<?>selectByExample(UserExample example) thorws SQLException按条件查询  
    List<?>selectByExampleWithBLOGs(UserExample example) thorws SQLException  
      
//    条件查询(包括BLOB字段)。只有当数据表中的字段类型有为二进制的才会产生。  
    int updateByPrimaryKey(User record) thorws SQLException按主键更新  
    int updateByPrimaryKeySelective(User record) thorws SQLException按主键更新  
      
//    值不为null的字段  
    int updateByExample(User record, UserExample example) thorws SQLException按条件更新  
    int updateByExampleSelective(User record, UserExample example) thorws    
      
    SQLException按条件更新值不为null的字段  
      
    mybatis中mapper的实例函数详解//    ① selectByPrimaryKey()  
      
    User user = ##Mapper.selectByPrimaryKey(100); 相当于select * from user where  
      
    id = 100  
      
//    ② selectByExample() 和 selectByExampleWithBLOGs()  
      
    UserExample example = new UserExample();  
    Criteria criteria = example.createCriteria();  
    criteria.andUsernameEqualTo("joe");  
    criteria.andUsernameIsNull();  
    example.setOrderByClause("username asc,email desc");  
    List<?>list = ##Mapper.selectByExample(example);  
    相当于select * from user where username = 'joe' and username is null order  
      
    by username asc,email desc  
      
    在iBator 生成的文件UserExample.java中包含一个static 的内部类 Criteria在Criteria中有很多方法主要是定义SQL 语句where后的查询条件//    ③ insert()  
      
    User user = new User();  
    user.setId(101);  
    user.setUsername("test");  
    user.setPassword("123")  
    user.setEmail("joe@163.com");  
    ##Mapper.insert(user);  
    相当于insert into user(ID,username,password,email) values  
      
    (101,'test','123','joe@163.com');  
      
//     ④ updateByPrimaryKey() 和 updateByPrimaryKeySelective()  
      
    User user =new User();  
    user.setId(101);  
    user.setUsername("joe");  
    user.setPassword("joe");  
    user.setEmail("joe@163.com");  
    ##Mapper.updateByPrimaryKey(user);  
    相当于update user set username='joe',password='joe',email='joe@163.com'  
      
    where id=101  
      
    User user = new User();  
    user.setId(101);  
    user.setPassword("joe");  
    ##Mapper.updateByPrimaryKeySelective(user);  
    相当于update user set password='joe' where id=101  
      
//    ⑤ updateByExample() 和 updateByExampleSelective()  
      
    UserExample example = new UserExample();  
    Criteria criteria = example.createCriteria();  
    criteria.andUsernameEqualTo("joe");  
    User user = new User();  
    user.setPassword("123");  
    ##Mapper.updateByPrimaryKeySelective(user,example);  
    相当于update user set password='123' where username='joe'  
      
    
//⑥ deleteByPrimaryKey()  
      
    ##Mapper.deleteByPrimaryKey(101);  相当于delete from user where id=101  
      
//    ⑦ deleteByExample()  
      
    UserExample example = new UserExample();  
    Criteria criteria = example.createCriteria();  
    criteria.andUsernameEqualTo("joe");  
    ##Mapper.deleteByExample(example);  
    相当于delete from user where username='joe'  
      
//    ⑧ countByExample()  
      
    UserExample example = new UserExample();  
    Criteria criteria = example.createCriteria();  
    criteria.andUsernameEqualTo("joe");  
    int count = ##Mapper.countByExample(example);  
    相当于select count(*) from user where username='joe'  

@vieyahn2017
Copy link
Owner Author

vieyahn2017 commented Jan 29, 2019

https://github.com/abel533/Mapper/wiki

MyBatis 通用 Mapper4

通用 Mapper4 是一个可以实现任意 MyBatis 通用方法的框架,项目提供了常规的增删改查操作以及Example 相关的单表操作。通用 Mapper 是为了解决 MyBatis 使用中 90% 的基本操作,使用它可以很方便的进行开发,可以节省开发人员大量的时间。

@vieyahn2017
Copy link
Owner Author

vieyahn2017 commented Jan 29, 2019

spring boot(六):如何优雅的使用mybatis

https://www.cnblogs.com/ityouknow/p/6037431.html

这两天启动了一个新项目因为项目组成员一直都使用的是mybatis,虽然个人比较喜欢jpa这种极简的模式,但是为了项目保持统一性技术选型还是定了 mybatis。到网上找了一下关于spring boot和mybatis组合的相关资料,各种各样的形式都有,看的人心累,结合了mybatis的官方demo和文档终于找到了最简的两种模式,花了一天时间总结后分享出来。

orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sql的mybatis,两者各有特点,在企业级系统开发中可以根据需求灵活使用。发现一个有趣的现象:传统企业大都喜欢使用hibernate,互联网行业通常使用mybatis。

hibernate特点就是所有的sql都用Java代码来生成,不用跳出程序去写(看)sql,有着编程的完整性,发展到最顶端就是spring data jpa这种模式了,基本上根据方法名就可以生成对应的sql了,有不太了解的可以看我的上篇文章springboot(五):spring data jpa的使用(http://www.ityouknow.com/springboot/2016/08/20/springboot(%E4%BA%94)-spring-data-jpa%E7%9A%84%E4%BD%BF%E7%94%A8.html)。

mybatis初期使用比较麻烦,需要各种配置文件、实体类、dao层映射关联、还有一大推其它配置。当然mybatis也发现了这种弊端,初期开发了generator可以根据表结果自动生产实体类、配置文件和dao层代码,可以减轻一部分开发量;后期也进行了大量的优化可以使用注解了,自动管理dao层和配置文件等,发展到最顶端就是今天要讲的这种模式了,

mybatis-spring-boot-starter就是springboot+mybatis可以完全注解不用配置文件,也可以简单配置轻松上手。

首先引入mybatis-spring-boot-starter的pom文件,现在最新版本是1.1.1(刚好快到双11了 :))

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.1.1</version>
</dependency>

下来分别介绍两种开发模式

无配置文件注解版

极简xml版本

@vieyahn2017 vieyahn2017 changed the title 9.18 mybatis 【all】 9.18 mybatis mapper初涉及,及相关问题 Jan 30, 2019
@vieyahn2017
Copy link
Owner Author

无配置文件注解版

就是一切使用注解搞定。

1 添加相关maven文件

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.1.1</version>
    </dependency>
     <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

完整的pom包这里就不贴了,大家直接看源码

2、application.properties 添加相关配置

mybatis.type-aliases-package=com.neo.entity

spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = root

springboot会自动加载spring.datasource.*相关配置,数据源就会自动注入到sqlSessionFactory中,sqlSessionFactory会自动注入到Mapper中,对了你一切都不用管了,直接拿起来使用就行了。

在启动类中添加对mapper包扫描@MapperScan

@SpringBootApplication
@MapperScan("com.neo.mapper")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

或者直接在Mapper类上面添加注解@Mapper,建议使用上面那种,不然每个mapper加个注解也挺麻烦的

3、开发Mapper

第三步是最关键的一块,sql生产都在这里

public interface UserMapper {

    @Select("SELECT * FROM users")
    @Results({
        @Result(property = "userSex",  column = "user_sex", javaType = UserSexEnum.class),
        @Result(property = "nickName", column = "nick_name")
    })
    List<UserEntity> getAll();

    @Select("SELECT * FROM users WHERE id = #{id}")
    @Results({
        @Result(property = "userSex",  column = "user_sex", javaType = UserSexEnum.class),
        @Result(property = "nickName", column = "nick_name")
    })
    UserEntity getOne(Long id);

    @Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
    void insert(UserEntity user);

    @Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
    void update(UserEntity user);

    @Delete("DELETE FROM users WHERE id =#{id}")
    void delete(Long id);

}

为了更接近生产我特地将user_sex、nick_name两个属性在数据库加了下划线和实体类属性名不一致,另外user_sex使用了枚举

@select 是查询类的注解,所有的查询均使用这个
@Result 修饰返回的结果集,关联实体类属性和数据库字段一一对应,如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。
@insert 插入数据库使用,直接传入实体类会自动解析属性到对应的值
@update 负责修改,也可以直接传入对象
@delete 负责删除
了解更多属性参考这里

注意,使用#符号和$符号的不同:

// This example creates a prepared statement, something like select * from teacher where name = ?;
@Select("Select * from teacher where name = #{name}")
Teacher selectTeachForGivenName(@Param("name") String name);

// This example creates n inlined statement, something like select * from teacher where name = 'someName';
@Select("Select * from teacher where name = '${name}'")
Teacher selectTeachForGivenName(@Param("name") String name);

4、使用

上面三步就基本完成了相关dao层开发,使用的时候当作普通的类注入进入就可以了

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper UserMapper;

    @Test
    public void testInsert() throws Exception {
        UserMapper.insert(new UserEntity("aa", "a123456", UserSexEnum.MAN));
        UserMapper.insert(new UserEntity("bb", "b123456", UserSexEnum.WOMAN));
        UserMapper.insert(new UserEntity("cc", "b123456", UserSexEnum.WOMAN));

        Assert.assertEquals(3, UserMapper.getAll().size());
    }

    @Test
    public void testQuery() throws Exception {
        List<UserEntity> users = UserMapper.getAll();
        System.out.println(users.toString());
    }

    @Test
    public void testUpdate() throws Exception {
        UserEntity user = UserMapper.getOne(3l);
        System.out.println(user.toString());
        user.setNickName("neo");
        UserMapper.update(user);
        Assert.assertTrue(("neo".equals(UserMapper.getOne(3l).getNickName())));
    }
}

源码中controler层有完整的增删改查,这里就不贴了
源码在这里spring-boot-mybatis-annotation
https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-annotation

@vieyahn2017
Copy link
Owner Author

极简xml版本

极简xml版本
极简xml版本保持映射文件的老传统,优化主要体现在不需要实现dao的是实现层,系统会自动根据方法名在映射文件中找对应的sql.

1、配置

pom文件和上个版本一样,只是application.properties新增以下配置

mybatis.config-locations=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

指定了mybatis基础配置文件和实体类映射文件的地址

mybatis-config.xml 配置

<configuration>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer" />
        <typeAlias alias="Long" type="java.lang.Long" />
        <typeAlias alias="HashMap" type="java.util.HashMap" />
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
        <typeAlias alias="ArrayList" type="java.util.ArrayList" />
        <typeAlias alias="LinkedList" type="java.util.LinkedList" />
    </typeAliases>
</configuration>

这里也可以添加一些mybatis基础的配置

2、添加User的映射文件

<mapper namespace="com.neo.mapper.UserMapper" >
    <resultMap id="BaseResultMap" type="com.neo.entity.UserEntity" >
        <id column="id" property="id" jdbcType="BIGINT" />
        <result column="userName" property="userName" jdbcType="VARCHAR" />
        <result column="passWord" property="passWord" jdbcType="VARCHAR" />
        <result column="user_sex" property="userSex" javaType="com.neo.enums.UserSexEnum"/>
        <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
    </resultMap>

    <sql id="Base_Column_List" >
        id, userName, passWord, user_sex, nick_name
    </sql>

    <select id="getAll" resultMap="BaseResultMap"  >
       SELECT 
       <include refid="Base_Column_List" />
       FROM users
    </select>

    <select id="getOne" parameterType="java.lang.Long" resultMap="BaseResultMap" >
        SELECT 
       <include refid="Base_Column_List" />
       FROM users
       WHERE id = #{id}
    </select>

    <insert id="insert" parameterType="com.neo.entity.UserEntity" >
       INSERT INTO 
            users
            (userName,passWord,user_sex) 
        VALUES
            (#{userName}, #{passWord}, #{userSex})
    </insert>

    <update id="update" parameterType="com.neo.entity.UserEntity" >
       UPDATE 
            users 
       SET 
        <if test="userName != null">userName = #{userName},</if>
        <if test="passWord != null">passWord = #{passWord},</if>
        nick_name = #{nickName}
       WHERE 
            id = #{id}
    </update>

    <delete id="delete" parameterType="java.lang.Long" >
       DELETE FROM
             users 
       WHERE 
             id =#{id}
    </delete>
</mapper>

其实就是把上个版本中mapper的sql搬到了这里的xml中了

3、编写Dao层的代码

public interface UserMapper {

    List<UserEntity> getAll();

    UserEntity getOne(Long id);

    void insert(UserEntity user);

    void update(UserEntity user);

    void delete(Long id);

}

对比上一步这里全部只剩了接口方法

###4、使用
使用和上个版本没有任何区别,大家就看代码吧

xml配置版本
https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-xml

@vieyahn2017
Copy link
Owner Author

如何选择
两种模式各有特点,注解版适合简单快速的模式,其实像现在流行的这种微服务模式,一个微服务就会对应一个自已的数据库,多表连接查询的需求会大大的降低,会越来越适合这种模式。

老传统模式比适合大型项目,可以灵活的动态生成SQL,方便调整SQL,也有痛痛快快,洋洋洒洒的写SQL的感觉。

完整代码地址

作者:纯洁的微笑
出处:http://www.ityouknow.com/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant