MyBatis笔记
1.mybatis入门案例
1.创建Maven工程
2.添加mybatis坐标(建立依赖)
<dependencies>
网上找到格式导入
</dependencies>
3.编写实体类User
eg: id
name
sex
address
4.编写持久成IUserDao
写交互逻辑功能
5.编写持久层接口的映射文件
注:必须和持久层在相同的包结构下,且名称相同,后缀名 .xml
6.编写sqlMapconfig.xml配置文件
<configuration>
<!--配置环境-->
<environments default="mysql">
<!--配置MySQL环境-->
<environment id="mysql">
<!--配置事务类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源-->
<dataSource type="POOLED">
<!--配置数据库4个基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/hmkdb"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置,映射配置文件值得是每个独立dao配置文件的位置-->
<mappers>
<mapper resource="com.hmk.dao.IUserDao.xml"/>
</mappers>
</configuration>
7.编写测试类
public class MybatisTest {
public static void main(String[] args)throws Exception {
//1.读取配置文件(主配置文件)
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建 SqlSessionFactory 的构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.使用构建者创建工厂对象 SqlSessionFactory
SqlSessionFactory factory = builder.build(in);
//4.使用 SqlSessionFactory 生产 SqlSession 对象
SqlSession session = factory.openSession();
//5.使用 SqlSession 创建 dao 接口的代理对象
IUserDao userDao = session.getMapper(IUserDao.class);
//6.使用代理对象执行查询所有方法
List<User> users = userDao.findAll();
for(User user : users) {
System.out.println(user);
}
//7.释放资源
session.close();
in.close();
}
}
2.使用注解(Annotation)
1.主配置文件保留,在DAO接口写上注解
@Select("select * from user")
2.修改主配置文件
修改主配置文件SqlMapConfig中mappers中为class,映射被注解的dao全限定类名;
<mappers>
<mapper class="com.hmk.dao.IUserDao"/>
</mappers>
*实际开发中不写实现类
3.CRUD(.xml)
eg:插入数据
1.准备前提
将测试类中的工厂创建,获取代理对象和资源的关闭封装
@Before
public void init() throws Exception {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(in);
//3.使用工厂生产SqlSession对象
session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
userDao = session.getMapper(IUserDao.class);
}
@After
public void destory() throws Exception {
//6.释放资源
session.close();
in.close();
}
2.增加IUserDao接口中的方法
/**
* 保存数据
*/
public void Save(User user);
3.修改IUserDao.xml配置文件
<!--插入新用户-->
<insert id="save" parameterType="com.hmk.domain.User">
insert into user(username,birthday,sex,address)value (#{username},#{birthday},#{sex},#{address})
</insert>
4.测试
@Test
public void testSave() {
User user = new User();
user.setUsername("贺梦坤");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("焦作市博爱县");
//执行保存
userDao.Save(user);
//提交事务
session.commit();
}
eg:得到插入后的id值
*其余操作同上
4.OGNL表达式
object group navigation language(对象图导航语言)
通过对象的取值方法来获取数据,通常省略get
eg:获取用户名称
类中:user.getusername();
ognl:user.username;
*mybatis中提供了parameter属性所属类,省略user.
5.Resource,URL和URI
resource属性:常用,用于指定配置文件的位置,是按照类路径的写法来写,且必须存在于类路径下!
URL(uniform resource locator): 统一资源定位符可以唯一标识一个资源的位置
写法:http://Localhost:8080/mybatisserver/demo1
协议 主机 端口号 URI
URI(uniform resource identifier):统一资源标识符,它可以在应用中唯一定位一个资源
6.typeAliases标签和package标签
1.
<!--!写在properties下面-->
<typeAliases>
<!--取别名,不区分大小写-->
<!--<typeAlias type="com.hmk.domain.User" alias="user"></typeAlias>-->
<!--在此包下的类都被起了别名,且类名即使别名,不区分大小写-->
<package name="com.hmk.domain"/>
</typeAliases>
2.
<mappers>
<!--<mapper resource="com/hmk/Dao/IUserDao.xml"/>-->
<!--package写完不用写resource或URL-->
<package name="com.hmk.dao"/>
</mappers>
7.动态sql语句中的标签(where,if,foreach,sql)
1.where
代替SQL语句总的where
eg:
2.if
在多个where条件时使用,eg:查询时参数有个能有“用户名,id,性别...”其中几个或没有时
3.foreach
在查询中使用集合时,eg: select * from user where id in (41,43,45);
SQL 语句: select 字段 from user where id in (?) 标签用于遍历集合,
属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
4.sql
抽取SQL语句中的公共部分
8.利用注解开发
1.单表CRUD
-
总配置文件还是要写的!对应的xml不需要写。
-
mybatis中针对,crud有四种注解,@select,@insert,@update,@delete
public interface IUserDao {
//@Description 查询所有 @Select("select * from user") public List<User> findAll(); // @Description 保存用户 @Insert("insert into user(username,address,sex,birthday) values(#{username},#{address},# {sex},#{birthday})") public void saveUser(User user); // @Description 更新用户 @Update("update user set username=#{username},sex=#{sex},address=#{address},birthday=# {birthday} where id=#{id}") public void updateUser(User user); // @Description 删除用户 @Delete("Delete from user where id=#{id}") public void deleteUser(Integer id); // @Description 通过id查询 @Select("select * from user where id=#{id}") User findById(Integer id); // @Description 通过姓名模糊查询 //@Select("select * from user where username like #%{username}%") @Select("select * from user where username like '%${value}%'")//value固定值 List<User> findByName(String name); // @Description 查询总数 @Select("select count(*) from user") int findTotalCount(); }
2.多表链接
1.多表链接的形式有: 一对一 通常情况下我们都是采用立即加载。
多对一 通常情况下我们都是采用立即加载。(在mybatis中称为一对一)
一对多 通常情况下我们都是采用延迟加载
多对多 通常情况下我们都是采用延迟加载
eg1:多个账户可以对应一个用户(多对一)。
-
在账户实体表中建立用户的属性,并获取对应的getter和setter
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
} -
在IAccountDao接口中实现findAll方法查询所有账户,且在IUser接口中实现findById方法实现通过id查询用户
-
在IAcountDao接口中封装返回结果
@Select(“select * from account”)
@Results(id = “accountMap”,value = {
@Result(id = true,column = “id”,property = “id”),
@Result(column = “uid”,property = “uid”),
@Result(column = “money”,property = “money”),
@Result(property = “user”,column = “uid”,
one = @One(select = “com.hmk.dao.IUserDao.findById”,fetchType = FetchType.EAGER))
})
List findAll();
@Results中属性介绍:
id自己起的名字,实现复用
@Result 中 属性介绍:
id 是否是主键字段,true代表是
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Result(one=@One)())) select表示对应方法的全限定方法名。
fetchType表示加载方式,EAGER表示立即加载,LAYT表示延迟加载。 -
编写测试类
eg2:一个用户可以拥有多个账户(一对多)
-
在用户实体表中建立账户,返回类型为 List 的属性,并获取对应的getter和setter(因为返回一对多,所以使用集合)
private List account;
public List getAccount() {
return account;
}public void setAccount(List<Account> account) { this.account = account; }
-
在IUser接口中实现findAll方法查询所有账户,且在IAccountDao接口中实现findAccountByuId方法实现通过id查询账户
//实现findAccountByuId方法
@Select(“select * from account where uid=#{userId}”)
List findAccountByUid(Integer userId); -
在IUser接口中封装返回结果
@Select(“select * from user”)
@Results(id = “userMap”,value = {
@Result(id = true,column = “id”,property = “id”),
@Result(column = “username”,property = “username”),
@Result(column = “address”,property = “address”),
@Result(column = “sex”,property = “sex”),
@Result(column = “birthday”,property = “birthday”),
@Result(property = “account”,column = “id”,
many=@Many(select=“com.hmk.dao.IAccountDao.findAccountByUid”,fetchType= FetchType.LAZY))
})
public List findAll();
many 需要使用的@Many 注解(@Result(many=@many)())) -
编写测试类
9.延迟加载(LAZY)
1.延迟加载(.xml)
实际开发过程中很多时候我们并不需要总是在加载用户信息时就一定要加载他的账户信息。此时就是我 们所说的延迟加载。
优点:就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载. 好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速 度要快。
缺点:因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗 时间,所以可能造成用户等待时间变长,造成用户体验下降。
eg1:一对一中的延迟加载
- 修改IAccountDao.xml中的select语句(不能一次性实现全过程查询操作)
SELECT * from user
- 修改返回封装类型
- 编写中指定的select中全限定方法名(后续步骤要执行的SQL语句)
- 编写测试用例
eg2:一对多的延迟加载