J2EE 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 Old Java Objects,普通的 Java对象)映射成数据库中的记录
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。
用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
 
 
 
 
mybatis自动生成:
mybatis-generator有三种用法:命令行、eclipse插件、maven插件。个人觉得maven插件最方便,可以在eclipse/intellij idea等ide上可以通用。
<plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.2</version>

<!--
mybatis-generator-maven-plugin会默认读取src/main/resources的generatorConfig.xml文件,

<configuration>
<configurationFile>src/main/resources/mybatis-generator/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
-->

 
    <executions>
        <execution>
            <id>Generate MyBatis Artifacts</id>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>
</plugin>

plugin要放在<pluginManagement> 之内。

一张表:

CREATE TABLE `test`.`teacher` (
`id` bigint NOT NULL DEFAULT 0 COMMENT '主键id',
`name` varchar(40) NOT NULL DEFAULT '' COMMENT '名称',
`age` smallint NOT NULL DEFAULT 0 COMMENT '年龄',
PRIMARY KEY (`id`)
) COMMENT='教师表';
 
需求1:为数据库中的表teacher生成Teacher.java, TeacherMapper.java, TeacherMapper.xml

在resources下新建一个文件database.properties.

 内容如下;

# 数据库驱动jar 路径
drive.class.path=F:/xampp/tomcat/webapps/mybatisuse/target/mybatisuse/WEB-INF/lib/mysql-connector-java-5.1.25.jar
 
 
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.1.156:3306/game_central
jdbc.username=root
jdbc.password=0987abc123
 
# 包路径配置
model.package=com.data.model
dao.package=com.data.dao
xml.mapper.package=com.data.dao

target.project=src/main/java
Œ…

在resoucess下新建:generatorConfig.xml ,配置文件内容如下;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 配置文件路径 -->
<properties resource="database.properties"/>
 
<!--数据库驱动包路径 -->
<classPathEntry location="${drive.class.path}"/>
 
<context id="MySQLTables" targetRuntime="MyBatis3">
<!--关闭注释 -->
<commentGenerator>
<property name="suppressDate" value="true"/>
</commentGenerator>
 
<!--数据库连接信息 -->
<jdbcConnection driverClass="${jdbc.driver}" connectionURL="${jdbc.url}" userId="${jdbc.username}"
password="${jdbc.password}">
</jdbcConnection>
 
<!--生成的model 包路径 -->
<javaModelGenerator targetPackage="${model.package}" targetProject="${target.project}">
<property name="enableSubPackages" value="ture"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
 
<!--生成xml mapper文件 路径 -->
<sqlMapGenerator targetPackage="${xml.mapper.package}" targetProject="${target.project}">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
 
<!-- 生成的Dao接口 的包路径 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="${dao.package}" targetProject="${target.project}">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
 
<!--对应数据库表名 -->
<table tableName="teacher">
 
</table>
</context>
</generatorConfiguration>

 根节点<generatorConfiguration>

generatorConfiguration节点没有任何属性,直接写节点即可,如下:

<generatorConfiguration>
    <!-- 具体配置内容 -->
</generatorConfiguration>  

3. <generatorConfiguration>子元素

从这段开始,就是配置的主要内容,这些配置都是generatorConfiguration元素的子元素。

包含以下子元素(有严格的顺序):

  1. <properties> (0个或1个)

  2. <classPathEntry> (0个或多个)

  3. <context> (1个或多个)

3.1 <properties> 元素

这个元素用来指定外部的属性元素,不是必须的元素。

元素用于指定一个需要在配置中解析使用的外部属性文件,引入属性文件后,可以在配置中使用 ${property}这种形式的引用,通过这种方式引用属性文件中的属性值。 对于后面需要配置的**jdbc信息**和targetProject属性会很有用。

这个属性可以通过resource或者url来指定属性文件的位置,这两个属性只能使用其中一个来指定,同时出现会报错。

  • resource:指定**classpath**下的属性文件,使用类似com/myproject/generatorConfig.properties这样的属性值。

  • url:可以指定文件系统上的特定位置,例如file:///C:/myfolder/generatorConfig.properties

3.2 <classPathEntry> 元素

这个元素可以0或多个,不受限制。

最常见的用法是通过这个属性指定驱动的路径,例如:

<classPathEntry location="E:mysqlmysql-connector-java-5.1.29.jar"/>

重点提醒:本文之前在这里有误导,特别强调。

注意,classPathEntry只在下面这两种情况下才有效

  • 当加载 JDBC 驱动内省数据库时
  • 当加载根类中的 JavaModelGenerator 检查重写的方法时
因此,如果你需要加载其他用途的jar包,classPathEntry起不到作用,不能这么写,解决的办法就是将你用的jar包添加到类路径中,在Eclipse等IDE中运行的时候,添加jar包比较容易。当从命令行执行的时候,需要用java -cp xx.jar,xx2.jar xxxMainClass这种方式在-cp后面指定来使用(注意-jar会导致-cp无效)。

使用方式:

mvn mybatis-generator:generate

就可以在我们配置的路径看到生成的java文件和xml文件了。

加参数:

mvn  mybatis-generator:generate -Dmybatis.generator.overwrite=true

表示强制重载已经存在了的同名文件。

 建表时,字段名称建议用"_"分隔多个单词,比如:AWB_NO、REC_ID...,这样生成的entity,属性名称就会变成漂亮的驼峰命名,即:awbNo、recId

参考:

MyBatis-Generator最佳实践

MyBatis Generator 详解

基础接口 Select

接口:SelectMapper<T>
方法:List<T> select(T record);
说明:根据实体中的属性值进行查询,查询条件使用等号

mapper对应的配置文件:

<!-- 此处namespace需要指定dao接口 -->
<mapper namespace="com.mymaven.mybatisdemo.dao.DepartmentMapper">
    <!--配置一个resultMap 指定返回的类型 -->
    <resultMap id="departMent" type="Department">
        <id column="dp_id" property="dp_id" />
        <result column="dp_name" property="dp_name" />
        <result column="cost_center" property="cost_center" />
    </resultMap>


    <!-- 返回一个list的写法 -->
    <select id="queryAllDepartment"  resultMap="departMent" >
        select * from t_department

    </select>


   
</mapper>

注意
<select id="queryAllDepartment"  resultMap="departMent" 这里返回类型是resultMap,不是ResultType.这个我搞错了。。。

注意:上述UserMapper.xml文件中resultType表明:如果返回的是是一个集合,要写集合中元素的类型,不能写成java.util.List,否则查询会报错,下面我们演示一下这种情况

♦修改UserMapper.xml文件,配置如下:

<select id="getAllUsers" resultType="java.util.List">
	select id, loginId, userName, role, note from t_user
</select>




https://www.cnblogs.com/dongying/p/4048828.html


深入理解Mybatis中的resultType和resultMap

MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的(对应着我们的model对象中的实体),而resultMap则是对外部ResultMap的引用(提前定义了db和model之间的隐射key-->value关系),但是resultType跟resultMap不能同时存在。

在MyBatis进行查询映射时,其实查询出来的每一个属性都是放在一个对应的Map里面的,其中键是属性名,值则是其对应的值。

①当提供的返回类型属性是resultType时,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。所以其实MyBatis的每一个查询映射的返回类型都是ResultMap,只是当提供的返回类型属性是resultType的时候,MyBatis对自动的给把对应的值赋给resultType所指定对象的属性。

②当提供的返回类型是resultMap时,因为Map不能很好表示领域模型,就需要自己再进一步的把它转化为对应的对象,这常常在复杂查询中很有作用

 二、ResultType
Blog.java
public class Blog {
private int id;
private String title;
private String content;
private String owner;
private List<Comment> comments;
}
其所对应的数据库表中存储有id、title、Content、Owner属性。
<typeAlias alias="Blog" type="com.tiantian.mybatis.model.Blog"/>
<select id="selectBlog" parameterType="int" resultType="Blog">
select * from t_blog where id = #{id}
</select>
MyBatis会自动创建一个ResultMap对象,然后基于查找出来的属性名进行键值对封装,然后再看到返回类型是Blog对象,再从ResultMap中取出与Blog对象对应的键值对进行赋值。


三、ResultMap
当返回类型直接是一个ResultMap的时候也是非常有用的,这主要用在进行复杂联合查询上,因为进行简单查询是没有什么必要的。先看看一个返回类型为ResultMap的简单查询,再看看复杂查询的用法。

①简单查询的写法
<resultMap type="Blog" id="BlogResult">
<id column="id" property="id"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="owner" property="owner"/>
</resultMap>
<select id="selectBlog" parameterType="int" resultMap="BlogResult">
select * from t_blog where id = #{id}
</select>
select映射中resultMap的值是一个外部resultMap的id,表示返回结果映射到哪一个resultMap上,外部resultMap的type属性表示该resultMap的结果是一个什么样的类型,这里是Blog类型,那么MyBatis就会把它当作一个Blog对象取出。resultMap节点的子节点id是用于标识该对象的id的,而result子节点则是用于标识一些简单属性的,其中的Column属性表示从数据库中查询的属性,Property则表示查询出来的属性对应的值赋给实体对象的哪个属性。简单查询的resultMap的写法就是这样的。

②复杂查询
有一个Comment类,其中有一个Blog的引用,表示是对哪个Blog的Comment,那么在查询Comment的时候把其对应的Blog也要查出来赋给其blog属性。
public class Comment {
private int id;
private String content;
private Date commentDate = new Date();
private Blog blog;
}
<!--来自CommentMapper.xml文件-->
<resultMap type="Comment" id="CommentResult">
<association property="blog" select="selectBlog" column="blog" javaType="Blog"/>
</resultMap>

<select id="selectComment" parameterType="int" resultMap="CommentResult">
select * from t_Comment where id = #{id}
</select>

<select id="selectBlog" parameterType="int" resultType="Blog">
select * from t_Blog where id = #{id}
</select>

先是请求id为selectComment的select映射,然后得到一个id为CommentResult的ResultMap对象,可以看到在对应的resultMap的返回类型是一个Comment对象,其中只有一个association节点,而没有像前面说的简单查询所对应的id、result子节点,但是其仍会把对应的id等属性赋给Comment对象,这就是前面所说的MyBatis拥有自动封装功能,只要提供了返回类型,MyBatis会根据自己的判断来利用查询结果封装对应的对象,所以前面的简单查询中,如果不在resultMap中明确的指出id对应哪个字段,title对应哪个字段,MyBatis也会根据自身的判断来帮封装,MyBatis的自身判断是把查询的field或其对应的别名与返回对象的属性进行比较,如果相匹配且类型也相匹配,MyBatis则会对其进行赋值。在上面对应的resultMap中关联了一个blog属性,其对应的java类型为Blog,在上述的写法中,关联对象是通过子查询来进行关联的,当然也可以直接通过关联查询来进行关联。上面的association子节点中,Property属性表示是resultMap返回类型的哪个关联属性,对于上面的例子就是Comment管理的blog属性;select表示进行哪个select映射来映射对应的关联属性,即会去请求id为select所对应的值的select映射 来查询出其所关联的属性对象;Column表示当前关联对象在id为CommentResult的resultMap中所对应的键值对,该键值对将作为对关联对象子查询的参数,即将把在selectComment中查询出来的blog属性的值作为参数传给进行关联对象blog的子查询selectBlog的参数;javaType表示当前关联对象在JAVA中是什么类型。


上述介绍的是一对一或一对多的情况下,对一对一方的关联的查询。在实际应用中还有一个用的比较多的应用是通过一对一方查出对应的多的一方,在拿出多的一方的时候也同样要把一对一方关联上:在拿出Blog对象时,就把其对应的Comment全部拿出来,在拿出Comment的时候也还是需要把其对应的Blog拿出来,这是在java中通过一次请求就拿出来的。

<!-- 来自BlogMapper.xml文件 -->
<resultMap type="Blog" id="BlogResult">
<id column="id" property="id"/>
<collection property="comments" select="selectCommentsByBlog" column="id" ofType="Comment"></collection>
</resultMap>

<resultMap type="Comment" id="CommentResult">
<association property="blog" javaType="Blog" column="blog" select="selectBlog"/>
</resultMap>

<select id="selectBlog" parameterType="int" resultMap="BlogResult">
select * from t_blog where id = #{id}
  </select>

  <select id="selectCommentsByBlog" parameterType="int" resultMap="CommentResult">
  select * from t_Comment where blog = #{blogId}
  </select>

上述请求的入口是id为selectBlog的select映射,返回结果为id为BlogResult的resultMap,id为BlogResult的类型为Blog,其中指定了id的属性和字段,指定id将对MyBatis内部的构造作用非常大。其中关联了一个comments对象,因为一个Blog可以有很多Comment,该comments为一个集合,所以用集合collection进行映射,其中的select还是表示进行哪个子查询来查询对应的comments,column表示把上述查出来的哪个字段值当作参数传给子查询,ofType也是表示返回类型,这里的返回类型是集合内部的类型,之所以用ofType而不是用type是MyBatis内部为了和关联association进行区别。 

public void selectCommentsByBlogTest() {
SqlSession session = Util.getSqlSessionFactory().openSession();
CommentMapper commentMapper = session.getMapper(CommentMapper.class);
List<Comment> comments = commentMapper.selectCommentsByBlog(6);
for (Comment comment : comments)
System.out.println(comment);
session.close();
}

public void testSelectOne() {
SqlSession session = Util.getSqlSessionFactory().openSession();
BlogMapper blogMapper = session.getMapper(BlogMapper.class);
Blog blog = blogMapper.selectBlog(6);
List<Comment> comments = blog.getComments();
if (comments != null) {
for (Comment comment : comments)
System.out.println(comment);
}
session.close();
}

原帖地址:http://haohaoxuexi.iteye.com/blog/1337009
 
 
 

MyBatis 通过包含的jdbcType类型

BIT         FLOAT      CHAR           TIMESTAMP       OTHER       UNDEFINED

TINYINT     REAL       VARCHAR        BINARY          BLOB        NVARCHAR

SMALLINT    DOUBLE     LONGVARCHAR    VARBINARY       CLOB        NCHAR

INTEGER     NUMERIC    DATE           LONGVARBINARY   BOOLEAN     NCLOB

BIGINT      DECIMAL    TIME           NULL            CURSOR

MybatisjavaTypejdbcType对应和CRUD例子

MybatisjavaTypejdbcType对应关系

JDBC Type			Java Type
CHAR				String
VARCHAR				String
LONGVARCHAR			String
NUMERIC				java.math.BigDecimal
DECIMAL				java.math.BigDecimal
BIT				boolean
BOOLEAN				boolean
TINYINT				byte
SMALLINT			short
INTEGER				int
BIGINT				long
REAL				float
FLOAT				double
DOUBLE				double
BINARY				byte[]
VARBINARY			byte[]
LONGVARBINARY		        byte[]
DATE				java.sql.Date
TIME				java.sql.Time
TIMESTAMP			java.sql.Timestamp
CLOB				Clob
BLOB				Blob
ARRAY				Array
DISTINCT			mapping of underlying type
STRUCT				Struct
REF	                        Ref
 
 

mybatis关于日期的陷阱

 

  1.mybatis 3.3.0(及以上?,博主的是3.4.0问题依然存在)中对于时间参数进行比较时的一个问题, 如果拿传入的时间类型参数与空字符串' '进行对比判断则会引发异常,即只需做非空判断即可<if test="createTime != null"> ...</if>。
  2.mysql中字段为datetimeZ类型,即年月日时分秒,这时前台若想传一个年月日的字符串来查找,可以使用,通过date()函数将年月日时分秒的日期截取为年月日

 
 
原文地址:https://www.cnblogs.com/youxin/p/5323052.html