[轉載] mybatis

參考鏈接: 在Java中使用_(下劃線)作為變量名

mybatis第一天??

1.mybatis概述和環境搭建??

mybatis概述??

mybatis環境搭建??

1. 創建maven工程、添加開發依賴、創建數據庫和表;??

2. 創建domain實體類和dao??

mybatis是一門java語言編寫持久層框架,大大簡化了jdbc操作,省去了我們注冊驅動,獲取連接等細節操作。??

??

org.mybatis?

mybatis?

3.4.5?

??

mysql?

mysql-connector-java?

8.0.11?

??

junit?

junit?

4.11?

test?

??

log4j?

log4j?

1.2.12?

3. 在resource中編寫mybatis主配置文件??

4. 編寫每個dao接口的映射配置文件??

/**??

* 用戶的持久層接口??

*/??

public interface IUserDao {??

/**??

* 查詢所有操作??

* @return??

*/??

List<User> findAll();??

}??

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"??

"http://mybatis.org/dtd/mybatis-3-config.dtd">??

??

default="mysql">??

id="mysql">??

type="jdbc">??

type="pooled">??

name="driver" value="com.mysql.jdbc.Driver"/>??

name="url" value="jdbc:mysql://localhost:3306/mybatis"/>??

name="username" value="root"/>??

name="password" value="78910J"/>??

??

resource="com/itheima/dao/IUserDao.xml">??

5.注意事項??

6.測試類中測試方法編寫??

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"??

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">??

namespace="com.itheima.dao.IUserDao">//namespace:接口的路徑 定位類中方法的具體位置??

id="findAll" resultType="com.itheima.domain.User"> SELECT * FROM USER??

1.在resource中創建IUserDao.xml時,文件的位置必須和IUserDao包結構相同,創建IUserDao.xml所在目錄結??

構時要一級一級創建。??

2.映射配置文件中的mapper的namespace屬性值必須是IUserDao的全類名??

3.執行sql操作的配置id屬性必須是執行方法的名詞,例如 <select id="findAll"??

@Test??

public void testFindAll() throws IOException {??

//1.讀取SqlMapConfig.xml配置文件??

InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");??

//2.創建SqlSessionFactory工廠類??

SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();??

SqlSessionFactory factory = builder.build(is);??

//3.使用SqlSessionFactory工廠創建SqlSession核心對象??

/*SqlSessionFactory是MyBatis的關鍵對象,它是個單個數據庫映射??

關系經過編譯后的內存鏡像.SqlSessionFactory對象的實例可以通??

過SqlSessionFactoryBuilder對象類獲得,而SqlSessionFactoryBuilder??

則可以從XML配置文件或一個預先定制的Configuration的實例構建出SqlSessionFactory??

的實例.每一個MyBatis的應用程序都以一個SqlSessionFactory對象的實例為核心.??

同時SqlSessionFactory也是線程安全的,SqlSessionFactory一旦被創建,應該在??

應用執行期間都存在.在應用運行期間不要重復創建多次,建議使用單例模式.SqlSessionFactory??

是創建SqlSession的工廠.*/??

SqlSession session = factory.openSession();//openSession方法默認手動提交 填寫false就是自動??

提交 當對表數據crud就需要提交事務??

//4.使用SqlSession創建接口的代理對象??

IUserDao userDao = session.getMapper(IUserDao.class);??

//5.執行查詢方法??

List<User> users = userDao.findAll();??

for (User user : users) {??

System.out.println(user);??

}??

//6.釋放資源??

is.close();??

session.close();??

}2.mybatis注解開發和編寫dao實體類方式??

mybatis注解開發??

編寫dao實現類開發??

1.在核心配置文件SqlMapConfig.xml的<mappers>中添加注解映射方式:??

<mappers>??

<mapper class="com.itheima.dao.IUserMapper"/>??

mappers>??

2.定義接口和抽象方法,在抽象方法上添加對應的注解:??

public interface IUserMapper {??

/**??

* 查詢所有用戶信息??

*/??

@Select("select * from user")??

public List<User> findList();??

}??

3.進行測試:??

@Test??

public void testFindList() throws IOException {??

//1.讀取核心配置文件??

InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");??

//2.創建SqlSessionFactory工廠類??

SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();??

SqlSessionFactory factory = builder.build(is);??

//3.創建SqlSession核心對象??

SqlSession session = factory.openSession();??

//4.獲取dao代理對象??

IUserMapper mapper = session.getMapper(IUserMapper.class);??

//5.執行查詢操作??

List<User> users = mapper.findList();??

for (User user : users) {??

System.out.println(user);??

}??

//6.釋放資源??

is.close();??

session.close();??

}??

1.編寫實現類:??

public class UserDaoImpl implements IUserDao{??

//1.聲明SqlSessionFactory工廠類??

private SqlSessionFactory factory;??

//2.構造賦值??

public UserDaoImpl(SqlSessionFactory factory) {??

this.factory = factory;??

}??

@Override??

public List<User> findAll() {注意:同一個dao接口不允許配置兩種映射方式,例如:下列寫法是錯誤的??

3.自定義mybatis框架??

流程分析??

自定義mybatis流程分析.png??

alt text??

Alt text??

alt text??

新建module,根據入門案例測試方法創建缺少的接口和類??

導入資料中utils目錄中的XMLConfifigBuilder.java文件,并修改錯誤??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用查詢的相關方法,哪個namespace中的哪個id方法對應的sql??

List<User> users = session.selectList("com.itheima.dao.IUserDao.findAll");??

//3.釋放資源??

session.close();??

return users;??

}??

}??

2.進行測試??

@Test??

public void testFindAllImpl() throws IOException {??

//1.讀取核心配置文件??

InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");??

//2.創建SqlSessionFactory工廠類??

SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();??

SqlSessionFactory factory = builder.build(is);??

//3.創建實現類對象并調用實現類方法查詢所有用戶信息??

UserDaoImpl dao=new UserDaoImpl(factory);??

List<User> users = dao.findAll();??

//4.遍歷輸出??

for (User user : users) {??

System.out.println(user);??

}??

//4.釋放資源??

is.close();??

}??

??

resource="com/itheima/dao/IUserDao.xml"/>??

class="com.itheima.dao.IUserDao"/>??

完成SqlSessionFactoryBuilder、SqlSessionFactory接口實現類、SqlSession接口實現類功能(實現類要自??

己創建)??

SqlSessionFactoryBuilder代碼實現??

1.添加依賴:??

<dependency>??

<groupId>dom4jgroupId>??

<artifactId>dom4jartifactId>??

<version>1.6.1version>??

dependency>??

<dependency>??

<groupId>jaxengroupId>??

<artifactId>jaxenartifactId>??

<version>1.1.6version>??

dependency>??

2.創建Configuration和Mapper兩個javabean對象??

public class Configuration {??

private String driver;??

private String url;??

private String username;??

private String password;??

private Map<String,Mapper> mappers=new HashMap<String, Mapper>();//保存多組映射信息的map集??

合??

// getter/setter方法省略??

public void setMappers(Map<String, Mapper> mappers) {??

this.mappers.putAll(mappers);??

}??

}??

public class Mapper {??

private String queryString;??

private String resultType;??

// getter/setter方法省略??

}??

/**??

* 構建者對象??

*/??

public class SqlSessionFactoryBuilder {??

/**??

* 根據配置文件輸入流對象創建工廠對象??

* @param configStream 配置文件輸入流??

* @return??

*/??

public SqlSessionFactory build(InputStream configStream) {??

//1.使用XMLConfigBuilder解析配置文件??

Configuration configuration = XMLConfigBuilder.loadConfiguration(configStream);??

System.out.println("configuration = " + configuration);??

//2.創建工廠實現類對象并返回??

return new DefaultSqlSessionFactory(configuration);DefaultSqlSessionFactory代碼實現??

DefaultSqlSession代碼實現??

}??

}??

/**??

* SqlSessionFactory接口的實現類??

*/??

public class DefaultSqlSessionFactory implements SqlSessionFactory {??

//聲明封裝主配置文件對象??

private Configuration configuration;??

public DefaultSqlSessionFactory(Configuration configuration) {??

this.configuration=configuration;??

}??

/**??

* 生產操作數據庫的核心SqlSession對象??

* @return??

*/??

public SqlSession openSession() {??

//創建SqlSession實現類對象并返回??

return new DefaultSqlSession(configuration);??

}??

}??

/**??

* 操作數據庫核心SqlSession接口的實現類??

*/??

public class DefaultSqlSession implements SqlSession {??

//聲明封裝主配置文件對象,因為getMapper需要連接和映射信息,所以需要這個配置對象??

private Configuration configuration;??

private Connection conn;??

public DefaultSqlSession(Configuration configuration) {??

this.configuration=configuration;??

//從連接池工具類中獲取連接對象??

conn= DataSourceUtils.getConnection(configuration);??

}??

/**??

* 通過動態代理的方式創建接口的實現類對象??

* @param daoClass 接口的Class對象??

* @param 返回接口實現類對象??

* @return??

*/??

public <T> T getMapper(Class<T> daoClass) {??

//創建dao代理對象并返回??

T t = (T) Proxy.newProxyInstance(daoClass.getClassLoader(),??

new Class[]{daoClass},??

new MapperProxy(configuration.getMappers(),conn));??

return t;DataSourceUtils工具類獲取連接??

InvocationHandler實現類MapperProxy的代碼實現??

}??

/**??

* 釋放資源??

*/??

public void close() {??

try {??

if (conn!=null) {??

conn.close();??

}??

} catch (SQLException e) {??

e.printStackTrace();??

}??

}??

}??

/**??

* 將來封裝連接池的工具類,目前不使用連接池??

*/??

public class DataSourceUtils {??

public static Connection getConnection(Configuration cfg) {??

//1.注冊驅動??

try {??

Class.forName(cfg.getDriver());??

//2.獲取連接??

return??

DriverManager.getConnection(cfg.getUrl(),cfg.getUsername(),cfg.getPassword());??

} catch (Exception e) {??

throw new RuntimeException(e);??

}??

}??

}??

/**??

* 當dao代理對象的方法被調用時,該監聽類的invoke方法就會執行??

*/??

public class MapperProxy implements InvocationHandler {??

//map集合的key=全類名+方法名??

private Map<String, Mapper> mappers;//封裝了sql語句和結果類型??

private Connection conn;//連接對象??

public MapperProxy(Map<String, Mapper> mappers,Connection conn) {??

this.mappers=mappers;??

this.conn=conn;??

}??

//當dao代理對象的方法被調用時,invoke方法就會執行,參數method表示代理對象調用的方法??

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {??

//1.根據執行的method方法從mappers集合中找到對應的mapper對象??

//1.1.獲取方法名將MapperProxy中需要的Executor類從資料中復制到項目的utils包下,該Executor類的selectList方法幫??

我們查詢所有信息并封裝到List中??

注意:在沒網的情況下,需要刪除SqlMapConfifig和映射文件的約束信息;??

mybatis第二天??

1.mybatis的CRUD操作??

1.1.映射配置文件IUserDao.xml信息??

String methodName = method.getName();??

//1.2.獲取全類名??

String className = method.getDeclaringClass().getName();??

//1.3.拼接map集合的key,找到對應的mapper對象??

String key=className+"."+methodName;??

System.out.println("key = " + key);??

//1.4.找到要的Mapper對象??

Mapper mapper = mappers.get(key);??

if (mapper==null) {??

//沒找到,配置的全類名有誤或者方法有誤??

throw new IllegalStateException("在"+className+"類中沒有"+methodName+"方法");??

}??

//2.調用Executor工具類的selectList方法執行查詢操作??

return new Executor().selectList(mapper,conn);??

}??

}??

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"??

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">??

namespace="com.itheima.dao.IUserDao">??

id="findAll" resultType="com.itheima.domain.User"> SELECT * from user??

id="saveUser" parameterType="com.itheima.domain.User">??

/*添加用戶信息之后查詢新用戶的id keyProperty對應的是user的id屬性*/??

keyColumn="id" keyProperty="id" resultType="int" order="AFTER">??

select last_insert_id();??

/*selectKey是后來加的,在添加用戶信息時可以先忽略*/??

insert into user values (null,#{username},#{birthday},#{sex},#{address})??

id="updateUser" parameterType="com.itheima.domain.User">1.2.封裝數據的User類省略??

1.3.測試類代碼??

update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}??

where id=#{id}??

id="deleteUser" parameterType="Integer">??

delete from user where id=#{id}??

id="findById" resultType="com.itheima.domain.User" parameterType="int"> select * FROM user where id=#{id}??

id="findByName" parameterType="String" resultType="com.itheima.domain.User"> select * from user where username like #{username}??

id="findTotal" resultType="int"> select count(*) from user??

public class MybatisTest {??

private InputStream is;??

private SqlSession session;??

private IUserDao userDao;??

/**??

* 初始化mybatis??

*/??

@Before??

public void init() throws IOException {??

//1.加載核心配置文件SqlMapConfig.xml??

is = Resources.getResourceAsStream("SqlMapConfig.xml");??

//2.創建SqlSessionFactory工廠對象??

SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();??

SqlSessionFactory factory = builder.build(is);??

//3.創建核心SqlSession對象??

session = factory.openSession();??

//4.創建IUserDao對象??

userDao = session.getMapper(IUserDao.class);??

}??

/**??

* 測試查詢所有用戶信息的findAll()方法??

*/??

@Test??

public void testFindAll(){??

List<User> users = userDao.findAll();??

//遍歷打印??

for (User user : users) {System.out.println(user);??

}??

}??

/**??

* 測試保存用戶信息的saveUser()方法??

*/??

@Test??

public void testSaveUser(){??

//創建用戶信息??

User user=new User();??

user.setUsername("老周");??

user.setBirthday(new Date());??

user.setAddress("武漢");??

user.setSex("男");??

System.out.println("添加前user = " + user);??

//添加到數據??

int row = userDao.saveUser(user);??

System.out.println("影響的行數row = " + row);??

//在IUserDao.xml配置了selectKey后,添加完user就會查詢到新用戶的id并封裝到user的id屬性上。??

System.out.println("添加后user = " + user);??

}??

/**??

* 測試更新用戶信息的updateUser()方法??

*/??

@Test??

public void testUpdateUser(){??

//準備要修改用戶的信息信息??

User user=new User();??

user.setId(52);??

user.setUsername("老李");??

user.setBirthday(new Date());??

user.setAddress("孝感");??

user.setSex("女");??

//修改用戶??

int row = userDao.updateUser(user);??

System.out.println("row = " + row);??

}??

/**??

* 測試更加用戶id刪除用戶信息的deleteUser()方法??

*/??

@Test??

public void testDeleteUser(){??

//根據id刪除用戶信息??

int row = userDao.deleteUser(52);??

System.out.println("row = " + row);??

}??

/**??

* 測試根據id查詢用戶信息的findById()方法??

*/??

@Test??

public void testFindById(){??

User user = userDao.findById(50);??

System.out.println(user);2.mybatis映射配置參數和返回值類型深入學習??

2.1.parameterType傳遞pojo包裝對象??

QueryVo實體類??

映射文件配置??

}??

/**??

* 測試根據用戶名稱模糊查詢的findByName()方法??

*/??

@Test??

public void testFindByName(){??

List<User> users = userDao.findByName("%王%");??

for (User user : users) {??

System.out.println(user);??

}??

}??

/**??

* 測試查詢總記錄條數的findTotal()方法??

*/??

@Test??

public void testFindTotal(){??

int total = userDao.findTotal();??

System.out.println("total = " + total);??

}??

/**??

* 釋放資源??

*/??

@After??

public void destory() throws IOException {??

//提交事務??

session.commit();??

//6.釋放資源??

session.close();??

is.close();??

}??

}??

public class QueryVo {??

private User user;??

public User getUser() {??

return user;??

}??

public void setUser(User user) {??

this.user = user;??

}??

}測試類測試方法編寫??

mybatis的dao層開發模式??

返回值類型-javabean的屬性和表字段名一致情況(了解)??

javabean實體類??

id="findByVo" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User"> /*username是user的屬性,user是QueryVo的屬性*/ select * from user where username like #{user.username}??

/**??

* 測試根據 QueryVo 中的條件查詢用戶的findByVo()方法??

*/??

@Test??

public void testFindByVo(){??

//創建QueryVo對象??

QueryVo queryVo=new QueryVo();??

//創建模糊查詢條件封裝到user對象中??

User user=new User();??

user.setUsername("%王%");??

queryVo.setUser(user);??

//執行查詢??

List<User> users = userDao.findByVo(queryVo);??

//遍歷打印??

for (User u : users) {??

System.out.println(u);??

}??

}??

* 基于DAO代理方式(推薦使用)??

* CRUD操作(保存操作|修改操作|刪除操作|查詢一個|模糊查詢|單值查詢|獲取保存對象的id)??

* 模糊查詢需要注意??

* 獲取保存對象的id??

* 輸入參數 parameterType屬性??

* 輸入參數的類型:int、string、User、plain old java object、包裝類型ValueObject??

* 輸出參數 resultType屬性、??

* 輸入參數的類型:User、int、string??

* 解決實體類屬性和數據庫列名不對應??

* 在sql語句上取別名, 對應, 簡單??

* 通過resultMap屬性來映射java對象和數據庫列名之間的關系??

* <result property="userName" column="username">result>??

property 遵循的是駝峰規則; column 單詞下劃線隔開解決辦法1:sql的結果集使用別名,別名和javabean的屬性一致??

好處:查詢效率高;弊端:書寫麻煩,開發效率低。??

解決辦法2:使用mybatis給我們提供的配置結果集映射??

好處:id="UMap"的可以重復使用,開發效率高;弊端:查詢效率略低。??

編寫測試類測試方法??

public class U {??

private Integer userId;??

private String userName;??

private Date userBirthday;??

private String userSex;??

private String userAddress;??

//自動生成setter、getter、toString省略,此時屬性和表的字段名不一致??

}??

id="findAllU" resultType="com.itheima.domain.U"> select id userId,username userName,birthday userBirthday,sex userSex,address userAddress from user;??

id="UMap" type="com.itheima.domain.U">??

column="id" property="userId"/>??

column="username" property="userName"/>??

column="birthday" property="userBirthday"/>??

column="sex" property="userSex"/>??

column="address" property="userAddress"/>??

id="findAllU" resultMap="UMap"> select * from user; 3.mybatis中編寫dao實現類的使用(了解)??

UserDaoImpl實現類代碼??

/**??

* 測試使用別名,查詢所有用戶信息的findAllU()方法??

*/??

@Test??

public void testFindAllU(){??

List<U> us = userDao.findAllU();??

//遍歷打印??

for (U u : us) {??

System.out.println(u);??

}??

}??

public class UserDaoImpl implements IUserDao {??

private SqlSessionFactory factory;??

//接收工廠對象,用于創建SqlSession對象??

public UserDaoImpl(SqlSessionFactory factory) {??

this.factory = factory;??

}??

@Override??

public List<User> findAll() {??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用selectList方法查詢所有用戶信息??

List<User> users = session.selectList("com.itheima.dao.IUserDao.findAll");??

//3.釋放資源??

session.close();??

return users;??

}??

@Override??

public int saveUser(User user) {??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用insert方法添加一條用戶信息??

int row = session.insert("com.itheima.dao.IUserDao.saveUser", user);??

//3.提交并釋放資源??

session.commit();??

session.close();??

//返回影響的函數??

return row;??

}??

@Override??

public int updateUser(User user) {??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用update方法修改一條用戶信息??

int row = session.update("com.itheima.dao.IUserDao.updateUser", user);??

//3.提交并釋放資源session.commit();??

session.close();??

//返回影響的函數??

return row;??

}??

@Override??

public int deleteUser(int id) {??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用delete方法刪除一條用戶信息??

int row = session.delete("com.itheima.dao.IUserDao.deleteUser", id);??

//3.提交并釋放資源??

session.commit();??

session.close();??

//返回影響的函數??

return row;??

}??

@Override??

public User findById(Integer id) {??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用selectList方法查詢所有用戶信息??

User user = session.selectOne("com.itheima.dao.IUserDao.findById",id);??

//3.釋放資源??

session.close();??

return user;??

}??

@Override??

public List<User> findByName(String username) {??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用selectList方法根據username模糊查詢所有用戶信息??

List<User> users = session.selectList("com.itheima.dao.IUserDao.findByName",username);??

//3.釋放資源??

session.close();??

return users;??

}??

@Override??

public int findTotal() {??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用delete方法刪除一條用戶信息??

int total = session.selectOne("com.itheima.dao.IUserDao.findTotal");??

//3.釋放資源??

session.close();??

//返回總記錄數??

return total;??

}??

@Override??

public List<User> findByVo(QueryVo vo) {??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用selectList方法根據vo.user.username模糊查詢所有用戶信息修改測試類init方法和destory方法即可,其他測試方法都不需要改??

4.mybatis中編寫dao實現類的使用過程分析??

5.properties標簽、typeAliases標簽、package標簽使用??

5.1.properties標簽的作用??

List<User> users =??

session.selectList("com.itheima.dao.IUserDao.findByName",vo.getUser().getUsername());??

//3.釋放資源??

session.close();??

return users;??

}??

@Override??

public List<U> findAllU() {??

//1.創建核心的SqlSession對象??

SqlSession session = factory.openSession();??

//2.調用selectList方法查詢所有用戶信息??

List<U> us = session.selectList("com.itheima.dao.IUserDao.findAllU");??

//3.釋放資源??

session.close();??

return us;??

}??

}??

@Before??

public void init() throws IOException {??

//1.加載核心配置文件SqlMapConfig.xml??

is = Resources.getResourceAsStream("SqlMapConfig.xml");??

//2.創建SqlSessionFactory工廠對象??

SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();??

SqlSessionFactory factory = builder.build(is);??

/*如果是使用dao代理方式,則需要創建SqlSession對象,并獲取dao的代理對象*/??

/*//3.創建核心SqlSession對象??

session = factory.openSession();??

//4.創建IUserDao對象??

userDao = session.getMapper(IUserDao.class);*/??

/*如果使用的是自定義dao實現類方法,則需要創建dao實現類對象,并傳遞factory工廠對象*/??

userDao=new UserDaoImpl(factory);??

}??

@After??

public void destory() throws IOException {??

//提交事務,如果是自定義dao實現類就不需要,在實現類內部提交??

//session.commit();??

//6.釋放資源,如果是自定義dao實現類就不需要,在實現類內部關閉??

//session.close();??

is.close();??

}作用:將連接數據庫的信息單獨配置到一個properties屬性文件中,配置方式如下??

外部jdbcConfifig.properties配置文件??

在SqlMapConfifig.xml跟標簽下使用properties標簽引入jdbcConfifig.properties??

在dataSource中引入外部properties的各個屬性??

5.2.typeAliases標簽、package標簽使用作用??

SqlMapConfifig.xml跟標簽下使用typeAliases標簽作用 :javabean取別名(了解)??

jdbc.driver=com.mysql.jdbc.Driver??

jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai??

jdbc.username=root??

jdbc.password=78910J??

??

name="driver" value="com.mysql.jdbc.Driver"/>??

name="url" value="jdbc:mysql://localhost:3306/mybatis???

serverTimezone=Asia/Shanghai"/>??

name="username" value="root"/>??

name="password" value="78910J"/>??

或者??

resource="jdbcConfig.properties">??

或者??

url="??

file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.prop??

erties">??

type="pooled">??

name="driver" value="${jdbc.driver}"/>??

name="url" value="${jdbc.url}"/>??

name="username" value="${jdbc.username}"/>??

name="password" value="${jdbc.password}"/>??

typeAliases標簽下使用package標簽作用 :指定包下的所有javabean的類名就是其別名,不區分大小寫??

(實用)??

Mappers標簽下使用package標簽作用 :不用寫mapper標簽,resources或class指定包下所有dao對應的??

映射文件都不用引入了,并且可以找到dao的接口或者dao接口對應的配置。(實用)??

mybatis第三天??

1.mybatis中連接池以及事務管理??

1.1 mybatis連接池??

mybatis中三種數據源介紹??

在sqlMapConfifig.xml中配置??

??

type="com.itheima.domain.User" alias="user"/>??

??

??

name="com.itheima.dao"/>??

UNPOOLED 不使用連接池的數據源,需要連接對象就使用DriverManager創建獲取一個,使用完成就直接銷毀??

POOLED 使用連接池的數據源 (很常用)??

JNDI 使用 JNDI 實現的數據源(最后講解,了解)1.2 mybatis事務管理??

mybatis中默認是開啟也是,也就是增刪改之后需要手動session.commit()方法手動提交事務;但是我們也可以設??

置自動提交,在增刪改完成之后不需要手動調用session.commit()提交事務。只需要在session =??

factory.openSession(true);參數true表示自動提交。??

2.mybatis中動態SQL??

使用場景:如果條件存在就帶條件查詢,如果條件不存在就不帶條件查詢,適用于搜索等場景。??

2.1 if標簽 - 動態添加條件??

在IUserDao.xml中配置查詢語句??

2.2 where 標簽 - 代替where 1=1??

在IUserDao.xml中修改之前配置的查詢語句??

在sqlMapConfig.xml中配置如下??

type="pooled">??

name="driver" value="${jdbc.driver}"/>??

name="url" value="${jdbc.url}"/>??

name="username" value="${jdbc.username}"/>??

name="password" value="${jdbc.password}"/>??

MyBatis 在初始化時,根據的 type 屬性來創建相應類型的的數據源 DataSource,即:??

type="POOLED": MyBatis 會創建 PooledDataSource 實例??

type="UNPOOLED": MyBatis 會創建 UnpooledDataSource 實例??

type="JNDI": MyBatis 會從 JNDI 服務上查找 DataSource 實例,然后返回使用??

id="findUserByCondition1" parameterType="user" resultType="user"> select * from user where 1=1 test="username!=null and username!=''">//連接判斷條件不能為&&和|| and username = #{username} test="sex!=null"> and sex = #{sex} 2.3 foreach標簽 - 遍歷,適用于in的條件??

foreach元素的屬性主要有 item,index,collection,open,separator,close。??

item: 循環體中的具體對象。支持屬性的點路徑訪問,如 item.age,item.info.details。具體說明:在 list 和數??

組中是其中的對象,在 map 中是 value,該參數為必選。(它是每一個元素進行迭代時的別名)??

index:在 list 和數組中,index 是元素的序號;在 map 中,index 是元素的 key。??

open :表示該語句以什么開始??

separator :表示在每次進行迭代之間以什么符號作為分隔符??

close :表示以什么結束??

_parameter :不只是方法傳遞過來的參數可以被用來判斷,取值??

_parameter:代表整個參數??

單個參數:_parameter就是這個參數??

多個參數: 1.參數會被封裝為一個map:_parameter就是代表這個map??

2._parameter 可以get(0)得到第一個參數。??

在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是在不同情況 下,該??

屬性的值是不一樣的,主要有一下3種情況:??

1.如果傳入的是單參數且參數類型是一個List的時候,collection屬性值為list??

2.如果傳入的是單參數且參數類型是一個array數組的時候,collection的屬性值為array??

3.如果傳入的參數是多個的時候,我們就需要把它們封裝成一個Map了,當然單參數也可以封裝成map??

遍歷map集合??

id="findUserByCondition1" parameterType="user" resultType="user"> select * from user test="username!=null and username!=''"> and username = #{username} test="sex!=null"> and sex = #{sex} 需求:根據qv中list集合查詢用戶信息-??

在IUserDao.xml中配置查詢語句??

測試類中測試- QueryVo中添加ids屬性省略了??

id="findByMap" parameterType="map" resultType="cn.itcast.mybatis.pojo.Product"> select * from user collection="_parameter" index="key" item="value" separator="and"> test="value !=null"> ${key} = #{value}??

id="findUserByCondition2" parameterType="QueryVo" resultType="user"> select * from user test="ids!=null and ids.size>0"> id="findUserByCondition2" parameterType="QueryVo" resultType="user">??

select * from user??

??

test="ids!=null and ids.size>0">??

and id in(??

collection="ids" item="uid" separator=",">??

#{uid}??

)??

@Test??

public void testFindUserByCondition2(){??

QueryVo qv=new QueryVo();??

List<Integer> ids=new ArrayList<Integer>();??

ids.add(41);2.4 補充1:抽取公共的sql語句??

在IUserDao.xml中跟標簽中使用sql標簽定義公共sql語句??

在中使用標簽引入公共sql 3.mybatis多表之間關系 3.1 一對一關系 需求:一個賬戶只屬于一個用戶,查詢賬戶信息的同時查詢用戶信息 實現步驟: 一對一映射 代碼示例: 1.創建Account實體類以及IAccountDao接口 ids.add(45); ids.add(46); ids.add(48); qv.setIds(ids); List<User> list = userDao.findUserByCondition2(qv); //變量展示 for (User u : list) { System.out.println("u = " + u); } } id="selectTemplate"> select * from user id="findAll" resultType="com.itheima.domain.User">??

refid="selectTemplate"/>??

1.創建Account實體類以及IAccountDao接口??

2.創建IAccountDao.xml映射問題??

3.創建AccountDaoTest測試類進行測試??

public class Account implements Serializable {??

private Integer id;??

private Integer uid;??

private Double money;??

//封裝對應的user對象2.創建IAccountDao.xml映射文件??

3.創建AccountTest測試類進行測試??

private User user;??

//setter、getter、toString方法省略??

}??

public interface IAccountDao {??

/**??

* 查詢所有賬號信息同時查詢對應用戶信息??

* @return??

*/??

List<Account> findAll();??

}??

namespace="com.itheima.dao.IAccountDao">??

id="accountUserMap" type="account">??

column="aid" property="id"/>??

column="uid" property="uid"/>??

column="money" property="money"/>??

property="user" javaType="user" column="uid">??

column="id" property="id"/>??

column="username" property="username"/>??

column="birthday" property="birthday"/>??

column="sex" property="sex"/>??

column="address" property="address"/>??

id="findAll" resultMap="accountUserMap"> /*注意:當多表查詢結果有相同字段名時,我們需要取別名區分*/ SELECT u.*,a.id aid,a.UID,a.MONEY FROM user u,account a where u.id=a.UID;??

@Test??

public void testFindAll(){??

//1.調用findAll方法??

List<Account> list = accountDao.findAll();??

//2.遍歷打印結果??

for (Account account : list) {??

System.out.println(account);??

}??

}注意:當多表查詢結果有相同字段名時,我們需要取別名區分??

3.2 一對多關系??

需求:一個用戶有多個賬戶,查詢用戶信息的同時查詢其所有賬戶信息??

實現步驟??

一對多映射??

代碼示例??

在IUserDao中添加新的查詢方法??

在IUserDao.xml中重新配置查詢語句??

編寫UserTest測試類進行測試??

1.在user中添加List<Account> accounts屬性,在IUserDao中添加新的查詢方法??

2.在IUserDao.xml中重新配置查詢語句??

3.在AccountDaoTest測試類進行測試??

/**??

* 多表查詢:查詢用戶信息的同時查詢其所有賬戶信息??

* @return??

*/??

List<User> findAllUserAndAccount();??

id="userAccountMap" type="user">??

column="id" property="id"/>??

column="username" property="username"/>??

column="birthday" property="birthday"/>??

column="sex" property="sex"/>??

column="address" property="address"/>??

property="accounts" javaType="java.util.List" ofType="account">??

column="id" property="id"/>??

column="uid" property="uid"/>??

column="money" property="money"/>??

id="findAllUserAndAccount" resultMap="userAccountMap"> SELECT * FROM user u LEFT OUTER JOIN account a ON u.id = a.UID; 3.3 多對多關系??

3.3.1 需求1:查詢角色信息以及該角色對應的所有用戶信息??

實現步驟??

代碼示例??

1.創建實體類Role以及IRoleDao接口??

/**??

* 多表查詢:查詢用戶信息的同時查詢其所有賬戶信息??

*/??

@Test??

public void testFindAllUserAndAccount(){??

List<User> users = userDao.findAllUserAndAccount();??

for (User user : users) {??

System.out.println(user);??

}??

}??

1.創建實體類Role以及IRoleDao接口??

2.創建IRoleDao.xml映射文件,并配置查詢信息??

3.創建RoleDaoTest測試類,并測試查詢方法??

public class Role {??

private Integer id;??

private String roleName;??

private String roleDesc;??

//封裝該角色對應的所有用戶信息??

private List<User> users;??

//setter、getter、toString方法省略??

}??

public interface IRoleDao {2.創建IRoleDao.xml映射文件,并配置查詢信息??

3.創建RoleDaoTest測試類,并測試查詢方法??

3.3.2 需求2:查詢用戶信息以及該用戶對應的所有角色信息??

實現步驟??

代碼示例??

/**??

* 需求1:查詢角色信息以及該角色對應的所有用戶信息??

*/??

List<Role> findAll();??

}??

namespace="com.itheima.dao.IRoleDao">??

id="roleMap" type="role">??

column="rid" property="id"/>??

column="ROLE_NAME" property="roleName"/>??

column="ROLE_DESC" property="roleDesc"/>??

property="users" javaType="java.util.List" ofType="user">??

column="id" property="id"/>??

column="username" property="username"/>??

column="birthday" property="birthday"/>??

column="sex" property="sex"/>??

column="address" property="address"/>??

id="findAll" resultMap="roleMap"> SELECT r.ID rid,r.ROLE_NAME,r.ROLE_DESC,u.* FROM role r LEFT JOIN user_role ur ON r.ID = ur.RID LEFT JOIN user u ON ur.UID = u.id??

@Test??

public void testFindAll(){??

List<Role> roles = roleDao.findAll();??

for (Role role : roles) {??

System.out.println(role);??

}??

}??

1.在實體類User中添加List<Role> roles屬性,并在IUserDao中添加新的查詢方法??

2.在IUserDao.xml中重新配置查詢語句??

3.在UserDaoTest測試類進行測試1.在IUserDao中添加新的查詢方法??

2.在IUserDao.xml中重新配置查詢語句??

3.在UserDaoTest測試類進行測試??

4.補充:JNDI??

mybatis第四天??

1.mybatis延遲加載??

1.1 概念??

/**??

* 需求2:查詢用戶信息以及該用戶對應的所有角色信息??

*/??

List<User> findAllUserAndRole();??

id="userRoleMap" type="user">??

column="id" property="id"/>??

column="username" property="username"/>??

column="birthday" property="birthday"/>??

column="sex" property="sex"/>??

column="address" property="address"/>??

property="roles" javaType="java.util.List" ofType="role">??

column="rid" property="id"/>??

column="ROLE_NAME" property="roleName"/>??

column="ROLE_DESC" property="roleDesc"/>??

id="findAllUserAndRole" resultMap="userRoleMap"> SELECT u.*,r.ID rid,r.ROLE_NAME,r.ROLE_DESC FROM user u LEFT JOIN user_role ur ON u.id = ur.UID LEFT JOIN role r ON ur.RID = r.ID;??

@Test??

public void testFindAllUserAndRole(){??

List<User> users = userDao.findAllUserAndRole();??

for (User user : users) {??

System.out.println(user);??

}??

}1.2 一對一實現延遲加載??

1.2.1 在主配置文件SqlMapConfifig.xml中開啟全局延遲加載??

1.2.2 在映射配置文件IAccountDao.xml中配置延遲加載查詢??

1.2.3 在AccountDaoTest測試類中進行測試??

1.3 一對多實現延遲加載??

1.3.1 在映射配置文件IUserDao.xml中配置延遲加載查詢??

1.立即加載:只要一調用方法,不管用不用的到數據都立馬去關聯查詢??

2.延遲加載:只有再用到數據時才去關聯查詢,不用就不關聯查詢,好處:先從單表查詢,需要時再從關聯表去關聯查??

詢,大大提高數據庫性能;延遲加載也叫按需加載或懶加載??

??

name="lazyLoadingEnabled" value="true"/>??

name="aggressiveLazyLoading" value="false"/>??

id="accountMap" type="account">??

column="id" property="id"/>??

column="uid" property="uid"/>??

column="money" property="money"/>??

property="user" javaType="user" column="uid"??

select="com.itheima.dao.IUserDao.findById"/>??

id="findAll" resultMap="accountMap"> select * FROM account??

/**??

* 延遲加載:查詢所有賬號信息同時查詢對應用戶信息??

*/??

@Test??

public void testFindAll() {??

List<Account> accounts = accountDao.findAll();??

/*只要不調用和user相關的方法,就不會查關聯表中的數據*/??

for (Account account : accounts) {??

System.out.println(account.getId()+","+account.getUid()+","+account.getMoney());??

}??

}1.3.2 在IAccountDao中添加fifindAccountById方法并在IAccountDao.xml配置??

1.3.3 在UserDaoTest測試類中進行測試??

2.mybatis中的一級緩存和二級緩存??

2.1 緩存的概念??

2.2 一級緩存??

概念??

id="userMap" type="user">??

column="id" property="id"/>??

column="username" property="username"/>??

column="birthday" property="birthday"/>??

column="sex" property="sex"/>??

column="address" property="address"/>??

property="accounts" ofType="account"??

select="com.itheima.dao.IAccountDao.findAccountById" column="id"/>??

id="findAll" resultMap="userMap"> SELECT * FROM USER ;??

id="findAccountById" parameterType="int" resultType="account"> SELECT * FROM account where uid=#{uid};??

@Test??

public void testFindAll() {??

List<User> list = userDao.findAll();??

for (User u : list) {??

System.out.println(u.getId()+","+u.getUsername()+","+u.getBirthday()+","+u.getSex()+","+u.getAd??

dress());??

/*只要不調用和account相關的方法,就不會查關聯表中的數據*/??

/*System.out.println(u.getAccounts());*/??

}??

}??

存在內存中的臨時數據就是緩存代碼演示??

結果說明??

2.3 二級緩存??

概念??

代碼演示??

它指的是Mybatis中SqlSession對象的緩存。當我們執行查詢之后,查詢的結果會同時存入到SqlSession為我們??

提供一塊區域中。該區域的結構是一個Map。當我們再次查詢同樣的數據,mybatis會先去sqlsession中查詢是否有,有??

的話直接拿出來用。當SqlSession對象消失時(close方法被調用),mybatis的一級緩存也就消失了。??

@Test??

public void testFirstLeverCache(){??

User user1 = userDao.findById(43);??

System.out.println("user1 = " + user1);??

//測試一下關閉session??

/*session.close();??

session=factory.openSession(true);??

userDao=session.getMapper(IUserDao.class);*/??

//也可以清除緩存??

//session.clearCache();??

//再次執行相同的查詢??

User user2 = userDao.findById(43);??

System.out.println("user2 = " + user2);??

//判斷user1和user2是不是同一個對象??

System.out.println("user1==user2 : " + (user1==user2));??

}??

如果是同一個session對象,那么第二次查詢的user對象和第一次查詢的user對象是同一個user對象,最后打印的??

結果是true,通過控制臺日志可以看出只執行了一次查詢;當中間關閉了session或者調用clearCache方法清除緩存之??

后,那兩個user對象就不是同一個對象了,控制臺查看日志也會發現執行了兩次查詢。??

它指的是Mybatis中SqlSessionFactory對象的緩存。由同一個SqlSessionFactory對象創建的SqlSession共享??

其緩存。??

二級緩存的使用步驟:??

第一步:讓Mybatis框架支持二級緩存(在SqlMapConfig.xml中配置)??

第二步:讓當前的映射文件支持二級緩存(在IUserDao.xml中配置)??

第三步:讓當前的操作支持二級緩存(在select標簽中配置)??

@Test??

public void testSecondLeverCache(){??

//1.獲取第一個sqlSession對象并查詢user??

SqlSession session1 = factory.openSession(true);??

IUserDao userDao1 = session1.getMapper(IUserDao.class);??

User user1 = userDao1.findById(43);結果說明以及注意事項??

3.mybatis注解開發??

3.1 mybatis注解開發CRUD操作??

3.1.1 SqlMapConfifig核心配置文件環境搭建??

System.out.println("user1 = " + user1);??

//關閉session1??

session1.close();??

//2.獲取第二個sqlSession對象并查詢user??

SqlSession session2 = factory.openSession(true);??

IUserDao userDao2 = session2.getMapper(IUserDao.class);??

User user2 = userDao2.findById(43);??

System.out.println("user2 = " + user2);??

session2.close();??

//判斷user1和user2是不是同一個對象??

System.out.println("user1==user2 : " + (user1==user2));??

}??

兩個對象雖然不是同一個對象,但是通過控制臺發現只執行了一次查詢??

注意:一定要關閉之前的sqlSession對象??

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"??

"http://mybatis.org/dtd/mybatis-3-config.dtd">??

??

resource="jdbcConfig.properties"/>??

??

name="com.itheima.domain"/>??

default="mysql">??

id="mysql">??

type="jdbc">??

type="pooled">??

name="driver" value="${jdbc.driver}"/>??

name="url" value="${jdbc.url}"/>??

name="username" value="${jdbc.username}"/>??

name="password" value="${jdbc.password}"/>??

??

name="com.itheima.dao"/>??

3.1.2 IUserDao中給方法添加注解??

/**??

* 查詢所有操作??

* @return??

*/??

@Select("select * from user")??

List<User> findAll();??

/**??

* 保存用戶??

* @param user??

* @return 影響數據庫記錄的行數??

*/??

@Insert("insert into user values(null,#{username},#{birthday},#{sex},#{address})")??

//配置SelectKey將新添加用戶的id封裝到user中??

@SelectKey(keyColumn = "id",keyProperty = "id",resultType =int.class,before = false, statement =??

"select last_insert_id()")??

int saveUser(User user);??

/**??

* 更新用戶??

* @param user??

* @return 影響數據庫記錄的行數??

*/??

@Update("update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}??

where id=#{id}")??

int updateUser(User user);??

/**??

* 根據 id 刪除用戶??

* @param id??

* @return 影響數據庫記錄的行數??

*/??

@Delete("delete from user where id=#{id}")??

int deleteUser(int id);??

/**??

* 根據 id 查詢??

* @param id??

* @return??

*/??

@Select("select * from user where id=#{id}")??

User findById(Integer id);??

/**??

* 根據名稱模糊查詢??

* @param username??

* @return??

*/??

@Select("select * from user where username LIKE #{username};")??

List<User> findByName(String username);??

/**3.1.3 在測試類中測試??

* 查詢總記錄條數??

* @return 總記錄條數??

*/??

@Select("select count(*) from user;")??

int findTotal();??

/**??

* 根據 QueryVo 中的條件查詢用戶??

* @param vo??

* @return??

*/??

@Select(" select * from user where username like #{user.username}")??

List<User> findByVo(QueryVo vo);??

private InputStream is;??

private SqlSession session;??

private IUserDao userDao;??

private SqlSessionFactory factory;??

@Before??

public void init() throws IOException {??

//1.獲取主配置文件輸入流??

is = Resources.getResourceAsStream("SqlMapConfig.xml");??

//2.創建SqlSessionFactory工廠對象??

factory = new SqlSessionFactoryBuilder().build(is);??

//3.創建核心SqlSession對象??

session = factory.openSession(true);??

//4.獲取IAccountDao代理對象??

userDao = session.getMapper(IUserDao.class);??

}??

//查詢所有操作??

@Test??

public void findAll(){??

List<User> users = userDao.findAll();??

for (User user : users) {??

System.out.println(user);??

}??

}??

//保存用戶??

@Test??

public void saveUser(){??

//創建用戶信息??

User user=new User();??

user.setUsername("老周");??

user.setBirthday(new Date());??

user.setAddress("武漢");??

user.setSex("男");??

System.out.println("添加前user = " + user);??

//添加到數據??

int row = userDao.saveUser(user);??

System.out.println("影響的行數row = " + row);System.out.println("添加后user = " + user);??

}??

//更新用戶??

@Test??

public void updateUser(){??

//準備要修改用戶的信息信息??

User user=new User();??

user.setId(55);??

user.setUsername("老李");??

user.setBirthday(new Date());??

user.setAddress("孝感");??

user.setSex("女");??

//修改用戶??

int row = userDao.updateUser(user);??

System.out.println("row = " + row);??

}??

//根據 id 刪除用戶??

@Test??

public void deleteUser(){??

//根據id刪除用戶信息??

int row = userDao.deleteUser(55);??

System.out.println("row = " + row);??

}??

//根據 id 查詢??

@Test??

public void findById(){??

User user = userDao.findById(50);??

System.out.println(user);??

}??

//根據名稱模糊查詢??

@Test??

public void findByName(){??

List<User> users = userDao.findByName("%王%");??

for (User user : users) {??

System.out.println(user);??

}??

}??

//查詢總記錄條數??

@Test??

public void findTotal(){??

int total = userDao.findTotal();??

System.out.println("total = " + total);??

}??

//根據 QueryVo 中的條件查詢用戶??

@Test??

public void findByVo(){??

//創建QueryVo對象??

QueryVo queryVo=new QueryVo();??

//創建模糊查詢條件封裝到user對象中??

User user=new User();??

user.setUsername("%王%");??

queryVo.setUser(user);??

//執行查詢3.2 mybatis注解開發實例類屬性與表列名不一致??

3.2.1 IUserDao中給方法添加注解??

3.2.2 在測試類中測試??

3.3 mybatis注解開發一對一/多查詢??

3.3.1 IUserDao中給方法添加注解??

List<User> users = userDao.findByVo(queryVo);??

//遍歷打印??

for (User u : users) {??

System.out.println(u);??

}??

}??

@After??

public void destroy() throws IOException {??

session.close();??

is.close();??

}??

/**??

* 使用別名,查詢所有用戶信息;??

* @return 所有用戶信息??

*/??

@Select("select * from user")??

//id="uMap"表示結果集映射的id,將來可以給其他@ResultMap復用??

@Results(id="uMap",value = {??

//id=true表示是主鍵,默認值是false??

@Result(id=true,column = "id",property = "userId"),??

@Result(id=false,column = "username",property = "userName"),??

@Result(column = "birthday",property = "userBirthday"),??

@Result(column = "sex",property = "userSex"),??

@Result(column = "address",property = "userAddress")??

}??

)??

List<U> findAllU();??

@Test??

public void findAllU(){??

List<U> us = userDao.findAllU();??

//遍歷打印??

for (U u : us) {??

System.out.println(u);??

}??

}??

/**3.3.2 IAccountDao中創建fifindAccountById方法并添加注解??

3.3.3 在測試類中測試??

* 立即查詢:查詢賬戶信息的同時查詢其用戶信息??

* @return??

*/??

@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(column = "uid",property = "user",one = @One(??

select="com.itheima.dao.IUserDao.findById",??

fetchType = FetchType.EAGER//立即查詢??

)),??

})??

List<Account> findAllAccountAndUser();??

/**??

* 延時查詢:查詢用戶信息的同時查詢其所有賬戶信息??

*/??

@Select("select * from user")??

@Results(id="userMap",value = {??

@Result(id=true,column = "id",property = "id"),??

@Result(column = "username",property = "username"),??

@Result(column = "birthday",property = "birthday"),??

@Result(column = "sex",property = "sex"),??

@Result(column = "address",property = "address"),??

@Result(column = "id",property = "accounts",many = @Many(??

select="com.itheima.dao.IAccountDao.findAccountById",??

fetchType = FetchType.LAZY//延時查詢??

)),??

})??

List<User> findAllUserAndAccount();??

public interface IAccountDao {??

/**??

* 根據uid查詢對應的所有賬戶信息??

* @param uid??

* @return??

*/??

@Select("select * from account where uid=#{uid}")??

List<Account> findAccountById(int uid);??

}??

//立即查詢:查詢賬戶信息的同時查詢其用戶信息??

@Test??

public void findAllAccountAndUser(){??

List<Account> accounts = userDao.findAllAccountAndUser();??

//變量打印3.4 mybatis注解開發使用二級緩存??

3.4.1 在被測試的dao類上添加注解開啟二級緩存即可??

注意:SqlMapConfifig.xml中的中的??

cacheEnabled默認值就是true,可以不用配置。??

3.4.2 代碼測試??

mybatis擴展內容??

for (Account account : accounts) {??

System.out.println(account.getId()+"-"+account.getUid()+"-"+account.getMoney());??

System.out.println(account.getUser());??

}??

}??

//延時查詢:查詢用戶信息的同時查詢其所有賬戶信息??

@Test??

public void findAllUserAndAccount(){??

List<User> users = userDao.findAllUserAndAccount();??

for (User u : users) {??

System.out.println(u.getId()+"-"+u.getUsername()+"-"+u.getBirthday()+"-"+u.getSex()+"-??

"+u.getAddress());??

// System.out.println(u.getAccounts());??

}??

}??

//該接口查詢開啟二級緩存??

@CacheNamespace(blocking = true)??

public interface IUserDao {}??

//測試二級緩存??

@Test??

public void testSecondLeverCache(){??

//1.獲取第一個sqlSession對象并查詢user??

SqlSession session1 = factory.openSession(true);??

IUserDao userDao1 = session1.getMapper(IUserDao.class);??

User user1 = userDao1.findById(43);??

System.out.println("user1 = " + user1);??

//關閉session1??

session1.close();??

//2.獲取第二個sqlSession對象并查詢user??

SqlSession session2 = factory.openSession(true);??

IUserDao userDao2 = session2.getMapper(IUserDao.class);??

User user2 = userDao2.findById(43);??

System.out.println("user2 = " + user2);??

session2.close();??

//判斷user1和user2是不是同一個對象??

System.out.println("user1==user2 : " + (user1==user2));??

}1.mybatis使用第三方連接池??

1.1 mybatis中連接池原理??

1.2 使用第三方連接池步驟??

1.2.1 自定義工廠類實現mybatis的DataSourceFactory接口??

MyBatis 在初始化時,根據<dataSource>的 type 屬性來創建相應類型的的數據源 DataSource,即:??

type="POOLED": MyBatis 會創建 PooledDataSource 實例??

type="UNPOOLED": MyBatis 會創建 UnpooledDataSource 實例??

type="JNDI": MyBatis 會從 JNDI 服務上查找 DataSource 實例,然后返回使用??

當我們在<dataSource type="POOLED">配置POOLED時mybatis就會為我們創建PooledDataSource對象,這個對象是??

通過連接池工程創建出來的:??

public class PooledDataSourceFactory extends UnpooledDataSourceFactory {??

public PooledDataSourceFactory() {??

this.dataSource = new PooledDataSource();??

}??

}??

public class UnpooledDataSourceFactory implements DataSourceFactory {??

//代碼省略??

}??

public interface DataSourceFactory {??

void setProperties(Properties props);??

DataSource getDataSource();??

}??

mybatis創建PooledDataSourceFactory工廠對象的同時會創建一個PooledDataSource連接池對象,然后調用工??

廠對象的setProperties(Properties props)方法將SqlMapConfig.xml中的連接池配置信息通過props傳遞進來,當??

進行CRUD操作時就調用getDataSource()方法獲取連接池對象。??

也就是說要想讓mybatis使用第三方連接池,我們就得自己定義一個工廠類,在工廠來中創建第三方連接池對象并??

在setProperties(Properties props)方法中設置連接參數,在getDataSource()方法中返回連接池對象??

package com.itheima.factory;??

import com.alibaba.druid.pool.DruidDataSource;??

import org.apache.ibatis.datasource.DataSourceFactory;??

import javax.sql.DataSource;??

import java.util.Properties;??

//DruidDataSourceFactory不是alibaba的DruidDataSourceFactory??

public class DruidDataSourceFactory implements DataSourceFactory {??

//聲明連接池對象??

private DruidDataSource dataSource;??

public DruidDataSourceFactory() {??

//創建連接池對象??

this.dataSource = new DruidDataSource();??

}??

@Override??

public void setProperties(Properties props) {??

//將SqlMapConfig.xml中的連接池配置信息設置給druid連接池對象??

dataSource.setDriverClassName(props.getProperty("driver"));1.2.2 在SqlMapConfifig.xml中使用第三方連接池??

1.2.3 在測試類中進行測試??

dataSource.setUrl(props.getProperty("url"));??

dataSource.setUsername(props.getProperty("username"));??

dataSource.setPassword(props.getProperty("password"));??

}??

@Override??

public DataSource getDataSource() {??

return dataSource;??

}??

}??

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"??

"http://mybatis.org/dtd/mybatis-3-config.dtd">??

??

resource="jdbcConfig.properties"/>??

??

name="com.itheima.domain"/>??

default="mysql">??

id="mysql">??

type="jdbc">??

type="com.itheima.factory.DruidDataSourceFactory">??

name="driver" value="${jdbc.driver}"/>??

name="url" value="${jdbc.url}"/>??

name="username" value="${jdbc.username}"/>??

name="password" value="${jdbc.password}"/>??

??

name="com.itheima.dao"/>??

2.mybatis查詢傳遞其他類型參數??

2.1 參數是Map集合??

在IUserDao.xml中配置查詢信息??

在測試類中測試??

//查詢所有操作??

@Test??

public void findAll(){??

//獲取連接池對象的名稱??

DataSource dataSource = session.getConfiguration().getEnvironment().getDataSource();??

System.out.println("dataSource = " + dataSource.getClass());//dataSource = class??

com.alibaba.druid.pool.DruidDataSource??

//查詢所有用戶信息??

List<User> users = userDao.findAll();??

for (User user : users) {??

System.out.println(user);??

}??

}??

id="findUserByMap" resultType="user"> select * from USER test="username!=null and username!=''"> and username like #{username} test="sex!=null and username!=''"> and sex = #{sex}??

//動態sql:根據map集合中的條件,查詢用戶信息??

@Test??

public void testFindUserByMap(){??

//創建Map集合并封裝查詢參數??

Map<String,Object> map=new HashMap<String,Object>();??

map.put("username","%王%");??

map.put("sex","女");??

//查詢符合條件的用戶信息??

List<User> users = userDao.findUserByMap(map);??

for (User user : users) {??

System.out.println(user);??

}??

}結論:使用map集合或者javabean對象作為參數,其實是一樣的,map集合對應的就是javabean的屬性。??

2.2 參數是List集合??

在IUserDao.xml中配置查詢信息??

在測試類中測試??

結論:mybatis其實是將參數list集合先存到map中,key為list(即map.pust("list",list集合對象)),所以??

collection="list"中的屬性值必須是list,就相當于從map中取出list遍歷??

2.3 參數是數組- 和參數是list幾乎一樣??

在IUserDao.xml中配置查詢信息??

id="findUserByList" resultType="user"> SELECT * FROM USER and id in( collection="list" item="id" separator=","> #{id} )??

//動態sql:查詢list集合中指定id的user信息??

@Test??

public void testFindUserByList(){??

//創建list集合并存儲要查的用戶id??

List<Integer> ids=new ArrayList<Integer>();??

ids.add(41);??

ids.add(43);??

ids.add(48);??

ids.add(50);??

//查詢符合條件的用戶信息??

List<User> users = userDao.findUserByList(ids);??

for (User user : users) {??

System.out.println(user);??

}??

}在測試類中測試??

結論:查詢參數是Array與查詢參數是list集合的原理是一樣的,都是現將對象存到map集合中,只不過參數??

為Array時,存到map集合中的key叫array,所以collection="array"的值必須是array??

2.4 多個參數情況以及@Param注解??

在IUserDao中定義查詢方法??

在IUserDao.xml中配置查詢信息??

id="findUserByArray" resultType="user"> SELECT * FROM USER and id in( collection="array" item="id" separator=","> #{id} )??

//動態sql:查詢數組中指定id的user信息??

@Test??

public void testFindUserByArray(){??

//創建list集合并存儲要查的用戶id??

Integer[] ids={41,43,48,50};??

//查詢符合條件的用戶信息??

List<User> users = userDao.findUserByArray(ids);??

for (User user : users) {??

System.out.println(user);??

}??

}??

/**??

* 多個參數:根據用戶名和性別查詢用戶信息??

* @Param("username") :定義參數的別名,將來在映射文件中使用??

*/??

public List<User> findUserByUsernameAndSex(@Param("username") String username,@Param("sex")??

String sex);??

}??

id="findUserByUsernameAndSex" resultType="user"> SELECT * FROM USER where username like #{username} and sex= #{sex} 在測試類中測試??

結論:最好是結果@Param注解一起使用,映射文件中#{username}使用的變量名就是 @Param("username")注解的參數值 3.mybatis注解開發-動態sql 3.1 方式1:在select注解中添加script腳本 在在IUserMapper方法上定義注解 測試類測試 /** * 多個參數:根據用戶名和性別查詢用戶信息 */ @Test public void testFindUserByUsernameAndSex(){ List<User> users = userDao.findUserByUsernameAndSex("%王%", "女"); for (User user : users) { System.out.println(user); } } /** * 動態sql:查詢list集合中指定id的user信息 */ @Select({""}) public List<User> findUserByList(List<Integer> ids); //動態sql:查詢list集合中指定id的user信息 @Test public void testFindUserByList(){ //創建list集合并存儲要查的用戶id List<Integer> ids=new ArrayList<Integer>(); ids.add(41); ids.add(43); ids.add(48); ids.add(50);總結:其實就是將xml映射文件中的配置拿過來用了,也是支持的。適用于帶in的查詢 3.1 方式2:字符串拼接(了解) 定義sql提供者UserMapperProvider類 在IUserMapper方法上定義注解 測試類測試 //查詢符合條件的用戶信息 List<User> users = userMapper.findUserByList(ids); for (User user : users) { System.out.println(user); } } /** * 為注解開發動態sql查詢提供sql */ public class UserMapperProvider { /** * 動態sql:根據map集合中的條件,查詢用戶信息 * @param map 查詢條件 * @return 根據條件返回sql */ public String findUserByMap(Map<String,Object> map){ StringBuilder sb=new StringBuilder("select * from user where 1=1 "); if(map.get("username")!=null){ sb.append(" and username like #{username}"); } if(map.get("sex")!=null){ sb.append(" and sex = #{sex}"); } return sb.toString(); } } public interface IUserMapper { /** * 動態sql:根據map集合中的條件,查詢用戶信息 */ @SelectProvider(type=UserMapperProvider.class,method = "findUserByMap") public List<User> findUserByMap(Map<String,Object> map); }3.2 方式3:使用mybatis中提供的SQL對象動態構建sql語句 修改UserMapperProvider提供者中的fifindUserByMap方法 4.mybatis使用Redis做二級緩存 總結 使用xml配置完成CURD操作 環境 jar包坐標 //動態sql:根據map集合中的條件,查詢用戶信息 @Test public void testFindUserByMap(){ //創建Map集合并封裝查詢參數 Map<String,Object> map=new HashMap<String,Object>(); map.put("username","%王%"); map.put("sex","女"); //查詢符合條件的用戶信息 List<User> users = userMapper.findUserByMap(map); for (User user : users) { System.out.println(user); } } public String findUserByMap(Map<String,Object> map){ return new SQL(){ //靜態代碼塊 { SELECT("*"); FROM("user"); if (map.get("username")!=null) { WHERE("username like #{username}"); } if (map.get("sex")!=null) { AND(); WHERE("sex = #{sex}"); } } }.toString(); } 配置文件 單表查詢 org.mybatis mybatis 3.4.5 mysql mysql-connector-java 5.1.38 junit junit 4.10 log4j log4j 1.2.12 測試多表查詢 一對多 多表查詢 多對多 使用annotation完成CURD操作 環境 與xml相同 單表查詢多表查詢 一對多

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540358.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540358.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540358.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

設置了li(float:right),里面的li反過來顯示 - 解決辦法

設置了li(float:right),里面的li反過來顯示 - 解決辦法 可以讓ul float:right ul里的li 依然float:left 本文轉自許琴 51CTO博客&#xff0c;原文鏈接&#xff1a;http://blog.51cto.com/xuqin/1127540&#xff0c;如需轉載請自行聯系原作者

[轉載] 純函數和函數柯里化

參考鏈接&#xff1a; 用示例編寫Java柯里化Currying函數 文章目錄 純函數什么是純函數純函數例子非純函數例子 函數柯里化函數柯里化簡單例子參數復用 純函數 什么是純函數 如果函數的調用參數相同&#xff0c;則永遠返回相同的結果。它不依賴于程序執行期間函數外部任何狀…

[轉載] scala

參考鏈接&#xff1a; 在Java的數字中使用下劃線 1 scala 底層是有一種隱式轉換機制&#xff0c;比如對String類型&#xff0c;底層會轉化Scala的StringOps類型 2 scala 的通用的化簡規則&#xff1a;調方法時候&#xff0c;方法的參數列表只有一個&#xff0c;則方法的&…

MySQL數據庫學習筆記

MySQL常用語法總結 一.創建Web數據庫 1.登陸到數據庫 mysql -h hostname -u username -p mysql -h hostname -u username -D dbname -p 2.創建數據庫 CREATE database dbname 3.使用數據庫 USE dbname 4.創建數據庫表 CREATE TABLE tablename (columns) 5.列的數據 create tabl…

[轉載] java實現四種常用排序算法

參考鏈接&#xff1a; 用Java排序 四種常用排序算法 ##注&#xff1a;從小到大排 ##冒泡排序## 特點&#xff1a;效率低&#xff0c;實現簡單 思想&#xff1a;每一趟將待排序序列中最大元素移到最后&#xff0c;剩下的為新的待排序序列&#xff0c;重復上述步驟直到排完所…

[轉載] Java復制對象與集合工具類

參考鏈接&#xff1a; Java中的類和對象 項目中經常需要將某個對象的屬性值復制給另一個對象&#xff0c;或者將一個集合復制到另一個集合。利用spring提供的BeanUtils&#xff0c;自己簡單封裝了一個工具類。 public class CopyUtils { /** * 復制集合 */ public static &l…

.NET深入學習筆記(4):深拷貝與淺拷貝(Deep Copy and Shallow Copy)

今天繼續利用準備WSE安全開發文章的空閑時間&#xff0c;完善《.NET深入學習筆記》系列&#xff08;基本都是.Net重要的知識點&#xff0c;我都做了詳細的總結&#xff0c;是什么、為什么、和怎么實現&#xff09;。想必很多人也接觸過這兩個概念。做過C的人對深淺拷貝的概念一…

VIM一般模式操作

2019獨角獸企業重金招聘Python工程師標準>>> vim介紹 vim和vi幾乎是一樣的&#xff0c;唯一的區別就是當編輯一個文本時&#xff0c;使用vi不會顯示顏色&#xff0c;而使用vim會顯示顏色。 vim有三個模式&#xff1a;一般模式&#xff0c;編輯模式&#xff0c;命令模…

[轉載] 解析Java的JNI編程中的對象引用與內存泄漏問題

參考鏈接&#xff1a; Java對象如何存儲在內存中 JNI&#xff0c;Java Native Interface&#xff0c;是 native code 的編程接口。JNI 使 Java 代碼程序可以與 native code 交互——在 Java 程序中調用 native code&#xff1b;在 native code 中嵌入 Java 虛擬機調用 Java 的…

[轉載] java中創建對象的方式

參考鏈接&#xff1a; 用Java創建對象的不同方法 java中的4種創建對象的方式&#xff1a; 在這片博文中和大家簡單分享一下常見的幾種創建java對象的方式 1.使用 new 的方式&#xff0c;這也是我們最常見的一種方式 我們以 Person 類來舉例說明 例&#xff1a; Person p…

Exchange 2007 SP1 如何定時清理日志???

Exchange 2007 SP1 如何定時清理日志&#xff1f;&#xff1f;&#xff1f; 時間:2011-12-31 11:00Tag標簽&#xff1a;來源:未知 作者:達思科技 點擊: 93次此文章出自&#xff1a; 專業數據恢復 問&#xff1a;Exchange 2007 SP1 如何定時清理日志&#xff1f;&#xff1f;&am…

[轉載] java-繼承和多態

參考鏈接&#xff1a; Java中的繼承 繼承&#xff1a; 繼承就是保持已有類的特性而構造新類的過程。繼承后&#xff0c;子類能夠利用父類中定義的變量和方法&#xff0c;就像它們屬于子類本身一樣。 單繼承&#xff1a;在類層次中&#xff0c;子類只繼承一個父類的數據結構…

走進SQL Server 2005:備份與恢復功能

每當有任何新的軟件發布的時候&#xff0c;你通常都會發現一些你從來不知道或者從來不知道你需要的新的特性。SQL Server 2000中存在的許多的備份和恢復特性都同樣保留在了SQL Server 2005中&#xff0c;但是有一些新的提高同樣值得你的關注。 鏡像備份 SQL Server 2005讓你可以…

[轉載] Java對返回值的封裝

參考鏈接&#xff1a; 用Java封裝 定義自己所需要的返回值類型 public class CodeMsg implements Cloneable { private int retCode; private String message; // 通用異常 public static CodeMsg SUCCESS new CodeMsg(0, "success"); public static CodeMsg EMP…

stateful set 學習筆記

2019獨角獸企業重金招聘Python工程師標準>>> 1、創建pv # cat pv.yaml kind: PersistentVolume apiVersion: v1 metadata:name: task-pv-volumelabels:type: local spec:capacity:storage: 3GiaccessModes:- ReadWriteOncehostPath:path: "/tmp/data" 2、…

[轉載] Java中對象數組的使用

參考鏈接&#xff1a; 如何在Java中交換或交換對象 Java對象數組使用 一、Java數組的使用二、Java的對象數組2.1 問題提出2.2 問題解析2.3 問題拆分2.4 代碼實現 一、Java數組的使用 對象數組其實和Java的數組類似的&#xff0c;所以要很清楚Java的數組是如何使用的&#xf…

Python自動化開發學習13-聯合唯一

聯合唯一 聯合唯一&#xff0c;就是一個表中的多個字段的組合需要唯一。 使用mysql語句創建 比如創建一張hosts表&#xff0c;記錄登錄的ip地址或者hostname&#xff08;表中對應字段host&#xff09;和 端口號&#xff08;表中對應字段port&#xff09;&#xff0c;要求host 和…

[轉載] Java獲取泛型T的類型 T.class

參考鏈接&#xff1a; Java中的抽象 import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class Main{ public static void main(String[] args) { Foo<String> foo new Foo<String>(){}; // 在類的外部這樣獲取 Type type ((…

自定義控件---重寫Listbox實現item圖標變換和item點擊事件

博客開通有一陣了&#xff0c;就是沒有時間寫&#xff0c;遺憾啊。&#xff01; 這幾天做了個排序的自定義控件&#xff0c;在listbox item里放是button 并支持圖標的交替變換 效果如下&#xff1a; 把代碼貼上&#xff1a;1using System; 2using System.Collections.…

[轉載] Spring面試題整理

參考鏈接&#xff1a; Java中的動態方法Dispatch和運行時多態 Spring面試題整理 2018年03月07日 21:11:46 hrbeuwhw 閱讀數&#xff1a;49116 Spring 概述 1. 什么是spring? spring 是個Java企業級應用的開源開發框架。Spring主要用來開發Java應用&#xff0c;但是有…