Mybatis知识
面试题
#{}与${}区别
-
#{} :
#{}:是sql语句占位符,相当于praperedstatement中的?,
#{}里面可以是任何类型的参数,基本类型、hashmap、po对象。
如果#{}里面的参数是基本类型,参数名可以随便。 value 、id 等
-
${} :
${}:sql语句的拼接符,将参数原封不动的拼接到sql中。
${}里面可以是任何类型的参数,基本类型、hashmap、po对象。
如果${}里面的参数是基本类型,参数名必须是value,不能是其他参数名。
${}:sql的拼接,有sql注入的问题。
一般能用#的就别用$
XML配置文件
mybatis.cfg.xml文件(转)
转:https://www.cnblogs.com/kevin1990/p/6231122.html
<?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="mysql.properties"></properties>
<!-- 为JAVA Bean起类别名 -->
<typeAliases>
<!-- 别名方式1,一个一个的配置 type中放置的是类的全路径,alias中放置的是类别名
<typeAliase type="com.cy.mybatis.beans.UserBean" alias="UserBean"/> -->
<!-- 别名方式2,自动扫描,将JAVA类的类名作为类的类别名 -->
<package name="com.wenyin.mybatis.beans"/>
</typeAliases>
<!-- 配置mybatis运行环境 -->
<environments default="cybatis">
<environment id="cybatis">
<!-- type="JDBC" 代表使用JDBC的提交和回滚来管理事务 -->
<transactionManager type="JDBC" />
<!-- mybatis提供了3种数据源类型,分别是:POOLED,UNPOOLED,JNDI -->
<!-- POOLED 表示支持JDBC数据源连接池 -->
<!-- UNPOOLED 表示不支持数据源连接池 -->
<!-- JNDI 表示支持外部数据源连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- 告知映射文件方式1,一个一个的配置
<mapper resource="com/cy/mybatis/mapper/UserMapper.xml"/>-->
<!-- 告知映射文件方式2,自动扫描包内的Mapper接口与配置文件 -->
<package name="com/wenyin/mybatis/mapper"/>
</mappers>
</configuration>
Mapper映射文件(转)
转:https://blog.youkuaiyun.com/majinggogogo/article/details/72123185
根元素
在根节点中支持9个元素,分别为insert、update、delete、select(增删改查);cache、cache-ref、resultMap、parameterMap、sql
<?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对应一个dao -->
<mapper namespace="com.dy.dao.UserDao">
<insert
<!-- 1. id (必须配置)
id是命名空间中的唯一标识符,可被用来代表这条语句。
一个命名空间(namespace) 对应一个dao接口,
这个id也应该对应dao里面的某个方法(相当于方法的实现),因此id 应该与方法名一致 -->
id="addUser"
<!-- 2. parameterType (可选配置, 默认为mybatis自动选择处理)
将要传入语句的参数的完全限定类名或别名, 如果不配置,mybatis会通过ParameterHandler 根据参数类型默认选择合适的typeHandler进行处理
parameterType 主要指定参数类型,可以是int, short, long, string等类型,也可以是复杂类型(如对象) -->
parameterType="user"
<!-- 3. flushCache (可选配置,默认配置为true)
将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句) -->
flushCache="true"
<!-- 4. statementType (可选配置,默认配置为PREPARED)
STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 -->
statementType="PREPARED"
<!-- 5. keyProperty (可选配置, 默认为unset)
(仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 -->
keyProperty=""
<!-- 6. keyColumn (可选配置)
(仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 -->
keyColumn=""
<!-- 7. useGeneratedKeys (可选配置, 默认为false)
(仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。 -->
useGeneratedKeys="false"
<!-- 8. timeout (可选配置, 默认为unset, 依赖驱动)
这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。 -->
timeout="20">
<update
id="updateUser"
parameterType="user"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteUser"
parameterType="user"
flushCache="true"
statementType="PREPARED"
timeout="20">
</mapper>
上面给出了一个比较全面的配置说明,但是在实际使用过程中并不需要都进行配置,可根据自己的需要删除部分配置项。
在这里,我列举出我自己的配置文件,精简之后是这样的:
<?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.majing.learning.mybatis.dao.UserDao">
<insert id="addUser" parameterType="user" useGeneratedKeys="true" keyProperty="id">
insert into user(name,password,age) values(#{name},#{password},#{age})
</insert>
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id}
</delete>
<update id="updateUser" parameterType="user" >
update user set name = #{name}, password = #{password}, age = #{age} where id = #{id}
</update>
</mapper>
根元素属性
insert
useGeneratedKey和keyProperty(转)
转:https://blog.youkuaiyun.com/nininininiabc222/article/details/79990570
useGeneratedKeys=“true” keyProperty=“对应的主键的对象”。
Mybatis 配置文件 useGeneratedKeys 参数只针对 insert 语句生效,默认为 false。当设置为 true 时,表示如果插入的表以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键返回。
/*
* 使用示例:表对应的 POJO
* */
public class User {
private int id;
private String name;
private Integer age;
public int getId() {
return id;
}
public void setId(int id) {
this.id= id;
}
//... 省略其它 getter 和 setter
}
/*
* 使用示例:mapper
* keyProperty 指明表的自增主键列
* */
<insert id="addUser" parameterType="com.model.User" keyProperty="id">
insert into User(name, age) values(#{name}, #{age})
</insert>
selectKey
如果是支持自增长的数据库,如mysql数据库,那么只需要设置useGeneratedKeys和keyProperties属性便可以了,但是对于不支持自增长的数据库(如oracle)该怎么办呢?mybatis里面在元素下面提供了子元素用于帮助解决这个问题。
<selectKey
<!-- selectKey 语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 -->
keyProperty="id"
<!-- 结果的类型。MyBatis 通常可以推算出来,但是为了更加确定写上也不会有什么问题。MyBatis 允许任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的 Object 或一个 Map。 -->
resultType="int"
<!-- 这可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素 - 这和像 Oracle 的数据库相似,在插入语句内部可能有嵌入索引调用。 -->
order="BEFORE"
<!-- 与前面相同,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 语句的映射类型,分别代表 PreparedStatement 和 CallableStatement 类型。 -->
statementType="PREPARED">
</selectKey>
针对不能使用自增长特性的数据库如Oracle,可以使用下面的配置来实现相同的功能:
<insert id="insertUser" parameterType="com.dy.entity.User">
<!-- oracle等不支持id自增长的,可根据其id生成策略,先获取id -->
<selectKey resultType="int" order="BEFORE" keyProperty="id">
select seq_user_id.nextval as id from dual
</selectKey>
insert into user(id, name, password, age, deleteFlag) values(#{id}, #{name}, #{password}, #{age}, #{deleteFlag})
</insert>
select
<select
<!-- 1. id (必须配置)
id是命名空间中的唯一标识符,可被用来代表这条语句。
一个命名空间(namespace) 对应一个dao接口,
这个id也应该对应dao里面的某个方法(相当于方法的实现),因此id 应该与方法名一致 -->
id="findUserById"
<!-- 2. parameterType (可选配置, 默认为mybatis自动选择处理)
将要传入语句的参数的完全限定类名或别名, 如果不配置,mybatis会通过ParameterHandler 根据参数类型默认选择合适的typeHandler进行处理
parameterType 主要指定参数类型,可以是int, short, long, string等类型,也可以是复杂类型(如对象) -->
parameterType="int"
<!-- 3. resultType (resultType 与 resultMap 二选一配置)
resultType用以指定返回类型,指定的类型可以是基本类型,可以是java容器,也可以是javabean -->
resultType="User"
<!-- 4. resultMap (resultType 与 resultMap 二选一配置)
resultMap用于引用我们通过 resultMap标签定义的映射类型,这也是mybatis组件高级复杂映射的关键 -->
resultMap="userResultMap"
<!-- 5. flushCache (可选配置)
将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false -->
flushCache="false"
<!-- 6. useCache (可选配置)
将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true -->
useCache="true"
<!-- 7. timeout (可选配置)
这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)-->
timeout="10000"
<!-- 8. fetchSize (可选配置)
这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)-->
fetchSize="256"
<!-- 9. statementType (可选配置)
STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED-->
statementType="PREPARED"
<!-- 10. resultSetType (可选配置)
FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)-->
resultSetType="FORWARD_ONLY">
settings
全局参数配置 标签
mybatis框架在运行时可以调整一些运行参数。比如:开启二级缓存、开启延迟(惰性)加载等。
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="30"/>
<setting name="defaultFetchSize" value="200"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
typeAliases
别名
在映射文件中的parameterType或resultType如果是pojo类型,必须要指定pojo类的完全限定名,比较繁琐,不便于开发。可以针对parameterType或resultType指定的pojo类型定义一些别名,在映射文件中通过别名,引用pojo类型。
自定义别名:
如果parameterType或resultType类型是pojo类型,默认别名不满足,需要自定义别名
单个定义别名,在主配置文件中:
<typeAliases>
<typeAlias type=*"com.mybatis.po.User"* alias=*"userpo"*/>
</typeAliases>
批量定义别名(常用),在主配置文件中:
<typeAliases>
<!-- name属性:指定要扫描的pojo类所在的包名。自动将包中所有pojo定义别名(类名,首字母大小写均可)-->
<package name=*"com.mybatis.po"*/>
</typeAliases>
settings要比typeAliases先写,不然会报错
resultMap
<resultMap type="" id="">
<!-- id, 唯一性,注意啦,这个id用于标示这个javabean对象的唯一性, 不一定会是数据库的主键(不要把它理解为数据库对应表的主键)
property属性对应javabean的属性名,column对应数据库表的列名
(这样,当javabean的属性与数据库对应表的列名不一致的时候,就能通过指定这个保持正常映射了)
-->
<id property="" column=""/>
<!-- result与id相比, 对应普通属性 -->
<result property="" column=""/>
<!--
constructor对应javabean中的构造方法
-->
<constructor>
<!-- idArg 对应构造方法中的id参数 -->
<idArg column=""/>
<!-- arg 对应构造方法中的普通参数 -->
<arg column=""/>
</constructor>
<!--
collection,对应javabean中容器类型, 是实现一对多的关键
property 为javabean中容器对应字段名
column 为体现在数据库中列名
ofType 就是指定javabean中容器指定的类型
-->
<collection property="" column="" ofType=""></collection>
<!--
association 为关联关系,是实现N对一的关键。
property 为javabean中容器对应字段名
column 为体现在数据库中列名
javaType 指定关联的类型
-->
<association property="" column="" javaType=""></association>
</resultMap>
例子
实体类
package com.majing.learning.mybatis.entity;
public class Interests {
private int id;
private String name;
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;
}
@Override
public String toString() {
return "Interests [id=" + id + ", name=" + name + "]";
}
}
package com.majing.learning.mybatis.entity;
import java.util.List;
public class User2 {
private int id;
private String name;
private String password;
private int age;
private List<Interests> interests;
private String author;
public List<Interests> getInterests() {
return interests;
}
public void setInterests(List<Interests> interests) {
this.interests = interests;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
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;
}
@Override
public String toString() {
return "User2 [id=" + id + ", name=" + name + ", password=" + password + ", age=" + age + ", interests=" + interests + ", author=" + author + "]";
}
}
然后,我们给相关实体类创建一下别名:
<typeAliases>
<typeAlias alias="UserWithInterests" type="com.majing.learning.mybatis.entity.User2"/>
<typeAlias alias="Interests" type="com.majing.learning.mybatis.entity.Interests"/>
</typeAliases>
然后再创建一个对应跟UserDao2对应的Mapper映射文件:
<?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.majing.learning.mybatis.dao.UserDao2">
<resultMap type="UserWithInterests" id="UserWithInterestsMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="password" column="password"/>
<result property="age" column="age"/>
<collection property="interests" column="interestname" ofType="Interests">
<id property="id" column="interestid"/>
<result property="name" column="interestname"/>
</collection>
</resultMap>
<select id="findUserById" resultMap="UserWithInterestsMap">
select a.*,c.* from user as a right join userinterests as b on a.id = b.userid right join interests as c on b.interestid = c.interestid where id = #{id}
</select>
</mapper>
collection和association
用来实现一对多,多对一
-
在多的一方,应当使用关联映射<association…/>
比如学生和教室
学生实体映射文件:
<?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"> <!--namespace为对应的Mapper接口路径 -->
<mapper namespace="com.demo.entity.StudentMapper">
<resultMap id="studentResultMap" type="com.demo.entity.Student">
<id property="id" column="student_id" /> <!--表中的实际列名为name,为了防止混淆这里取student_name,同时也要在下面的SQL语句中声明 -->
<result property="name" column="student_name" />
<result property="age" column="age" />
<association property="classRoom" javaType="com.demo.entity.ClassRoom">
<id property="id" column="classroom_id" />
<result property="name" column="name" />
</association>
</resultMap> <!--通过学生id查找这个学生的信息 -->
<select id="selectStudentById" parameterType="int" resultMap="studentResultMap">
SELECT c.*, s.*, s.name student_name <!--给student_inf表的name列名取别名 -->
FROM classroom_inf c,student_inf s WHERE c.classroom_id =
s.classroom_id AND s.student_id = #{id}
</select> <!--查找所有学生信息 -->
<select id="selectStudent" resultMap="studentResultMap"> SELECT c.*, s.*, s.name
student_name FROM classroom_inf c,student_inf s WHERE c.classroom_id =
s.classroom_id </select>
</mapper>
-
在一的一方<collection…/>
教室实体映射文件:
<?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="com.demo.entity.ClassRoomMapper"> <resultMap id="classRoomMap" type="com.demo.entity.ClassRoom"> <id property="id" column="classroom_id" /> <result property="name" column="name" /> <collection property="students" ofType="com.demo.entity.Student"> <id property="id" column="student_id" /> <!--这里同样需要取别名student_name --> <result property="name" column="student_name" /> <result property="age" column="age" /> </collection> </resultMap> <!--查找所有教室信息和对应的学生信息 --> <select id="selectClassRoom" resultMap="classRoomMap"> SELECT c.*, s.*, s.name student_name FROM classroom_inf c, student_inf s WHERE c.classroom_id = s.classroom_id </select> <!--根据id查找所有教室信息和对应的学生信息 --> <select id="selectClassRoomById" resultMap="classRoomMap" parameterType="int"> SELECT c.*, s.*, s.name student_name FROM classroom_inf c, student_inf s WHERE c.classroom_id = s.classroom_id AND c.classroom_id = #{id} </select> </mapper>
Sql
sql元素的意义,在于我们可以定义一串SQL语句,其他的语句可以通过引用它而达到复用它的目的。因为平时用到的也不多,这里就不多介绍了,感兴趣的朋友可以自行查阅资料了解一下。
mybatis 逆向工程
引入一个官方jar,加上官方的配置文件,设置好配置文件的相关属性,就可以根据表自动生成实体类和mapper映射文件
mybatis.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>
<settings>
<!-- 开启驼峰命名规则 -->
<setting name="mapUnderscoreToCamelCase" value="true" />
<!-- 打印查询语句 -->
<!-- <setting name="logImpl" value="STDOUT_LOGGING" /> -->
</settings>
<typeAliases>
<package name="com.zzh.entity" />
</typeAliases>
</configuration>
mbg.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>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 数据源 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://192.168.41.129:3306/test" userId="root"
password="root">
<!--设置可以获取tables remarks信息 -->
<property name="useInformationSchema" value="true" />
<!--设置可以获取remarks信息 -->
<property name="remarks" value="true" />
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 指定javaBean生成的位置 -->
<javaModelGenerator targetPackage="com.zzh.entity"
targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 指定sql映射文件生成的位置 -->
<sqlMapGenerator targetPackage="mybatis\mapper"
targetProject=".\src\main\resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 指定dao接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.zzh.dao" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<table tableName="db_user" domainObjectName="User"></table>
<table tableName="db_dept" domainObjectName="Dept"></table>
</context>
</generatorConfiguration>
main方法执行生成程序
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
public class MBGTest {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("./src/main/resources/mybatis/mbg.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}
自动生成的实体类文件和mapper映射文件
<?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="com.zzh.dao.UserMapper">
<resultMap id="BaseResultMap" type="com.zzh.entity.User">
<id column="user_id" jdbcType="INTEGER" property="userId" />
<result column="user_pwd" jdbcType="VARCHAR" property="userPwd" />
<result column="user_name" jdbcType="VARCHAR" property="userName" />
<result column="user_dept_id" jdbcType="INTEGER" property="userDeptId" />
</resultMap>
<resultMap id="BaseResultMapWithDept" type="com.zzh.entity.User">
<id column="user_id" jdbcType="INTEGER" property="userId" />
<result column="user_pwd" jdbcType="VARCHAR" property="userPwd" />
<result column="user_name" jdbcType="VARCHAR" property="userName" />
<result column="user_dept_id" jdbcType="INTEGER" property="userDeptId" />
<association property="dept" javaType="com.zzh.entity.Dept">
<id column="dept_id" property="dpetId" />
<result column="dept_name" property="dpetName" />
</association>
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value}
and
#{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem"
open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<where>
<foreach collection="example.oredCriteria" item="criteria"
separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value}
and
#{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem"
open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
user_id, user_pwd, user_name, user_dept_id
</sql>
<sql id="Base_Column_List_WithDept">
user_id, user_pwd, user_name,
user_dept_id,dept_id,dept_name
</sql>
<select id="selectByExample" parameterType="com.zzh.entity.UserExample"
resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from db_user
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer"
resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from db_user
where user_id = #{userId,jdbcType=INTEGER}
</select>
<select id="selectByExampleWithDept" parameterType="com.zzh.entity.UserExample"
resultMap="BaseResultMapWithDept">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List_WithDept" />
from db_user left join db_dept on db_user.user_dept_id=db_dept.dept_id
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKeyWithDept" parameterType="java.lang.Integer"
resultMap="BaseResultMapWithDept">
select
<include refid="Base_Column_List_WithDept" />
from db_user left join db_dept on db_user.user_dept_id=db_dept.dept_id
where user_id = #{userId,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from
db_user
where user_id = #{userId,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="com.zzh.entity.UserExample">
delete from db_user
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="com.zzh.entity.User" useGeneratedKeys="true" keyProperty="userId">
insert into db_user (user_id,
user_pwd, user_name,
user_dept_id)
values (#{userId,jdbcType=INTEGER},
#{userPwd,jdbcType=VARCHAR},
#{userName,jdbcType=VARCHAR},
#{userDeptId,jdbcType=INTEGER})
</insert>
<insert id="insertSelective" parameterType="com.zzh.entity.User">
insert into db_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userId != null">
user_id,
</if>
<if test="userPwd != null">
user_pwd,
</if>
<if test="userName != null">
user_name,
</if>
<if test="userDeptId != null">
user_dept_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userId != null">
#{userId,jdbcType=INTEGER},
</if>
<if test="userPwd != null">
#{userPwd,jdbcType=VARCHAR},
</if>
<if test="userName != null">
#{userName,jdbcType=VARCHAR},
</if>
<if test="userDeptId != null">
#{userDeptId,jdbcType=INTEGER},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.zzh.entity.UserExample"
resultType="java.lang.Long">
select count(*) from db_user
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
update db_user
<set>
<if test="record.userId != null">
user_id = #{record.userId,jdbcType=INTEGER},
</if>
<if test="record.userPwd != null">
user_pwd = #{record.userPwd,jdbcType=VARCHAR},
</if>
<if test="record.userName != null">
user_name = #{record.userName,jdbcType=VARCHAR},
</if>
<if test="record.userDeptId != null">
user_dept_id = #{record.userDeptId,jdbcType=INTEGER},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
update db_user
set user_id = #{record.userId,jdbcType=INTEGER},
user_pwd = #{record.userPwd,jdbcType=VARCHAR},
user_name =
#{record.userName,jdbcType=VARCHAR},
user_dept_id =
#{record.userDeptId,jdbcType=INTEGER}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="com.zzh.entity.User">
update db_user
<set>
<if test="userPwd != null">
user_pwd = #{userPwd,jdbcType=VARCHAR},
</if>
<if test="userName != null">
user_name = #{userName,jdbcType=VARCHAR},
</if>
<if test="userDeptId != null">
user_dept_id = #{userDeptId,jdbcType=INTEGER},
</if>
</set>
where user_id = #{userId,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.zzh.entity.User">
update db_user
set
user_pwd = #{userPwd,jdbcType=VARCHAR},
user_name =
#{userName,jdbcType=VARCHAR},
user_dept_id =
#{userDeptId,jdbcType=INTEGER}
where user_id =
#{userId,jdbcType=INTEGER}
</update>
</mapper>
package com.zzh.entity;
public class User {
private Integer userId;
private String userPwd;
private String userName;
private Integer userDeptId;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd == null ? null : userPwd.trim();
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName == null ? null : userName.trim();
}
public Integer getUserDeptId() {
return userDeptId;
}
public void setUserDeptId(Integer userDeptId) {
this.userDeptId = userDeptId;
}
@Override
public String toString() {
return "User [userId=" + userId + ", userPwd=" + userPwd + ", userName=" + userName + ", userDeptId="
+ userDeptId + "]";
}
}
动态SQL
通过Mybatis提供的各种动态标签实现动态拼接sql,使得mapper映射文件在编写SQL时更加灵活,方便。常用动态SQL标签有:if、where、foreach
if和where
if标签用来判断
里面有test属性,可以输入判断语句
where标签,处理条件是否输入正确。如果没有条件,就把自己干掉,
具体使用代码来看看
foreach
注意:foreach中的open和close这两个属性,open:在遍历之前将创建该字符串,一直遍历,遍历结束后,将close中的内容拼接上去。
sql片段
通俗点讲,就是对动态sql的重用,将写好的动态sql提取出来,然后在需要的地方进行调用。
Sql片段要先定义后使用