parameterType:即将传入的语句参数的完全限定类名和别名。这个属性是可选项的,因为MyBatis可以推断出传入语句的具体参数,因此不建议配置该属性
flushCache:默认值为true,任何时候只要语句被调用,都会清空一级缓存和二级缓存
useGeneratedKeys默认值为false。如果设置为true,MyBatis会使用JDBC的getGeneratedKeys方法来取出由数据库内部生成的主键
keyProperty:MyBatis通过getGeneratedKeys获取主键值后将要赋值的属性名。如果希望得到多个数据库自动生成的列,属性值也可以是以逗号分隔的属性名称列表
此处<insert>中的SQL就是一个简单的INSERT语句,将所有的列都列举出来,在values中通过#{property}方式从参数中取出属性的值。
为了防止类型错误,对于一些特殊的数据类型,建议指定具体的jdbcType值。例如,icon字段指定BLOB类型,createTime指定TIMESTAMP类型
tips:
BLOB对应的类型是ByteArrayInputStream,就是二进制数据流
由于数据库区分date,time,dataTime类型,但是Java中一般都使用java.util.Date类型。因此为了保证数据类型的正确,需要手动指定日期类型,date,time,datetime对应的JDBC类型的DATE,TIME,TIMESTAMP
<insert id="insertSysUser" parameterType="user" useGeneratedKeys="true" keyProperty="id" > insert into sys_user ( user_name, user_password, user_email, icon, create_time ) values ( #{userName}, #{userPassword}, #{userEmail}, #{icon,jdbcType=BLOB}, #{createTime,jdbcType=TIMESTAMP} ) </insert>
<insert id="insertSysUser" > insert into sys_user ( user_name, user_password, user_email, icon, create_time ) values ( #{userName}, #{userPassword}, #{userEmail}, #{icon,jdbcType=BLOB}, #{createTime,jdbcType=TIMESTAMP} ) <selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER" > select LAST_INSERT_ID() </selectKey> </insert>
selectKey标签的keyColumn、keyProperty和上面useGeneratedKeys的用法含义相同,这里的resultType用于设置返回值类型。order属性的设置和使用的数据库有关。
在MySQL数据库中,order属性设置的值是AFTER,因为当前记录的主键值在insert语句执行成功后才能获取到。
而Oracle数据库中,order的值要设置为BEFORE,这是因为Oracle中需要先从序列获取值,然后将值作为主键插入到数据库中
http://www.mybatis.org/mybatis-3/zh/configuration.html
What is the difference between #{...} and ${...}?
MyBatis interprets #{...} as a parameter marker in a JDBC prepared statement. MyBatis interprets ${...} as string substitution. It is important to know the difference because parameter markers cannot be used in certain places in SQL statements.
For example, you cannot use a parameter marker to specify a table name.
Given the following code:
Map<String, Object> parms = new HashMap<String, Object>(); parms.put("table", "foo"); parms.put("criteria", 37); List<Object> rows = mapper.generalSelect(parms);
<select id="generalSelect" parameterType="map"> select * from ${table} where col1 = #{criteria} </select>
MyBatis will generate the following prepared statement:
select * from foo where col1 = ?
Important: note that use of ${...} (string substitution) presents a risk for SQL injection attacks. Also, string substitution can be problematical for complex types like dates. For these reasons, we recommend using the #{...} form whenever possible.
How do I code an SQL LIKE?
There are two methods. In the first (and preferred) method, you append the SQL wildcards in your Java code.
For example:
String wildcardName = "%Smi%"; List<Name> names = mapper.selectLike(wildcardName);
<select id="selectLike"> select * from foo where bar like #{value} </select>
Another method is to concatenate the wildcards in your SQL. This method is less safe than the method above because of possible SQL injection.
For example:
String wildcardName = "Smi"; List<Name> names = mapper.selectLike(wildcardName);
<select id="selectLike"> select * from foo where bar like '%' || '${value}' || '%' </select>
Important: Note the use of $ vs. # in the second example!
How do I code a batch insert?
First, code a simple insert statement like this:
<insert id="insertName"> insert into names (name) values (#{value}) </insert>
Then execute a batch in Java code like this:
List<String> names = new ArrayList<String>(); names.add("Fred"); names.add("Barney"); names.add("Betty"); names.add("Wilma"); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { NameMapper mapper = sqlSession.getMapper(NameMapper.class); for (String name : names) { mapper.insertName(name); } sqlSession.commit(); } finally { sqlSession.close(); }
How can I retrieve the value of an auto generated key?
The insert method always returns an int - which is the number of rows inserted. Auto generated key values are placed into the parameter object and are available after the completion of the insert method.
For example:
<insert id="insertName" useGeneratedKeys="true" keyProperty="id"> insert into names (name) values (#{name}) </insert>
Name name = new Name(); name.setName("Fred"); int rows = mapper.insertName(name); System.out.println("rows inserted = " + rows); System.out.println("generated key value = " + name.getId());
https://github.com/mybatis/mybatis-3/wiki/FAQ#how-do-i-code-a-batch-insert
userDao-mapping.xml相当于是UserDao的实现, 同时也将User实体类与数据表User成功关联起来。
再编写一个userDao-mapping.xml (可随便命名):
userDao-mapping.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"> <mapper namespace="com.dy.dao.UserDao"> <select id="findUserById" resultType="com.dy.entity.User" > select * from user where id = #{id} </select> </mapper>
package com.dy.entity; public class User { private int id; private String name; private String password; private int age; private int deleteFlag; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getDeleteFlag() { return deleteFlag; } public void setDeleteFlag(int deleteFlag) { this.deleteFlag = deleteFlag; } }
再编写一个UserDao 接口:
UserDao:
package com.dy.dao; import java.util.List; import com.dy.entity.User; public interface UserDao { public void insert(User user); public User findUserById (int userId); public List<User> findAllUsers(); }
http://www.cnblogs.com/dongying/p/4031382.html
注意:#与$区别:
1.#是把传入的数据当作字符串,如#field#传入的是id,则sql语句生成是这样,order by "id",这当然会报错..
2.$传入的数据直接生成在sql里,如#field#传入的是id,则sql语句生成是这样,order by id, 这就对了.
$方式一般用于传入数据库对象.例如传入表名.
#方式一般用于传入插入/更新的值或查询/删除的where条件
http://aqxiebin.iteye.com/blog/1415578
<select>是iBatis已经映射的语句类型,就是查询了,为了配合说明,这里再介绍两个标记:<sql>和<include>,前者用来创建一个文本片段,这些片段可以组合起来创建完整的SQL语句;后者很显然就是包含的意思了。假设我们有如下代码段:
<sql id="select-user"> select * from users </sql> <sql id="select-count"> select count(*) as value from users </sql> <sql id="where-age-over-value"> <![CDATA[ where age > #value:INT# ]]> </sql> <select id="getUserAgeOver" resultClass="hashmap"> <include refid="select-user" /> <include refid="where-age-over-value" /> </select> <select id="getUserCountAgeOver" resultClass="int"> <include refid="select-count" /> <include refid="where-age-over-value" /> </select>
该部分代码展示了sql和include的使用,其中使用了CDATA段,这是因为XML标签本体中出现了于XML标签冲突的字符,这很好理解。后面两个查询就是我们执行的语句部分,程序代码可以这么来写:
List users = sqlMap.queryForList("User.getUserAgeOver","23"); System.out.println(users); int userCount = (Integer) sqlMap.queryForObject( "User.getUserCountAgeOver", "22"); System.out.println(userCount);
如果可以查询到记录,那么就会打印出来了。上面的例子中我们是用了#来标识传递的参数,#被成为占位符,这是内联参数的传递方式的一种。
<select id="getUserById" resultClass="User"> select userId, userName, password, age, mobile, mail from users where userId = #value# </select>
在程序中,用下面这些代码就能达到查询效果了。
User user = (User) sqlMap.queryForObject("User.getUserById", new Integer(1)); System.out.println(user);
#value#是告诉iBatis传递一个简单的参数,iBatis处理该语句时,将会把#value#转换为预处理参数形式,然后将这个参数的值设置为1(就是queryForObject()方法的第二个参数),之后执行该预处理语句。最后iBatis接受返回的结果,然后把它映射到一个Java对象并返回该对象,这就是sqlMap的执行过程。
下面来看另外一种内联参数形式,就是使用$作为占位符。它可以直接把参数插入到SQL语句中,这在该SQL语句被转变为参数化语句之前就执行了。如此就会留下安全隐患,它可能给SQL注入有机可乘,而且过度使用还会有性能问题,看下面这个语句:
<select id="getUserByLikeEmail" resultClass="User"> select userId, userName, password, age, mobile, email from users where email like '%$value$%' </select>
在程序中,我们可以使用如下代码来执行模糊查询:
List<User> users = sqlMap.queryForList("User.getUserByLikeEmail", "gmail");
System.out.println(users);
若要使用#方式来当占位符,那么模糊查询时可能不是那么方便,需要如下进行:email like concat('%',#value#,'%'),这是MySQL的情况。所以模糊查询使用$比较方便。
以上的查询中我们使用了resultClass这种自动结果映射,这是iBatis的一种执行机制,而我们也可以进行自定义结果映射,就是使用resultMap。如果我们在查询中两者都没有使用的话,那么iBatis执行查询但是不能返回任何东西。
当我们使用bean作为结果映射时要注意如果结果列存在于数据库而不存在于bean中,那么我们不会得到任何数据,而且执行不会报错。自动映射使用起来很方便,但是更稳健的要数外部结果映射了
http://sarin.iteye.com/blog/731655
//外部调用此方法对mybatis配置文件进行解析 public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; //从根节点configuration parseConfiguration(parser.evalNode("/configuration")); return configuration; } //此方法就是解析configuration节点下的子节点 //由此也可看出,我们在configuration下面能配置的节点为以下10个节点 private void parseConfiguration(XNode root) { try { propertiesElement(root.evalNode("properties")); //issue #117 read properties first typeAliasesElement(root.evalNode("typeAliases")); pluginElement(root.evalNode("plugins")); objectFactoryElement(root.evalNode("objectFactory")); objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); settingsElement(root.evalNode("settings")); environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631 databaseIdProviderElement(root.evalNode("databaseIdProvider")); typeHandlerElement(root.evalNode("typeHandlers")); mapperElement(root.evalNode("mappers")); } catch (Exception e) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); } } }
通过以上源码,我们就能看出,在mybatis的配置文件中:
1. configuration节点为根节点。
2. 在configuration节点之下,我们可以配置10个子节点, 分别为:
properties、
typeAliases、
plugins、
objectFactory、
objectWrapperFactory、
settings、
environments、
databaseIdProvider、
typeHandlers、
mappers
http://www.cnblogs.com/dongying/p/4031613.html