Mybatis总结
一、Mybatis使用步骤
1.导入maven依赖pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjpowernode</groupId>
<artifactId>ch01-hello-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<!--<packaging>jar</packaging>-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--PageHelper依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
2.resources文件下的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:控制mybatis全局行为-->
<settings>
<!--设置mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!--环境配置: 数据库的连接信息
default:必须和某个environment的id值一样。
告诉mybatis使用哪个数据库的连接信息。也就是访问哪个数据库
-->
<environments default="made">
<!-- environment : 一个数据库信息的配置, 环境
id:一个唯一值,自定义,表示环境的名称。
-->
<environment id="made">
<!--
transactionManager :mybatis的事务类型
type: JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理)
-->
<transactionManager type="JDBC"/>
<!--
dataSource:表示数据源,连接数据库的
type:表示数据源的类型, POOLED表示使用连接池
-->
<dataSource type="POOLED">
<!--
driver, user, username, password 是固定的,不能自定义。
-->
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
如果maven依赖是mysql 8.0版本或者以上的需要把下面改为
jdbc:mysql://localhost:3306/user?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
<property name="url" value="jdbc:mysql://localhost:3306/user"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="root"/>
</dataSource>
</environment>
<!--表示线上的数据库,是项目真实使用的库-->
<environment id="online">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/user"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- sql mapper(sql映射文件)的位置-->
<mappers>
<!--一个mapper标签指定一个文件的位置。
从类路径开始的路径信息。 target/clasess(类路径)
-->
这里是需要用的Dao类的xml位置,如果需要多个就设置多个,如果都在这些xml文件都在Dao类下
直接用<package name="com/example/demo1/dao/UserDao"/>/错误可以换成.
<mapper resource="com/example/demo1/dao/UserDao.xml"/>
<!--<mapper resource="com/bjpowernode/dao/SchoolDao.xml" />-->
</mappers>
</configuration>
<!--
mybatis的主配置文件: 主要定义了数据库的配置信息, sql映射文件的位置
1. 约束文件
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
mybatis-3-config.dtd:约束文件的名称
2. configuration 根标签。
-->
3.Dao层下面的接口文件
//接口操作student表
public interface UserDao {
//查询student表的所有的数据
public List<User> selectUsers();
public List<User> selectAllUuser();
public List<User> selectAllUuser1();
public List<User> selectLike(String user);
public List<User> selectForIf(User user);
public List<User> selectFirstIf(User user);
public List<User> selectForeachOne(List<String> userList);
//插入方法
//参数: student ,表示要插入到数据库的数据
//返回值: int , 表示执行insert操作后的 影响数据库的行数
public int insertUser(User user);
public User selectByUser(String user);
public List<User> selectMultiPara(@Param("myUser") String user,@Param("myKey") String key);
public int selectForObject(User user);
public List<User> selectOrder(@Param("colName") String colName);
}
4.Dao层下面的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="com.example.demo1.dao.UserDao">
<!--
select:表示查询操作。
id: 你要执行的sql语法的唯一标识, mybatis会使用这个id的值来找到要执行的sql语句
可以自定义,但是要求你使用接口中的方法名称。
resultType:表示结果类型的, 是sql语句执行后得到ResultSet,遍历这个ResultSet得到java对象的类型。
值写的类型的全限定名称
-->
<select id="selectUsers" resultType="com.example.demo1.bean.User" >
SELECT * FROM t_user
</select>
<select id="selectByUser" parameterType="java.lang.String" resultType="com.example.demo1.bean.User" >
SELECT * FROM t_user where `user`=#{user}
</select>
<select id="selectMultiPara" resultType="com.example.demo1.bean.User">
SELECT * from t_user where `user`=#{myUser} or `key`=#{myKey}
</select>
<select id="selectForObject" resultType="java.lang.Integer">
SELECT count(*) from t_user where`user`=#{user} or `key`=#{key}
</select>
<select id="selectOrder" resultType="com.example.demo1.bean.User">
SELECT * from t_user order by ${colName}
</select>
<resultMap id="Uuser" type="com.example.demo1.bean.User">
<!--列名和java属性的关系-->
<!--注解列,使用id标签
column :列名
property:java类型的属性名
-->
<result column="SIUSER" property="user" />
<result column="SIKEY" property="key" />
</resultMap>
<select id="selectAllUuser" resultMap="Uuser">
select `user` AS SIUSER,`key` AS SIKEY from t_user
</select>
<resultMap id="Uuser1" type="com.example.demo1.bean.User">
<!--列名和java属性的关系-->
<!--注解列,使用id标签
column :列名
property:java类型的属性名
-->
<result column="Uuser" property="user" />
<result column="Ukey" property="key" />
</resultMap>
<select id="selectAllUuser1" resultMap="Uuser1">
select `user` as Uuser,`key` as Ukey from t_user
</select>
<select id="selectLike" resultType="com.example.demo1.bean.User">
select * from t_user where `user` like "%" #{myuser} "%"
</select>
<sql id="UserSqlOne">
`user`,`key`
</sql>
<select id="selectFirstIf" resultType="com.example.demo1.bean.User">
select <include refid="UserSqlOne" /> from t_user
where 1=1
<if test="user !=null and user !='' ">
and `user` = #{user}
</if>
<if test="key == 123456">
or `key` = #{key}
</if>
</select>
<sql id="UserSql">
select * from t_user
</sql>
<select id="selectForIf" resultType="com.example.demo1.bean.User">
<include refid="UserSql" />
<where>
<if test="user!=null and user!=``">
user= #{user}
</if>
</where>
</select>
<!--foreach使用1 , List<Integer>-->
<select id="selectForeachOne" resultType="com.example.demo1.bean.User">
select * from t_user where `user` in
<foreach collection="list" item="user" open="(" close=")" separator=",">
#{user}
</foreach>
</select>
<!--插入操作-->
<insert id="insertUser">
insert into t_user values(#{user},#{key})
</insert>
</mapper>
<!--
sql映射文件(sql mapper): 写sql语句的, mybatis会执行这些sql
1.指定约束文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mybatis-3-mapper.dtd是约束文件的名称, 扩展名是dtd的。
2.约束文件作用: 限制,检查在当前文件中出现的标签,属性必须符合mybatis的要求。
3.mapper 是当前文件的根标签,必须的。
namespace:叫做命名空间,唯一值的, 可以是自定义的字符串。
要求你使用dao接口的全限定名称。
4.在当前文件中,可以使用特定的标签,表示数据库的特定操作。
<select>:表示执行查询,select语句
<update>:表示更新数据库的操作, 就是在<update>标签中 写的是update sql语句
<insert>:表示插入, 放的是insert语句
<delete>:表示删除, 执行的delete语句
-->
5.utils下的工具文件
public class MyBatisUtils {
private static SqlSessionFactory factory = null;
static {
String config="mybatis.xml"; // 需要和你的项目中的文件名一样
try {
InputStream in = Resources.getResourceAsStream(config);
//创建SqlSessionFactory对象,使用SqlSessionFactoryBuild
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession的方法
public static SqlSession getSqlSession() {
SqlSession sqlSession = null;
if( factory != null){
sqlSession = factory.openSession();// 非自动提交事务
}
return sqlSession;
}
}
6.测试使用mybatis查询数据
public class selectAllUuser {
public static void main(String[] args) {
获取sqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
获取Mapper映射
UserDao dao = sqlSession.getMapper(UserDao.class);
执行sql语句,并且根据返回值返回数据
List<User> userList = dao.selectAllUuser();
for(User user : userList)
{
System.out.println(user);
}
sqlSession.close();
}
}
二、使用详细
1.直接使用
在Dao层下面的xml文件,和Dao层下面的接口需要一致,比如我们xml里sql语句的id是selectUsers,在Dao下面的接口方法名也是selectUsers
<select id="selectUsers" resultType="com.example.demo1.bean.User" >
SELECT * FROM t_user
</select>
public List<User> selectUsers();
在xml里面,resultType是返回值,这里我设置的返回值
2.使用一个或多个参数
<select id="selectMultiPara" resultType="com.example.demo1.bean.User">
SELECT * from t_user where `user`=#{myUser} or `key`=#{myKey}
</select>
public List<User> selectMultiPara(@Param("myUser") String user,@Param("myKey") String key);
3.使用一个对象作为参数
xml里面的#{user}和#{key}的user和key,必须和User类里面的数据名一致
<select id="selectForObject" resultType="java.lang.Integer">
SELECT count(*) from t_user where`user`=#{user} or `key`=#{key}
</select>
public int selectForObject(User user);
4.查询以某一项数据进行排序的数据
<select id="selectOrder" resultType="com.example.demo1.bean.User">
SELECT * from t_user order by ${colName}
</select>
public List<User> selectOrder(@Param("colName") String colName);
5.ResultMap自定义返回数据类型
<resultMap id="Uuser" type="com.example.demo1.bean.User">
<!--列名和java属性的关系-->
<!--注解列,使用id标签
column :列名
property:java类型的属性名
-->
<result column="SIUSER" property="user" />
<result column="SIKEY" property="key" />
</resultMap>
<select id="selectAllUuser" resultMap="Uuser">
select `user` AS SIUSER,`key` AS SIKEY from t_user
</select>
public List<User> selectAllUuser();
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao dao = sqlSession.getMapper(UserDao.class);
List<User> userList = dao.selectAllUuser();
for(User user : userList)
{
System.out.println(user);
}
sqlSession.close();
这里的column需要和数据库里面的数据列名一致,property需要和Bean层下面的User类数据一致,查询的返回值就是Bean层下的User类。
6.模糊查询
第一种方法,直接在xml文件里面加入前后的%,但是不推荐用这种方式
<select id="selectLike" resultType="com.example.demo1.bean.User">
select * from t_user where `user` like "%" #{myuser} "%"
</select>
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao dao = sqlSession.getMapper(UserDao.class);
List<User> userList = dao.selectLike("123");
for(User user : userList)
{
System.out.println(user);
}
sqlSession.close();
第二种方法,在传参中用数据连接加入前后的%
<select id="selectLike" resultType="com.example.demo1.bean.User">
select * from t_user where `user` like #{myuser}
</select>
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao dao = sqlSession.getMapper(UserDao.class);
String sql = "%"+"123"+"%";
List<User> userList = dao.selectLike(sql);
for(User user : userList)
{
System.out.println(user);
}
sqlSession.close();
7.xml里面定义sql语句,可以做到代码复用
这里的意思是定义一个语句或者语句片段,id是UserSqlOne,在下面select语句中加入 include refid="UserSqlOne"就可以直接使用定义的语句片段
<sql id="UserSqlOne">
`user`,`key`
</sql>
<select id="selectFirstIf" resultType="com.example.demo1.bean.User">
select <include refid="UserSqlOne" /> from t_user
</select>
8.where和if的用法
以下代码意思就是select * from t_user,然后传值user不是空,就在sql语句后面加上,where user=传值的user,如果user是空,sql语句就是select * from t_user。满足if条件就加上后续语句,where的作用是去掉没有用的or或者and,做到高容错。
<sql id="UserSql">
select * from t_user
</sql>
<select id="selectForIf" resultType="com.example.demo1.bean.User">
<include refid="UserSql" />
<where>
<if test="user!=null and user!=``">
user= #{user}
</if>
</where>
</select>
这里的user是一个数据类,类里面有个user数据,一般都是传类过去。
public List<User> selectForIf(User user);
9.foreach使用
传值为list《String》集,在xml中list表示传过来的值为list集,item是遍历每一个元素的值,比如下面java代码传过来的值就是[123, 123456, 1234566, 1234562],item就是123.123456.1234566.1234562,所以sql语句就是select * from t_user where user
in ( 123.123456.1234566.1234562 ) ,separator是分隔符,open和close是开始和结束标志符。
<select id="selectForeachOne" resultType="com.example.demo1.bean.User">
select * from t_user where `user` in
<foreach collection="list" item="user" open="(" close=")" separator=",">
#{user}
</foreach>
</select>
public List<User> selectForeachOne(List<String> userList);
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao dao = sqlSession.getMapper(UserDao.class);
List<String> users = new ArrayList<String>();
users.add("123");
users.add("123456");
users.add("1234566");
users.add("1234562");
List<User> userList = dao.selectForeachOne(users);
for(User user : userList)
{
System.out.println(user);
}
sqlSession.close();
foreach传list《User》集,其他代码不变,在xml和java代码里面稍微修改
<select id="selectForeachTwo" resultType="com.bjpowernode.domain.Student">
<include refid="studentSql" /> where id in (
<foreach collection="list" item="stu" >
#{stu.id},
</foreach>
-1 )
</select>
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> stuList = new ArrayList<>();
Student s1 = new Student();
s1.setId(1002);
s1.setName("lisi");
stuList.add(s1);
s1 = new Student();
s1.setId(1005);;
s1.setName("zs");
stuList.add(s1);
List<Student> students = dao.selectForeachTwo(stuList);
for(Student stu:students){
System.out.println("foreach--two ==="+stu);
10.PageHelper分页请求
分页请求本质就是在sql语句里面加limit,只是这个请求可以用pagehelper动态设置limit. PageHelper.startPage(1,3)意思是将数据分为每一页3条,比如我有10条数据,也就是一共4页,可以用for循环,1,3 2,3表示第一页,第二页
<!--查询所有-->
<select id="selectAll" resultType="com.bjpowernode.domain.Student">
select * from student order by id
</select>
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//加入PageHelper的方法,分页
// pageNum: 第几页, 从1开始
// pageSize: 一页中有多少行数据
PageHelper.startPage(1,3);
List<Student> students = dao.selectAll();
for(Student stu:students){
System.out.println("foreach--one ==="+stu);