Mybatis框架的学习
SqlMapperConfig.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>
<!-- 环境,可以配置多个,default:指定采用哪个环境 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<environments default="test">
<!-- id:唯一标识 -->
<environment id="test">
<!-- 事务管理器,JDBC类型的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,池类型的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/testmybatis?serverTimezone=GMT%2B8" />
<property name="username" value="root" />
<property name="password" value="1234" />
</dataSource>
</environment>
<environment id="development">
<!-- 事务管理器,JDBC类型的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,池类型的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<mapper resource="mappers/MyMapper.xml" />
</mappers>
</configuration>
XXXmapper.xml的配置
<?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:命名空间,随便写,一般保证命名空间唯一,在使用代理方法开发的时候,namespace 有特殊的意义 -->
<mapper namespace="MyMapper">
<!-- id==statement的id,内容:sql语句。将来sql语句会封装到mappedstatement对象当中。id:唯一标识,随便写,在同一个命名空间下保持唯一,resultType:sql语句查询结果集的封装类型,tb_user即为数据库中的表
-->
<select id="selectUser" parameterType="int" resultType="www.com.inone.pojo.User" >
select * from tb_user where id = #{id}
<!--#{}表示一个占位符 id表示接收输入的参数 resultType表示sql输出的结果映射成pojo,parameterType参数类型 -->
</select>
<!--${value}:接收输入参数的内容,拼接符。如果传入的值是简单类型则只能使用value-->
<select id="findUserByName" parameterType="String" resultType="www.com.inone.pojo.User">
select * from tb_user where user_name LIKE '%{value}%'
</select>
<insert id="insertUser" parameterType="www.com.inone.pojo.User">
insert into tb_user (id,user_name,password,name,age,sex)value (#{id},#{userName},# {password},#{name},#{age},#{sex} )
</insert>
</mapper>
配置文件的记载过程
//创建输入流
String resource = "SqlMapConfig.xml";
InputStream inputStrean=Resources.getResourceAsStrean(resource);
// 创建会话工厂
SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder.builde(inputStream);
自增主键的返回
将插入的主键进行返回,只适用于主键的自增。
keyProperty:将查询到的结果设置到parameterType指定的对象的哪个属性中
order:指的是执行的顺序
非自增主键的返回
使用mysql的uuid()函数生主键,需要修改表中的id字段为string类型,并且指定长度为35位
使用mysql的uuid
// An highlighted block
<!--先通过uuid()获取主键,然后设置到mysql数据库当中-->
<insert id="insertUser" parameterType="www.com.inone.pojo.User">
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Integer">
SELECT UUID()
</selectKey>
insert into tb_user (id,user_name,password,name,age,sex)value (#{id},#{userName},#{password},#{name},#{age},#{sex} )
</insert>
总结:
1、#{}表示一个占位符,类型可以是简单的类型,pojo,hashmap,如果接受的是简单的类型,#{}中可以写成value或其他的名称
2、&{}表示一个拼接符号,会引入sql的注入,所以不建议使用,接受的参数可以是pojo,hashmap,如果接收的是基本类型则只能使用value
mybatis和hibernate的区别和应用场景
1、hibernate:是一个标准的ORM,入门门槛比较高,不用写sql语句和jpa差不多。
- 适用于需求变化不多的中小型的项目:OA /ORM/ERP 等等
2、mybatis需要我们可以自己编写sql语句。(不完全的ORM项目) - 主要应用于需求变化较多的项目:互联网的项目等等
只通风mapper接口进行增删查改的操作
话不多说直接上代码
1、创建mapper接口
package www.com.inone.userdao;
import org.apache.ibatis.annotations.Param;
import www.com.inone.pojo.User;
import java.util.List;
/**
* @Auther: ZQB
* Date:2019/12/12
*/
public interface UserMapper {
/**
* 登录(直接使用注解指定传入参数名称)
* @param userName
* @param password
* @return
*/
public User login(@Param("userName") String userName, @Param("password") String password);
/**
* 根据表名查询用户信息(直接使用注解指定传入参数名称)
* @param tableName
* @return
*/
public List<User> queryUserByTableName(@Param("tableName") String tableName);
/**
* 根据Id查询用户信息
* @param id
* @return
*/
public User queryUserById(Long id);
/**
* 查询所有用户信息
* @return
*/
public List<User> queryUserAlls();
/**
* 新增用户信息
* @param user
*/
public void insertUser(User user);
/**
* 根据id更新用户信息
* @param user
*/
public void updateUser(User user);
/**
* 根据id删除用户信息
* @param id
*/
public void deleteUserById(Long id);
}
2、创建配置文件
<?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:命名空间,随便写,一般保证命名空间唯一 ,为了使用接口动态代理,这里必须是接口的全路径名-->
<mapper namespace="www.com.inone.userdao.UserMapper">
<!--
1.#{},预编译的方式preparedstatement,使用占位符替换,防止sql注入,一个参数的时候,任意参数名可以接收
2.${},普通的Statement,字符串直接拼接,不可以防止sql注入,一个参数的时候,必须使用${value}接收参数
-->
<select id="queryUserByTableName" resultType="www.com.inone.pojo.User">
select * from ${tableName}
</select>
<select id="login" resultType="www.com.inone.pojo.User">
select * from tb_user where user_name = #{userName} and password = #{password}
</select>
<!-- statement,内容:sql语句。
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
resultType:sql语句查询结果集的封装类型,使用动态代理之后和方法的返回类型一致;resultMap:二选一
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<select id="queryUserById" resultType="www.com.inone.pojo.User">
select * from tb_user where id = #{id}
</select>
<select id="queryUserAlls" resultType="www.com.inone.pojo.User">
select * from tb_user
</select>
<!-- 新增的Statement
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
useGeneratedKeys:开启主键回写
keyColumn:指定数据库的主键
keyProperty:主键对应的pojo属性名
-->
<insert id="insertUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id"
parameterType="www.com.inone.pojo.User">
INSERT INTO tb_user (
id,
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
null,
#{userName},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
NOW(),
NOW()
);
</insert>
<!--
更新的statement
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<update id="updateUser" parameterType="www.com.inone.pojo.User">
UPDATE tb_user
<trim prefix="set" suffixOverrides=",">
<if test="userName!=null">user_name = #{userName},</if>
<if test="password!=null">password = #{password},</if>
<if test="name!=null">name = #{name},</if>
<if test="age!=null">age = #{age},</if>
<if test="sex!=null">sex = #{sex},</if>
<if test="birthday!=null">birthday = #{birthday},</if>
updated = now(),
</trim>
WHERE
(id = #{id});
</update>
<!--
删除的statement
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<delete id="deleteUserById" parameterType="java.lang.String">
delete from tb_user where id=#{id}
</delete>
</mapper>
3、添加主配置文件中
<?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>
<!-- 环境,可以配置多个,default:指定采用哪个环境 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<environments default="test">
<!-- id:唯一标识 -->
<environment id="test">
<!-- 事务管理器,JDBC类型的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,池类型的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/testmybatis?serverTimezone=GMT%2B8" />
<property name="username" value="root" />
<property name="password" value="1234" />
</dataSource>
</environment>
<environment id="development">
<!-- 事务管理器,JDBC类型的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,池类型的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/MyMapper.xml" />
<mapper resource="mappers/UserDaoMapper.xml"/>
<mapper resource="mappers/UserMapper.xml"/>
</mappers>
</configuration>
4、测试
package www.com.inone.userdao;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;
import www.com.inone.pojo.User;
import www.com.inone.utils.SessFactoryUtil;
import java.util.List;
/**
* @Auther: ZQB
* Date:2019/12/12
*/
public class UserMapperTest {
public UserMapper userMapper;
@Before
public void setUp() throws Exception {
// 指定配置文件
SqlSession sqlSession= SessFactoryUtil.getSession();
// 1. 映射文件的命名空间(namespace)必须是mapper接口的全路径
// 2. 映射文件的statement的id必须和mapper接口的方法名保持一致
// 3. Statement的resultType必须和mapper接口方法的返回类型一致
// 4. statement的parameterType必须和mapper接口方法的参数类型一致(不一定)
this.userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void testQueryUserAll() {
List<User> userList = this.userMapper.queryUserAlls();
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testDeleteUserById() {
this.userMapper.deleteUserById(1l);
}
}
- 注意:1、命名空间的i值一定要是mapper接口的全路径。
- 2、mapper.xml增删查改的id值一定要和mapper接口中的增删查改的方法名相同.
- 3、在主配置文件中添加
对主配置文件的学习
// A code block
<?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="application.properties"></properties>
<!--设置pojo和数据表相互对应-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<!--type:类的全名 alis:别名-->
<typeAlias type="www.com.inone.pojo.User" alias="user"></typeAlias>
</typeAliases>
<!--环境可以写多个-->
<environments default="development">
<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/testmybatis?serverTimezone=GMT%2B8" />
<property name="username" value="root" />
<property name="password" value="1234" />
</dataSource>
</environment>
</configuration>
typeAliases(别名,重点)
在mapper.xml中,定义了很多的statement,statement需要parameterType指定输入参数的类型,需要resultType指定输出的映射类型。
如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType和resultType指定的类型定义一些别名,在mappper.xml通过别名定义,方便开发。
《单个别名》
<typeAliases>
type:实体类的全路径。alias:别名,通常首字母小写
<typeAlias type="www.com.inone.pojo.Userr" alias="User"/>
</typeAliases>
《批量别名》
<typeAliases>
<package name="www.com.inone.pojo"/>
</typeAliases>
Mybatis已经为普通的 Java 类型内建了许多相应的类型别名。它们都是大小写不敏感的.
通过mapper接口加载映射文件
通过mapper接口加载映射文件
规范:1、需要将mapper接口类名和mapper.xml映射文件名称保持一致且在同一个目录当中
2、使用mapper接口代理的方式
- 注意:可能出现的问题:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): www.com.inone.userdao.UserMapper.queryUserAll
如果我们的mapper.xml文件没有放置到src-main-resources下面,是不会被maven build plugin给默认扫描到的。此时需要修改启动的模块的pom文件,在build标签里面加入:
解决方法:在pom文件加入:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
- 单独加载mapper
- 批量加载
传递pojo的包装对象
resultType可以指定pojo将查询的结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功!
ResultMap的简单使用
mybatis中使用resultMap来完成高级映射。
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名做一个映射关系。
使用步骤:
1、定义ResultMap
<resultMap id="userResultMap" type="user">
<!--唯一主键列的映射-->
<!--id:查询结果的唯一表示 property:pojo的属性名-->
<id column="id_" property="id"></id>
<!--其他属性列的映射-->
<result column="username_" property="userName"></result>
</resultMap>
2、使用ResultMap作为statement的输出类型
<!--resitMap:指定定义的resultMap,如果这个resultMap在其他的mapper.xml文件中,则前面需要加namespace-->
<select id="findUserByIdMap" parameterType="int" resultMap="userResultMap">
select id id_,user_name username_ from tb_user where id=#{value}
</select>
动态sql
- if where
// An highlighted block
<select id="findUserList" parameterType="UserQueryVo" resultType="UserCustom">
select * from tb_user
<where>
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and tb_user.sex=#{userCustom.sex}
</if>
<if test="userCustom.userName!=null and userCustom.userName!=''">
and tb_user.user_name like '%${userCustom.userName}%'
</if>
</if>
</where>
</select>
- sql 片段
<sql id=””></sql>
<include refId=”” />
- foreach
/**
* 按多个Id查询
* @param ids
* @return
*/
List<User> queryUserListByIds(@Param("ids") String[] ids);
<select id="queryUserListByIds" resultType="com.zpc.mybatis.pojo.User">
select * from tb_user where id in
<!--collection:指定输入对象中集合属性 item:每个遍历生成的id,open:开始遍历拼接的串 close:结束遍历拼接的串-->
《!--select * from tb_user where tb_user.user_name LIKE '%${value}%' AND (id=? or id =? or id=? )--》
<foreach collection="ids" item="id_item" open="AND (" close=")" separator="or">
id=#{id_iten}
</foreach>
</select>
————————————————
原文链接:https://blog.csdn.net/hellozpc/article/details/80878563
————————————————
参考原文链接:https://blog.csdn.net/hellozpc/article/details/80878563
参考原文链接:https://www.jianshu.com/p/a9516bcd3cb0
参考原文链接:https://www.cnblogs.com/huanghuanghui/p/9836765.html
参考原文链接:http://blog.csdn.net/isea533/article/details/73555400