Mybatis架构
环境搭建
- jar包
- 核心配置文件sqlMapConfig.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>
</configuration>
- 普通映射文件
<?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>
Mybatis入门
- 数据库的创建
- 实体类的创建
package com.entity;
public class User {
private Integer uno;
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getUno() {
return uno;
}
public void setUno(Integer uno) {
this.uno = uno;
}
@Override
public String toString() {
return "User [uno=" + uno + ", username=" + username + ", password=" + password + "]";
}
}
- 核心文件配置
<?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>
<!-- 数据库环境的配置 -->
<environments default="development">
<environment id="development">
<!-- 数据库事务的配置 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据库连接池配置 -->
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:@***.***.***.***:1521:orcl" />
<property name="username" value="user1" />
<property name="password" value="user1" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="tqb/entity/User.xml"/>
</mappers>
</configuration>
- Dao测试类的创建(入门:通过id查询数据)
public class UserDaoTest1 {
/*
* 通过id查询用户
*/
@Test
public void fun1() throws Exception{
//加载配置文件
String resource = "sqlMapConfig.xml";
InputStream config = Resources.getResourceAsStream(resource);
//获取sessionFactory
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(config);
//获得session
SqlSession session = sessionFactory.openSession();
// 第一个参数为映射文件中的id值,第二个参数为传入的id值
User user = session.selectOne("user.byId", 2);
System.out.println(user);
config.close();
session.close();
}
}
- 映射文件的配置
<?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 namespace="user">
<!--
id:selectOne方法的第一个参数
resultType:返回值的类型
parameterType:传入参数id的类型
#{任意值}:占位符,相当于jdbc中的 ?
-->
<select id="byId" resultType="User" parameterType="Integer">
select * from "user" where uno = #{v}
</select>
</mapper>
其它crud操作
模糊查询
/*
* 模糊查询
*/
@Test
public void fun2() throws Exception{
//加载配置文件
String resource = "sqlMapConfig.xml";
InputStream config = Resources.getResourceAsStream(resource);
//获取sessionFactory
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(config);
//获得session
SqlSession session = sessionFactory.openSession();
List<User> list = session.selectList("user.byName", "s");
for (User user : list) {
System.out.println(user);
}
config.close();
session.close();
}
<!-- $符号的作用是字符串拼接 -->
<!-- mysql中也可以这样书写 select * from "user" where username like "%"#{value}"%" -->
<select id="byName" resultType="tqb.entity.User" parameterType="String">
select * from "user" where username like '%${value}%'
</select>
添加操作
/*
* 添加用户
*/
@Test
public void fun3() throws Exception{
//加载配置文件
String resource = "sqlMapConfig.xml";
InputStream config = Resources.getResourceAsStream(resource);
//获取sessionFactory
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(config);
//获得session
SqlSession session = sessionFactory.openSession();
User user = new User();
user.setUsername("lisi");
user.setPassword("654321");
session.insert("user.insertUser", user);
session.commit();
// 获得返回的id值(uno)
System.out.println(user.getUno());
config.close();
session.close();
}
<insert id="insertUser" parameterType="tqb.entity.User">
<!-- Oracle: select user_seq.currval from dual -->
<!-- Mysql: select LAST_INSERT_ID order值为BEFORE mysql中先生成主键值再插入 而Oracle中使用触发器和序列完成的,得在插入后获得当前序列值-->
<!-- 返回主键值 -->
<selectKey resultType="Integer" order="AFTER" keyProperty="uno">
select user_seq.currval from dual
</selectKey>
insert into "user" values(null,#{username},#{password})
</insert>
更新数据
/*
* 更新用户
*/
@Test
public void fun4() throws Exception{
//加载配置文件
String resource = "sqlMapConfig.xml";
InputStream config = Resources.getResourceAsStream(resource);
//获取sessionFactory
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(config);
//获得session
SqlSession session = sessionFactory.openSession();
User user = new User();
user.setUno(2);
user.setUsername("lisi_asd");
user.setPassword("lisi_asd");
session.update("user.updateUser", user);
session.commit();
config.close();
session.close();
}
<update id="updateUser" parameterType="tqb.entity.User">
update "user" set username=#{username},"password"=#{password} where uno=#{uno}
</update>
删除数据
/*
* 删除用户
*/
@Test
public void fun5() throws Exception{
//加载配置文件
String resource = "sqlMapConfig.xml";
InputStream config = Resources.getResourceAsStream(resource);
//获取sessionFactory
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(config);
//获得session
SqlSession session = sessionFactory.openSession();
User user = new User();
user.setUno(5);
session.delete("user.deleteUser", user);
session.commit();
config.close();
session.close();
}
<delete id="deleteUser" parameterType="tqb.entity.User">
delete "user" where uno=#{uno}
</delete>
Mybatis和Hibernate的区别
- Hibernate可以通过实体类进行创建表,而MyBatis不可以,但是在实际的开发过程中,建数据表并不是简简单单的一些表,还需要考虑到很多的问题,如一些约束,数据库以及SQL的优化等等,Hibernate这时候就心有余而力不足了,相比来说,在这方面,Mybatis的灵活性更高,在开发中使用的频率也是非常高。
- 在SQL语句方面,HIbernate不需要自己书写SQL语句,可以判断底层使用的具体数据库来自动生成自适应的SQL语句,而MyBatis需要自己在配置文件中书写原生态的SQL语句。
- Mybatis相比Hibernate来说简单易学,可以直接书写原生态的SQL语句,可以严格控制SQL执行性能,灵活度很高。
- 这里的区别可能不是很全面,理解就好。
- 总之没有什么框架是最好的,适应就是最好,各有千秋!
Mapper动态代理开发(实际开发)
Mapper动态代理开发的四大要素
- 返回值类型和映射文件中的resultType相同
- 方法名和映射文件中的id值相同
- 输入参数类型和映射文件中的parameterType相同
- 名称空间绑定具体映射接口
public interface UserMapper {
/*
* 四个原则
* 接口方法名等于映射文件中的id名
* 返回类型与映射文件中的返回类型相同
* 参数类型与映射文件中的参数类型相同
* 映射文件中的名称空间绑定该类
*/
public User byId(Integer uno);
}
测试
public class MapperTest {
/*
* 通过id查询用户
*/
@Test
public void fun1() throws Exception{
//加载配置文件
String resource = "sqlMapConfig.xml";
InputStream config = Resources.getResourceAsStream(resource);
//获取sessionFactory
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(config);
//获得session
SqlSession session = sessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.byId(2);
System.out.println(user);
}
}
核心配置文件标签
注:标签顺序必须按照下图所示,不能乱序使用
- propertise:key-value的设置,可以进行一些常用变量的设置,使用起来更加的方便,如数据库驱动信息,数据库连接信息等等。
<properties>
<property name="" value=""/>
</properties>
- typeAliases:别名设置,如我们上边经常是使用的返回值类型,需要写全路径,设置好了之后,可以直接使用类名
<typeAliases>
<!-- 自动扫描该包下的所有类,确保别名使用 -->
<package name="com.entity"/>
</typeAliases>
- mappers中的mapper标签:
1)class:要求mapper接口名称和映射文件相同,且在同一个目录下class属性要求mapper接口名称和映射文件相同,且在同一个目录下
2)resouce:指定文件位置
3)url:绝对路径,开发中绝对不会使用
- mappers中的package标签:注册该包下的所有mapper接口,要求mapper接口名称和映射文件相同,且在同一个目录下
输入参数_POJO的包装类
- 创建包装类
public class QueryVO implements Serializable {
private static final long serialVersionUID = 1L;
private User user = new User();
public void setUser(User user) {
this.user = user;
}
}
- 配置文件
<select id="insertUser" parameterType="QueryVO">
insert into "user" values(null,#{user.username},#{user.password})
</select>
- 测试类(映射接口中的抽象方法自己完成)
public class MapperTest{
@Test
public void fun(){
String resource = "sqlMapConfig.xml";
InputStream config = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(config);
SqlSession session = sessionFactory.openSession();
User user = new User();
user.setUsername("test");
user.setPassword("test");
QueryVO vo = new QueryVO();
vo.setUser(user);
session.insertUser(vo);
config.close();
session.close();
}
}
输出类型ResultMap(手动配置结果参数类型)
<resultMap type="User" id="findAll">
<id column="uno" property="uno" javaType="Integer"/>
<result column="username" property="username" javaType="String"/>
<result column="password" property="password" javaType="String"/>
</resultMap>
<select id="findAll" resultMap="findAll">
select * from "user"
</select>
动态SQL
- if&&where:if条件判断,如多条件查询中进行条件判断;where即where关键字,作用可以去除一些影响sql语句正确性的关键字,如我们之前进行多条件判断时,必须添加1=1这样的条件,避免and关键字影响sql语句正确性,但是有了where标签,就不需要了,自动检测and位置并调整语句,在这里,and的位置必须按照下面这个格式进行书写。
<!-- 多条件查询 -->
<select id="selectCondition" resultType="User" parameterType="User">
select * from "user"
<!-- 注意的是:where保证的是and关键字在条件前边才可以去除 -->
<where>
<if test="username != null and username != ''">
username = #{username}
</if>
<if test="password != null and password != ''">
and "password" = #{password}
</if>
</where>
</select>
- sql片段
<!-- sql片段使用sql标签 -->
<sql id="selectAll">
select * from "user"
</sql>
<!-- 在具体的语句中使用include标签调用SQL片段 -->
<select >
<include refid="selectAll"></include>
</select>
- foreach
<!-- 通过多个id进行查询数据 -->
<select id="findByMoreId" resultType="User" parameterType="QueryVO">
select * from "user"
<where>
uno in
<!--
open:集合开始的标志
close:集合结束的标志
separator:集合内元素分割的符号
-->
<!-- 若参入参数不是QueryVO 直接传入的数组,那么在映射文件中的collection元素值为array,若直接传入的是map集合,那么collection的元素值为map -->
<foreach collection="unoList" item="uno" open="(" close=")" separator=",">
#{uno}
</foreach>
</where>
</select>
一对一关联
<resultMap type="Orders" id="findByOid">
<id column="o_id" property="o_id" javaType="Integer"/>
<result column="o_date" property="o_date" javaType="java.util.Date"/>
<!-- 一对一映射 -->
<association property="user" javaType="User">
<result column="username" property="username" javaType="String"/>
</association>
</resultMap>
<select id="findByOid" parameterType="Integer" resultMap="findByOid">
select o.o_id,o.o_date,o.o_address,u.username from orders o,"user" u
where o.uno=u.uno and o.o_id = #{o_id}
</select>
一对多关联
<resultMap type="User" id="findByUid">
<id column="uno" property="uno" javaType="Integer"/>
<result column="username" property="username" javaType="String"/>
<collection property="orders" ofType="Orders">
<id column="o_id" property="o_id" javaType="Integer"/>
<result column="o_date" property="o_date" javaType="java.util.Date"/>
</collection>
</resultMap>
<select id="findByUid" parameterType="Integer" resultMap="findByUid">
select o.o_id,o.o_date,o.o_address,u.uno,u.username from orders o,"user" u
where o.uno=u.uno and u.uno = #{uno}
</select>
Spring整合Mybatis——Mapper动态代理开发
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="jdbcUrl" value="jdbc:oracle:thin:@172.22.229.194:1521:orcl"></property>
<property name="user" value="user1"></property>
<property name="password" value="user1"></property>
</bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 指定核心配置文件位置 -->
<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
</bean>
<!-- 等同于代码中获得sqlSession对象和获得映射接口的实现类 -->
<bean id="mapperFactoryBean" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactoryBean"></property>
<property name="mapperInterface" value="tqb.mapper.UserMapper"></property>
</bean>
</beans>
public class Test1 {
@Test
public void fun1(){
//加载spring核心配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper usermapper = (UserMapper) applicationContext.getBean(UserMapper.class);
User user = usermapper.findByUid(2);
System.out.println(user);
}
}
Spring整合Mybatis——Mapper动态代理开发之自动扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="jdbcUrl" value="jdbc:oracle:thin:@172.22.229.194:1521:orcl"></property>
<property name="user" value="user1"></property>
<property name="password" value="user1"></property>
</bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 指定核心配置文件位置 -->
<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
</bean>
<!-- Mapper动态代理开发自动扫描 -->
<!-- 不用引入sqlSessionFactory实例,直接在Spring容器里及进行查找并使用 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="tqb.mapper"></property>
</bean>
</beans>